diff --git a/apps/synapse-playground/package.json b/apps/synapse-playground/package.json index ef455316..689d259f 100644 --- a/apps/synapse-playground/package.json +++ b/apps/synapse-playground/package.json @@ -74,6 +74,7 @@ "lucide-react": "^0.546.0", "nanostores": "^1.0.1", "next-themes": "^0.4.6", + "p-retry": "^7.1.0", "react": "19.2.0", "react-dom": "19.2.0", "react-dropzone": "^14.3.8", diff --git a/apps/synapse-playground/src/components/warm-storage/create-data-set.tsx b/apps/synapse-playground/src/components/warm-storage/create-data-set.tsx index 027e5f78..cb46d426 100644 --- a/apps/synapse-playground/src/components/warm-storage/create-data-set.tsx +++ b/apps/synapse-playground/src/components/warm-storage/create-data-set.tsx @@ -49,13 +49,13 @@ export function CreateDataSetDialog() { cdn: boolean }>({ values: { - provider: providers?.[2]?.providerId.toString() ?? '', + provider: providers?.[0]?.id.toString() ?? '', cdn: false, }, }) function onSubmit(values: { provider: string; cdn: boolean }) { - const provider = providers?.find((p) => p.providerId.toString() === values.provider) + const provider = providers?.find((p) => p.id.toString() === values.provider) createDataSet({ provider: provider!, cdn: values.cdn }) } @@ -94,8 +94,8 @@ export function CreateDataSetDialog() { {providers?.map((provider) => ( - - # {provider.providerId} {provider.name} + + # {provider.id} {provider.name} ))} diff --git a/apps/synapse-playground/src/components/warm-storage/data-sets-section.tsx b/apps/synapse-playground/src/components/warm-storage/data-sets-section.tsx index 6ff5111b..8354bb2f 100644 --- a/apps/synapse-playground/src/components/warm-storage/data-sets-section.tsx +++ b/apps/synapse-playground/src/components/warm-storage/data-sets-section.tsx @@ -1,5 +1,11 @@ import type { DataSetWithPieces, UseProvidersResult } from '@filoz/synapse-react' -import { CloudDownload, FileAudio, FileCode, FilePlay, FileText, Globe, Info } from 'lucide-react' +import { useDeletePiece } from '@filoz/synapse-react' +import { CloudDownload, FileAudio, FileCode, FilePlay, FileText, Globe, Info, Trash } from 'lucide-react' +import { useState } from 'react' +import { toast } from 'sonner' +import { toastError } from '@/lib/utils.ts' +import { ButtonLoading } from '../custom-ui/button-loading.tsx' +import { ExplorerLink } from '../explorer-link.tsx' import { PDPDatasetLink, PDPPieceLink, PDPProviderLink } from '../pdp-link.tsx' import { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar.tsx' import { Button } from '../ui/button.tsx' @@ -15,7 +21,7 @@ export function DataSetsSection({ dataSets?: DataSetWithPieces[] providers?: UseProvidersResult }) { - const providerWithDataSets = providers?.filter((p) => dataSets?.some((d) => d.providerId === p.providerId)) + const providerWithDataSets = providers?.filter((p) => dataSets?.some((d) => d.providerId === p.id)) const imagesMimeTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'] const videosMimeTypes = ['video/mp4', 'video/quicktime', 'video/webm'] @@ -45,6 +51,29 @@ export function DataSetsSection({ 'application/x-toml', ] + const [deletingPiece, setDeletingPiece] = useState(null) + const { mutate: deletePiece, isPending: isDeletingPiece } = useDeletePiece({ + onHash: (hash) => { + toast.loading('Deleting piece...', { + description: , + id: 'delete-piece', + }) + }, + mutation: { + onSuccess: () => { + toast.success('Piece deleted', { + id: 'delete-piece', + }) + }, + onError: (error) => { + toastError(error, 'delete-piece', 'Piece deletion failed') + }, + onSettled: () => { + setDeletingPiece(null) + }, + }, + }) + return providers ? (
@@ -57,16 +86,16 @@ export function DataSetsSection({
{providerWithDataSets?.map((provider) => ( -
+

{dataSets - ?.filter((dataSet) => dataSet.providerId === provider.providerId) + ?.filter((dataSet) => dataSet.providerId === provider.id) .map((dataSet) => (

- + @@ -93,7 +122,7 @@ export function DataSetsSection({

{dataSet.pieces.map((piece) => ( - + {imagesMimeTypes.includes(piece.metadata.type) ? ( {piece.metadata.name ) : videosMimeTypes.includes(piece.metadata.type) ? ( @@ -121,25 +150,39 @@ export function DataSetsSection({ ) : ( - + NA )} - + - {piece.metadata.type} + + {piece.metadata.type} {piece.id} + + { + setDeletingPiece(piece.id) + deletePiece({ + dataSet, + pieceId: piece.id, + }) + }} + > + + ))} diff --git a/apps/synapse-playground/src/components/warm-storage/uploads-section.tsx b/apps/synapse-playground/src/components/warm-storage/uploads-section.tsx index ec7cd201..e0bc4544 100644 --- a/apps/synapse-playground/src/components/warm-storage/uploads-section.tsx +++ b/apps/synapse-playground/src/components/warm-storage/uploads-section.tsx @@ -28,12 +28,12 @@ export function UploadsSection({ const providerWithDataSets = providers?.map((provider) => ({ ...provider, - dataSets: dataSets?.filter((d) => d.providerId === provider.providerId), + dataSets: dataSets?.filter((d) => d.providerId === provider.id), })) useEffect(() => { if (!dataSet && dataSets && dataSets.length > 0) { - setDataSet(dataSets[0].pdpDatasetId.toString()) + setDataSet(dataSets[0].dataSetId.toString()) } }, [dataSets]) @@ -86,11 +86,11 @@ export function UploadsSection({ {providerWithDataSets?.map((provider) => ( - + {provider.name} {provider.dataSets?.map((dataSet) => ( - - # {dataSet.pdpDatasetId} {dataSet.cdn ? 'CDN' : ''} + + # {dataSet.dataSetId} {dataSet.cdn ? 'CDN' : ''} ))} diff --git a/apps/synapse-playground/src/main.tsx b/apps/synapse-playground/src/main.tsx index 479d0ea0..4e51bacf 100644 --- a/apps/synapse-playground/src/main.tsx +++ b/apps/synapse-playground/src/main.tsx @@ -46,7 +46,7 @@ export const config = createConfig({ transports: { [mainnet.id]: http(), [calibration.id]: http(undefined, { - batch: true, + batch: false, }), }, batch: { diff --git a/biome.json b/biome.json index f6659918..b708f236 100644 --- a/biome.json +++ b/biome.json @@ -33,7 +33,7 @@ "!**/components.d.ts", "!**/mockServiceWorker.js", "!**/abis/gen.ts", - "!packages/synapse-core/src/generated.ts" + "!packages/synapse-core/src/abis/generated.ts" ] }, "vcs": { diff --git a/docs/src/content/docs/guides/rails-settlement.mdx b/docs/src/content/docs/guides/rails-settlement.mdx index d8630015..51b8d0a1 100644 --- a/docs/src/content/docs/guides/rails-settlement.mdx +++ b/docs/src/content/docs/guides/rails-settlement.mdx @@ -17,7 +17,7 @@ Rails ensure reliable payments through a simple lockup mechanism: When you create a data set (storage), the system calculates how much balance you need to maintain: -- **Formula**: `lockup = paymentRate × lockupPeriod` (e.g., 10 days worth of payments) +- **Formula**: `lockup = paymentRate × lockupPeriod` (e.g., 30 days worth of payments) - **Example**: Storing 1 GiB costs ~0.0000565 USDFC/epoch, requiring ~1.63 USDFC minimum balance - **Purpose**: This protects the service provider by ensuring you always have enough for the next payment period diff --git a/docs/src/content/docs/intro/components.mdx b/docs/src/content/docs/intro/components.mdx index ea82db28..35e7db5b 100644 --- a/docs/src/content/docs/intro/components.mdx +++ b/docs/src/content/docs/intro/components.mdx @@ -139,6 +139,9 @@ if (verification.dataSetLive) { // Service provider operations const isApproved = await warmStorageService.isProviderApproved(providerAddress) const providers = await warmStorageService.getAllApprovedProviders() + +// Top up CDN payment rails +await wamStorageService.topUpCDNPaymentRails(signer, dataSetId, cdnAmountToAdd, cacheMissAmountToAdd) ``` ### Subgraph Service diff --git a/examples/cli/package.json b/examples/cli/package.json new file mode 100644 index 00000000..0aea738e --- /dev/null +++ b/examples/cli/package.json @@ -0,0 +1,25 @@ +{ + "name": "synapse-cli", + "version": "1.0.0", + "description": "CLI for Synapse", + "type": "module", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "packageManager": "pnpm@10.19.0", + "dependencies": { + "@clack/prompts": "^0.11.0", + "@filoz/synapse-sdk": "workspace:^", + "@filoz/synapse-core": "workspace:^", + "cleye": "^1.3.4", + "conf": "^15.0.2", + "viem": "^2.38.4" + }, + "devDependencies": { + "@types/node": "^24.9.1" + } +} diff --git a/examples/cli/src/commands/dataset-terminate.ts b/examples/cli/src/commands/dataset-terminate.ts new file mode 100644 index 00000000..6a0d32a7 --- /dev/null +++ b/examples/cli/src/commands/dataset-terminate.ts @@ -0,0 +1,87 @@ +import * as p from '@clack/prompts' +import { calibration } from '@filoz/synapse-core/chains' +import { getDataSets, terminateDataSet } from '@filoz/synapse-core/warm-storage' +import { RPC_URLS, Synapse } from '@filoz/synapse-sdk' +import { type Command, command } from 'cleye' +import { createPublicClient, createWalletClient, type Hex, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { waitForTransactionReceipt } from 'viem/actions' +import config from '../config.ts' + +const publicClient = createPublicClient({ + chain: calibration, + transport: http(), +}) + +export const datasetTerminate: Command = command( + { + name: 'dataset-terminate', + description: 'Terminate a data set', + alias: 'dt', + help: { + description: 'Terminate a data set', + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + + const account = privateKeyToAccount(privateKey as Hex) + const client = createWalletClient({ + account, + chain: calibration, + transport: http(), + }) + + const spinner = p.spinner() + spinner.start(`Fetching data sets...`) + try { + const dataSets = await getDataSets(publicClient, { + address: account.address, + }) + spinner.stop(`Fetching data sets complete`) + + const dataSetId = await p.select({ + message: 'Pick a data set to terminate.', + options: dataSets + // .filter((dataSet) => dataSet.pdpEndEpoch === 0n) + .map((dataSet) => ({ + value: dataSet.dataSetId.toString(), + label: `#${dataSet.dataSetId} - SP: #${dataSet.providerId} ${dataSet.pdp.serviceURL}`, + })), + }) + if (p.isCancel(dataSetId)) { + p.cancel('Operation cancelled.') + process.exit(0) + } + + spinner.start(`Terminating data set ${dataSetId}...`) + // const synapse = await Synapse.create({ + // privateKey: privateKey as Hex, + // rpcURL: RPC_URLS.calibration.http, + // }) + + // const tx = await synapse.storage.terminateDataSet(Number(dataSetId)) + + const tx = await terminateDataSet(client, { + dataSetId: BigInt(dataSetId), + }) + + spinner.message(`Waiting for transaction to be mined...`) + await waitForTransactionReceipt(publicClient, { + hash: tx, + }) + + spinner.stop(`Data set terminated`) + } catch (error) { + spinner.stop() + console.error(error) + p.outro('Please try again') + return + } + } +) diff --git a/examples/cli/src/commands/datasets.ts b/examples/cli/src/commands/datasets.ts new file mode 100644 index 00000000..398e47d3 --- /dev/null +++ b/examples/cli/src/commands/datasets.ts @@ -0,0 +1,53 @@ +import * as p from '@clack/prompts' +import { calibration } from '@filoz/synapse-core/chains' +import { getDataSets } from '@filoz/synapse-core/warm-storage' +import { type Command, command } from 'cleye' +import { createPublicClient, type Hex, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import config from '../config.ts' + +const publicClient = createPublicClient({ + chain: calibration, + transport: http(), +}) + +export const datasets: Command = command( + { + name: 'datasets', + description: 'List all data sets', + alias: 'ds', + help: { + description: 'List all data sets', + examples: ['synapse datasets', 'synapse datasets --help'], + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + + const account = privateKeyToAccount(privateKey as Hex) + const spinner = p.spinner() + + spinner.start('Listing data sets...') + try { + const dataSets = await getDataSets(publicClient, { + address: account.address, + }) + spinner.stop('Data sets:') + dataSets.forEach(async (dataSet) => { + p.log.info( + `#${dataSet.dataSetId} ${dataSet.pdp.serviceURL} ${dataSet.pdpEndEpoch > 0n ? `Terminating at epoch ${dataSet.pdpEndEpoch}` : ''}` + ) + }) + } catch (error) { + spinner.stop() + console.error(error) + p.outro('Failed to list data sets') + return + } + } +) diff --git a/examples/cli/src/commands/deposit.ts b/examples/cli/src/commands/deposit.ts new file mode 100644 index 00000000..32113059 --- /dev/null +++ b/examples/cli/src/commands/deposit.ts @@ -0,0 +1,68 @@ +import * as p from '@clack/prompts' +import { calibration } from '@filoz/synapse-core/chains' +import { depositAndApprove } from '@filoz/synapse-core/pay' +import { type Command, command } from 'cleye' +import { createPublicClient, createWalletClient, type Hex, http, parseEther } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { waitForTransactionReceipt } from 'viem/actions' +import config from '../config.ts' + +const publicClient = createPublicClient({ + chain: calibration, + transport: http(), +}) + +export const deposit: Command = command( + { + name: 'deposit', + description: 'Deposit funds to the wallet', + alias: 'd', + help: { + description: 'Deposit funds to the wallet', + examples: ['synapse deposit', 'synapse deposit --help'], + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + const client = createWalletClient({ + account: privateKeyToAccount(privateKey as Hex), + chain: calibration, + transport: http(), + }) + + const spinner = p.spinner() + const value = await p.text({ + message: 'Enter the amount to deposit', + }) + + if (p.isCancel(value)) { + p.cancel('Operation cancelled.') + process.exit(0) + } + + spinner.start('Depositing funds...') + try { + const hash = await depositAndApprove(client, { + amount: parseEther(value), + }) + + spinner.message('Waiting for transaction to be mined...') + + await waitForTransactionReceipt(publicClient, { + hash, + }) + + spinner.stop('Funds deposited') + } catch (error) { + spinner.stop() + console.error(error) + p.outro('Failed to deposit funds') + return + } + } +) diff --git a/examples/cli/src/commands/fund.ts b/examples/cli/src/commands/fund.ts new file mode 100644 index 00000000..778be922 --- /dev/null +++ b/examples/cli/src/commands/fund.ts @@ -0,0 +1,63 @@ +import * as p from '@clack/prompts' +import { claimTokens, formatBalance } from '@filoz/synapse-core' +import { calibration } from '@filoz/synapse-core/chains' +import { RPC_URLS, Synapse } from '@filoz/synapse-sdk' +import { type Command, command } from 'cleye' +import { createPublicClient, type Hex, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { waitForTransactionReceipt } from 'viem/actions' +import config from '../config.ts' + +const publicClient = createPublicClient({ + chain: calibration, + transport: http(), +}) + +export const fund: Command = command( + { + name: 'fund', + description: 'Fund the wallet', + alias: 'f', + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + + p.intro('Funding wallet...') + const spinner = p.spinner() + const account = privateKeyToAccount(privateKey as Hex) + + spinner.start('Requesting faucets...') + try { + const hashes = await claimTokens({ address: account.address }) + + spinner.message(`Waiting for transactions to be mined...`) + await waitForTransactionReceipt(publicClient, { + hash: hashes[0].tx_hash, + }) + + const synapse = await Synapse.create({ + privateKey: privateKey as Hex, + rpcURL: RPC_URLS.calibration.http, // Use calibration testnet for testing + }) + + spinner.stop('Balances') + const filBalance = await synapse.payments.walletBalance() + const usdfcBalance = await synapse.payments.walletBalance('USDFC') + p.log.info(`FIL balance: ${formatBalance({ value: filBalance })}`) + p.log.info(`USDFC balance: ${formatBalance({ value: usdfcBalance })}`) + } catch (error) { + spinner.stop() + console.error(error) + p.outro('Please try again') + return + } finally { + spinner.stop() + process.exit(0) + } + } +) diff --git a/examples/cli/src/commands/init.ts b/examples/cli/src/commands/init.ts new file mode 100644 index 00000000..ece22821 --- /dev/null +++ b/examples/cli/src/commands/init.ts @@ -0,0 +1,49 @@ +import { intro, log, outro, text } from '@clack/prompts' +import { type Command, command } from 'cleye' +import { generatePrivateKey } from 'viem/accounts' + +import config from '../config.ts' + +export const init: Command = command( + { + name: 'init', + description: 'Initialize a new service provider', + alias: 'i', + flags: { + auto: { + type: Boolean, + }, + }, + help: { + description: 'Initialize a new service provider', + examples: ['synapse init', 'synapse init --auto'], + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (privateKey) { + log.success(`Private key: ${privateKey}`) + log.info(`Config file: ${config.path}`) + outro(`You're all set!`) + return + } + if (argv.flags.auto) { + intro(`Initializing Synapse CLI...`) + const privateKey = generatePrivateKey() + log.success(`Private key: ${privateKey}`) + config.set('privateKey', privateKey) + outro(`You're all set!`) + return + } + + intro(`Initializing Synapse CLI...`) + const privateKeyInput = await text({ + message: 'Enter your private key', + validate(value) { + if (!/^0x[a-fA-F0-9]{64}$/.test(value)) return `Invalid private key!` + }, + }) + config.set('privateKey', privateKeyInput) + outro(`You're all set!`) + } +) diff --git a/examples/cli/src/commands/pay.ts b/examples/cli/src/commands/pay.ts new file mode 100644 index 00000000..ee86199a --- /dev/null +++ b/examples/cli/src/commands/pay.ts @@ -0,0 +1,55 @@ +import * as p from '@clack/prompts' +import { formatBalance } from '@filoz/synapse-core' +import { RPC_URLS, Synapse } from '@filoz/synapse-sdk' +import { type Command, command } from 'cleye' +import type { Hex } from 'viem' +import config from '../config.ts' + +export const pay: Command = command( + { + name: 'pay', + description: 'Check wallet balances', + alias: 'p', + help: { + description: 'Check wallet balances', + examples: ['synapse pay', 'synapse pay --help'], + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + + const spinner = p.spinner() + + spinner.start('Checking wallet balance...') + try { + const synapse = await Synapse.create({ + privateKey: privateKey as Hex, + rpcURL: RPC_URLS.calibration.http, // Use calibration testnet for testing + }) + + const filBalance = await synapse.payments.walletBalance() + const usdfcBalance = await synapse.payments.walletBalance('USDFC') + const paymentsBalance = await synapse.payments.accountInfo() + + spinner.stop('Balances') + p.log.info(`FIL balance: ${formatBalance({ value: filBalance })}`) + p.log.info(`USDFC balance: ${formatBalance({ value: usdfcBalance })}`) + p.log.info(`Available funds: ${formatBalance({ value: paymentsBalance.availableFunds })}`) + p.log.info(`Lockup current: ${formatBalance({ value: paymentsBalance.lockupCurrent })}`) + p.log.info(`Lockup rate: ${formatBalance({ value: paymentsBalance.lockupRate })}`) + p.log.info(`Lockup last settled at: ${formatBalance({ value: paymentsBalance.lockupLastSettledAt })}`) + p.log.info(`Funds: ${formatBalance({ value: paymentsBalance.funds })}`) + p.log.info(`Address: ${await synapse.getSigner().getAddress()}`) + } catch (error) { + spinner.stop() + p.log.error((error as Error).message) + p.outro('Please try again') + return + } + } +) diff --git a/examples/cli/src/commands/pieces.ts b/examples/cli/src/commands/pieces.ts new file mode 100644 index 00000000..10ddece9 --- /dev/null +++ b/examples/cli/src/commands/pieces.ts @@ -0,0 +1,141 @@ +import * as p from '@clack/prompts' +import { metadataArrayToObject } from '@filoz/synapse-core' +import { calibration } from '@filoz/synapse-core/chains' +import { getDataSets, getPieces, type Piece } from '@filoz/synapse-core/warm-storage' +import { RPC_URLS, Synapse } from '@filoz/synapse-sdk' +import { type Command, command } from 'cleye' +import { createPublicClient, type Hex, http, stringify } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { readContract, waitForTransactionReceipt } from 'viem/actions' +import config from '../config.ts' + +const publicClient = createPublicClient({ + chain: calibration, + transport: http(), +}) + +export const pieces: Command = command( + { + name: 'pieces', + description: 'List all pieces', + alias: 'ps', + help: { + description: 'List all pieces', + examples: ['synapse pieces', 'synapse pieces --help'], + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + + const account = privateKeyToAccount(privateKey as Hex) + const spinner = p.spinner() + + spinner.start('Fetching data sets...') + try { + const dataSets = await getDataSets(publicClient, { + address: account.address, + }) + spinner.stop('Fetching data sets complete') + let pieces: Piece[] = [] + const group = await p.group( + { + dataSetId: () => { + return p.select({ + message: 'Pick a data set.', + options: dataSets + .filter((dataSet) => dataSet.pdpEndEpoch === 0n) + .map((dataSet) => ({ + value: dataSet.dataSetId, + label: `#${dataSet.dataSetId} - SP: #${dataSet.providerId} ${dataSet.pdp.serviceURL}`, + })), + }) + }, + pieceId: async ({ results }) => { + const dataSetId = results.dataSetId + const rsp = await getPieces(publicClient, { + dataSet: dataSets.find((dataSet) => dataSet.dataSetId === dataSetId)!, + address: account.address, + }) + pieces = rsp.pieces + if (rsp.pieces.length === 0) { + p.outro('No pieces found') + return + } + return await p.select({ + message: 'Pick a piece.', + options: rsp.pieces.map((piece) => ({ + value: piece.id, + label: `#${piece.id} ${piece.cid}`, + })), + }) + }, + action: async () => { + if (pieces.length === 0) { + return + } + return p.select({ + message: 'Pick an action.', + options: [ + { value: 'info', label: 'Info' }, + { value: 'delete', label: 'Delete' }, + ], + }) + }, + }, + { + // On Cancel callback that wraps the group + // So if the user cancels one of the prompts in the group this function will be called + onCancel: () => { + p.cancel('Operation cancelled.') + process.exit(0) + }, + } + ) + + if (group.action === 'info') { + const piece = pieces.find((piece) => piece.id === group.pieceId)! + const metadata = await readContract(publicClient, { + address: calibration.contracts.storageView.address, + abi: calibration.contracts.storageView.abi, + functionName: 'getAllPieceMetadata', + args: [group.dataSetId, BigInt(piece.id)], + }) + p.log.message( + stringify( + { + ...piece, + metadata: metadataArrayToObject(metadata), + }, + undefined, + 2 + ) + ) + } else if (group.action === 'delete') { + spinner.start('Deleting piece...') + const piece = pieces.find((piece) => piece.id === group.pieceId)! + const synapse = await Synapse.create({ + privateKey: privateKey as Hex, + rpcURL: RPC_URLS.calibration.http, + }) + const context = await synapse.storage.createContext({ + dataSetId: Number(group.dataSetId), + }) + const txHash = await context.deletePiece(piece.cid) + spinner.message('Waiting for transaction to be mined...') + await waitForTransactionReceipt(publicClient, { hash: txHash as Hex }) + spinner.stop('Piece deleted') + } else { + return + } + } catch (error) { + spinner.stop() + console.error(error) + return + } + } +) diff --git a/examples/cli/src/commands/upload.ts b/examples/cli/src/commands/upload.ts new file mode 100644 index 00000000..5c9f8801 --- /dev/null +++ b/examples/cli/src/commands/upload.ts @@ -0,0 +1,94 @@ +import * as p from '@clack/prompts' +import { RPC_URLS, Synapse } from '@filoz/synapse-sdk' +import { type Command, command } from 'cleye' +import { readFile } from 'fs/promises' +import path from 'path' +import type { Hex } from 'viem' +import config from '../config.ts' + +export const upload: Command = command( + { + name: 'upload', + parameters: [''], + description: 'Upload a file to the warm storage', + alias: 'u', + flags: { + forceCreateDataSet: { + type: Boolean, + description: 'Force create a new data set', + default: false, + }, + withCDN: { + type: Boolean, + description: 'Enable CDN', + default: false, + }, + dataSetId: { + type: Number, + description: 'The data set ID to use', + default: undefined, + }, + }, + help: { + description: 'Upload a file to the warm storage', + }, + }, + async (argv) => { + const privateKey = config.get('privateKey') + if (!privateKey) { + p.log.error('Private key not found') + p.outro('Please run `synapse init` to initialize the CLI') + return + } + + const spinner = p.spinner() + + const filePath = argv._.requiredPath + const absolutePath = path.resolve(filePath) + const fileData = await readFile(absolutePath) + + spinner.start(`Uploading file ${absolutePath}...`) + try { + const synapse = await Synapse.create({ + privateKey: privateKey as Hex, + rpcURL: RPC_URLS.calibration.http, // Use calibration testnet for testing + }) + + const upload = await synapse.storage.upload(fileData, { + forceCreateDataSet: argv.flags.forceCreateDataSet, + withCDN: argv.flags.withCDN, + dataSetId: argv.flags.dataSetId, + metadata: { + name: path.basename(absolutePath), + }, + callbacks: { + onDataSetCreationStarted(transaction) { + spinner.message(`Creating data set, tx: ${transaction.hash}`) + }, + onProviderSelected(provider) { + spinner.message(`Selected provider: ${provider.serviceProvider}`) + }, + onDataSetResolved(info) { + spinner.message(`Using existing data set: ${info.dataSetId}`) + }, + onUploadComplete(pieceCid) { + spinner.message(`Upload complete! PieceCID: ${pieceCid}`) + }, + onPieceAdded(transaction) { + spinner.message(`Piece add, tx: ${transaction?.hash}`) + }, + onPieceConfirmed(pieceIds) { + spinner.message(`Piece confirmed: ${pieceIds.join(', ')}`) + }, + }, + }) + + spinner.stop(`File uploaded ${upload.pieceCid}`) + } catch (error) { + spinner.stop() + p.log.error((error as Error).message) + p.outro('Please try again') + return + } + } +) diff --git a/examples/cli/src/config.ts b/examples/cli/src/config.ts new file mode 100644 index 00000000..a4c606d5 --- /dev/null +++ b/examples/cli/src/config.ts @@ -0,0 +1,20 @@ +import Conf from 'conf' + +const packageJson = { + name: 'synapse-cli', + version: '1.0.0', +} + +const schema = { + privateKey: { + type: 'string', + }, +} + +const config = new Conf<{ privateKey: string }>({ + projectName: packageJson.name, + projectVersion: packageJson.version, + schema, +}) + +export default config diff --git a/examples/cli/src/index.ts b/examples/cli/src/index.ts new file mode 100755 index 00000000..fc5ad792 --- /dev/null +++ b/examples/cli/src/index.ts @@ -0,0 +1,21 @@ +import { cli } from 'cleye' +import { datasetTerminate } from './commands/dataset-terminate.ts' +import { datasets } from './commands/datasets.ts' +import { deposit } from './commands/deposit.ts' +import { fund } from './commands/fund.ts' +import { init } from './commands/init.ts' +import { pay } from './commands/pay.ts' +import { pieces } from './commands/pieces.ts' +import { upload } from './commands/upload.ts' + +const argv = cli({ + name: 'synapse-cli', + version: '0.0.1', + + commands: [init, pay, fund, deposit, upload, datasets, datasetTerminate, pieces], +}) + +if (!argv.command) { + argv.showHelp() + process.exit(1) +} diff --git a/examples/cli/tsconfig.json b/examples/cli/tsconfig.json new file mode 100644 index 00000000..4f9b64b8 --- /dev/null +++ b/examples/cli/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "noEmit": true, + "outDir": "./dist" + }, + "include": ["src"], + "exclude": ["node_modules", "dist"], + "references": [ + { + "path": "../../packages/synapse-sdk" + }, + { + "path": "../../packages/synapse-core" + } + ] +} diff --git a/package.json b/package.json index 593cbc95..09cca8af 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "check:markdown": "markdownlint-cli2 --config .github/.markdownlint-cli2.jsonc '**/*.md' '**/*.mdx'", "check:repo": "pnpx sherif@latest -r root-package-manager-field", "check:knip": "knip --config .github/knip.jsonc", - "clean": "rm -rf node_modules pnpm-lock.yaml package-lock.json packages/*/{pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules} examples/*/{pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules} docs/{pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules,.astro} apps/*/{pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules}" + "clean": "rm -rf node_modules pnpm-lock.yaml package-lock.json packages/*/{.wireit,pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules} examples/*/{.wireit,pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules} docs/{.wireit,pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules,.astro} apps/*/{.wireit,pnpm-lock.yaml,package-lock.json,coverage,.nyc_output,dist,node_modules}" }, "devDependencies": { "@biomejs/biome": "~2.2.6", diff --git a/packages/synapse-core/package.json b/packages/synapse-core/package.json index db466c8d..2cd4b367 100644 --- a/packages/synapse-core/package.json +++ b/packages/synapse-core/package.json @@ -32,9 +32,9 @@ "types": "./dist/src/chains.d.ts", "default": "./dist/src/chains.js" }, - "./curio": { - "types": "./dist/src/curio.d.ts", - "default": "./dist/src/curio.js" + "./sp": { + "types": "./dist/src/sp.d.ts", + "default": "./dist/src/sp.js" }, "./erc20": { "types": "./dist/src/erc20.d.ts", @@ -67,6 +67,10 @@ "./errors": { "types": "./dist/src/errors/index.d.ts", "default": "./dist/src/errors/index.js" + }, + "./piece": { + "types": "./dist/src/piece.d.ts", + "default": "./dist/src/piece.js" } }, "typesVersions": { @@ -74,8 +78,8 @@ "chains": [ "./dist/src/chains" ], - "curio": [ - "./dist/src/curio" + "sp": [ + "./dist/src/sp" ], "erc20": [ "./dist/src/erc20" @@ -100,6 +104,9 @@ ], "errors": [ "./dist/src/errors/index" + ], + "piece": [ + "./dist/src/piece" ] } }, @@ -142,9 +149,10 @@ "@web3-storage/data-segment": "^5.3.0", "dnum": "^2.15.0", "filsnap-adapter": "^3.3.8", - "iso-web": "^1.4.0", + "iso-web": "^1.4.2", "multiformats": "^13.4.1", - "ox": "^0.9.12" + "ox": "^0.9.12", + "p-retry": "^7.1.0" }, "devDependencies": { "@biomejs/biome": "~2.2.6", diff --git a/packages/synapse-core/src/abis/generated.ts b/packages/synapse-core/src/abis/generated.ts index a58cc5e8..59c2714f 100644 --- a/packages/synapse-core/src/abis/generated.ts +++ b/packages/synapse-core/src/abis/generated.ts @@ -1,1321 +1,1650 @@ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FilecoinWarmStorageService +// Errors ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x80617b65FD2EEa1D7fDe2B4F85977670690ed348) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x0000000000000000000000000000000000000000) */ -export const filecoinWarmStorageServiceAbi = [ +export const errorsAbi = [ { - type: 'constructor', + type: 'error', inputs: [ - { name: '_pdpVerifierAddress', internalType: 'address', type: 'address' }, - { - name: '_paymentsContractAddress', - internalType: 'address', - type: 'address', - }, - { name: '_usdfcTokenAddress', internalType: 'address', type: 'address' }, - { - name: '_filCDNBeneficiaryAddress', - internalType: 'address', - type: 'address', - }, - { - name: '_serviceProviderRegistry', - internalType: 'contract ServiceProviderRegistry', - type: 'address', - }, { - name: '_sessionKeyRegistry', - internalType: 'contract SessionKeyRegistry', - type: 'address', + name: 'field', + internalType: 'enum Errors.AddressField', + type: 'uint8', }, ], - stateMutability: 'nonpayable', + name: 'AddressAlreadySet', }, { - type: 'function', - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [{ name: '', internalType: 'string', type: 'string' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'CDNPaymentAlreadyTerminated', }, { - type: 'function', - inputs: [], - name: 'VERSION', - outputs: [{ name: '', internalType: 'string', type: 'string' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'CacheMissPaymentAlreadyTerminated', }, { - type: 'function', - inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], - name: 'addApprovedProvider', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'expectedPayer', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, + ], + name: 'CallerNotPayer', }, { - type: 'function', - inputs: [{ name: 'totalBytes', internalType: 'uint256', type: 'uint256' }], - name: 'calculateRatesPerEpoch', - outputs: [ - { name: 'storageRate', internalType: 'uint256', type: 'uint256' }, - { name: 'cacheMissRate', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnRate', internalType: 'uint256', type: 'uint256' }, + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'expectedPayer', internalType: 'address', type: 'address' }, + { name: 'expectedPayee', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, ], - stateMutability: 'view', + name: 'CallerNotPayerOrPayee', }, { - type: 'function', + type: 'error', inputs: [ - { name: '_maxProvingPeriod', internalType: 'uint64', type: 'uint64' }, - { - name: '_challengeWindowSize', - internalType: 'uint256', - type: 'uint256', - }, + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, ], - name: 'configureProvingPeriod', - outputs: [], - stateMutability: 'nonpayable', + name: 'CallerNotPayments', }, { - type: 'function', + type: 'error', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: 'windowStart', internalType: 'uint256', type: 'uint256' }, + { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, ], - name: 'dataSetCreated', - outputs: [], - stateMutability: 'nonpayable', + name: 'ChallengeWindowTooEarly', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: '', internalType: 'uint256', type: 'uint256' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, ], - name: 'dataSetDeleted', - outputs: [], - stateMutability: 'nonpayable', + name: 'ClientDataSetAlreadyRegistered', }, { - type: 'function', - inputs: [], - name: 'eip712Domain', - outputs: [ - { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, - { name: 'name', internalType: 'string', type: 'string' }, - { name: 'version', internalType: 'string', type: 'string' }, - { name: 'chainId', internalType: 'uint256', type: 'uint256' }, - { name: 'verifyingContract', internalType: 'address', type: 'address' }, - { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, - { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, + type: 'error', + inputs: [ + { + name: 'commissionType', + internalType: 'enum Errors.CommissionType', + type: 'uint8', + }, + { name: 'max', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - stateMutability: 'view', + name: 'CommissionExceedsMaximum', }, { - type: 'function', - inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], - name: 'extsload', - outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'DataSetNotFoundForRail', }, { - type: 'function', - inputs: [ - { name: 'slot', internalType: 'bytes32', type: 'bytes32' }, - { name: 'size', internalType: 'uint256', type: 'uint256' }, - ], - name: 'extsloadStruct', - outputs: [{ name: '', internalType: 'bytes32[]', type: 'bytes32[]' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'DataSetNotRegistered', }, { - type: 'function', - inputs: [], - name: 'filCDNBeneficiaryAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'DataSetPaymentAlreadyTerminated', }, { - type: 'function', - inputs: [], - name: 'getEffectiveRates', - outputs: [ - { name: 'serviceFee', internalType: 'uint256', type: 'uint256' }, - { name: 'spPayment', internalType: 'uint256', type: 'uint256' }, + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'currentBlock', internalType: 'uint256', type: 'uint256' }, ], - stateMutability: 'view', + name: 'DataSetPaymentBeyondEndEpoch', }, + { type: 'error', inputs: [], name: 'DivisionByZero' }, { - type: 'function', + type: 'error', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'string', type: 'string' }, ], - name: 'getProvingPeriodForEpoch', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'DuplicateMetadataKey', }, + { type: 'error', inputs: [], name: 'ExtraDataRequired' }, { - type: 'function', - inputs: [], - name: 'getServicePrice', - outputs: [ - { - name: 'pricing', - internalType: 'struct FilecoinWarmStorageService.ServicePricing', - type: 'tuple', - components: [ - { - name: 'pricePerTiBPerMonthNoCDN', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'pricePerTiBPerMonthWithCDN', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'tokenAddress', internalType: 'address', type: 'address' }, - { name: 'epochsPerMonth', internalType: 'uint256', type: 'uint256' }, - ], - }, - ], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'FilBeamServiceNotConfigured', }, { - type: 'function', + type: 'error', inputs: [ - { name: '_maxProvingPeriod', internalType: 'uint64', type: 'uint64' }, - { - name: '_challengeWindowSize', - internalType: 'uint256', - type: 'uint256', - }, - { - name: '_filCDNControllerAddress', - internalType: 'address', - type: 'address', - }, - { name: '_name', internalType: 'string', type: 'string' }, - { name: '_description', internalType: 'string', type: 'string' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'minExpected', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', + name: 'InvalidChallengeCount', }, { - type: 'function', + type: 'error', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'epoch', internalType: 'uint256', type: 'uint256' }, + { name: 'minAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'isEpochProven', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: '_viewContract', internalType: 'address', type: 'address' }], - name: 'migrate', - outputs: [], - stateMutability: 'nonpayable', + name: 'InvalidChallengeEpoch', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'challengeEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'leafCount', internalType: 'uint256', type: 'uint256' }, - { name: '', internalType: 'bytes', type: 'bytes' }, + { name: 'maxProvingPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'challengeWindowSize', internalType: 'uint256', type: 'uint256' }, ], - name: 'nextProvingPeriod', - outputs: [], - stateMutability: 'nonpayable', + name: 'InvalidChallengeWindowSize', }, { - type: 'function', - inputs: [], - name: 'owner', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidDataSetId', }, { - type: 'function', - inputs: [], - name: 'paymentsContractAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [ + { name: 'fromEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'toEpoch', internalType: 'uint256', type: 'uint256' }, + ], + name: 'InvalidEpochRange', }, { - type: 'function', - inputs: [], - name: 'pdpVerifierAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidServiceDescriptionLength', }, { - type: 'function', + type: 'error', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidServiceNameLength', + }, + { + type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'firstAdded', internalType: 'uint256', type: 'uint256' }, - { - name: 'pieceData', - internalType: 'struct Cids.Cid[]', - type: 'tuple[]', - components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], - }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, ], - name: 'piecesAdded', - outputs: [], - stateMutability: 'nonpayable', + name: 'InvalidSignature', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: 'expectedLength', internalType: 'uint256', type: 'uint256' }, + { name: 'actualLength', internalType: 'uint256', type: 'uint256' }, ], - name: 'piecesScheduledRemove', - outputs: [], - stateMutability: 'nonpayable', + name: 'InvalidSignatureLength', }, { - type: 'function', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidTopUpAmount', + }, + { type: 'error', inputs: [], name: 'MaxProvingPeriodZero' }, + { + type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: '', internalType: 'uint256', type: 'uint256' }, - { name: '', internalType: 'uint256', type: 'uint256' }, - { name: 'challengeCount', internalType: 'uint256', type: 'uint256' }, + { name: 'metadataArrayCount', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceCount', internalType: 'uint256', type: 'uint256' }, ], - name: 'possessionProven', - outputs: [], - stateMutability: 'nonpayable', + name: 'MetadataArrayCountMismatch', }, { - type: 'function', - inputs: [], - name: 'proxiableUUID', - outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], - stateMutability: 'view', + type: 'error', + inputs: [ + { name: 'keysLength', internalType: 'uint256', type: 'uint256' }, + { name: 'valuesLength', internalType: 'uint256', type: 'uint256' }, + ], + name: 'MetadataKeyAndValueLengthMismatch', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'terminator', internalType: 'address', type: 'address' }, - { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'length', internalType: 'uint256', type: 'uint256' }, ], - name: 'railTerminated', - outputs: [], - stateMutability: 'nonpayable', + name: 'MetadataKeyExceedsMaxLength', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'length', internalType: 'uint256', type: 'uint256' }, ], - name: 'removeApprovedProvider', - outputs: [], - stateMutability: 'nonpayable', + name: 'MetadataValueExceedsMaxLength', }, { - type: 'function', - inputs: [], - name: 'renounceOwnership', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'periodDeadline', internalType: 'uint256', type: 'uint256' }, + { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NextProvingPeriodAlreadyCalled', }, { - type: 'function', - inputs: [], - name: 'serviceCommissionBps', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'NoPDPPaymentRail', }, { - type: 'function', - inputs: [], - name: 'serviceProviderRegistry', - outputs: [ - { - name: '', - internalType: 'contract ServiceProviderRegistry', - type: 'address', - }, + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, ], - stateMutability: 'view', + name: 'OldServiceProviderMismatch', }, { - type: 'function', - inputs: [], - name: 'sessionKeyRegistry', - outputs: [ - { - name: '', - internalType: 'contract SessionKeyRegistry', - type: 'address', - }, + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, ], - stateMutability: 'view', + name: 'OnlyFilBeamControllerAllowed', }, { - type: 'function', - inputs: [{ name: '_viewContract', internalType: 'address', type: 'address' }], - name: 'setViewContract', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, + ], + name: 'OnlyPDPVerifierAllowed', }, { - type: 'function', + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, + ], + name: 'OnlySelf', + }, + { + type: 'error', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'oldServiceProvider', internalType: 'address', type: 'address' }, - { name: 'newServiceProvider', internalType: 'address', type: 'address' }, - { name: '', internalType: 'bytes', type: 'bytes' }, + { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, ], - name: 'storageProviderChanged', - outputs: [], - stateMutability: 'nonpayable', + name: 'PaymentRailsNotFinalized', }, { - type: 'function', + type: 'error', inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'terminateCDNService', - outputs: [], - stateMutability: 'nonpayable', + name: 'ProofAlreadySubmitted', }, { - type: 'function', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'terminateService', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'ProviderAlreadyApproved', }, { - type: 'function', - inputs: [{ name: 'newController', internalType: 'address', type: 'address' }], - name: 'transferFilCDNController', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'ProviderNotInApprovedList', }, { - type: 'function', - inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], - name: 'transferOwnership', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'provider', internalType: 'address', type: 'address' }], + name: 'ProviderNotRegistered', }, { - type: 'function', - inputs: [{ name: 'newCommissionBps', internalType: 'uint256', type: 'uint256' }], - name: 'updateServiceCommission', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'ProvingNotStarted', }, { - type: 'function', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'ProvingPeriodNotInitialized', + }, + { + type: 'error', inputs: [ - { name: 'newImplementation', internalType: 'address', type: 'address' }, - { name: 'data', internalType: 'bytes', type: 'bytes' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', + name: 'ProvingPeriodPassed', }, { - type: 'function', - inputs: [], - name: 'usdfcTokenAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'RailNotAssociated', }, + { type: 'error', inputs: [], name: 'ServiceContractMustTerminateRail' }, { - type: 'function', + type: 'error', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'proposedAmount', internalType: 'uint256', type: 'uint256' }, - { name: 'fromEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'toEpoch', internalType: 'uint256', type: 'uint256' }, - { name: '', internalType: 'uint256', type: 'uint256' }, - ], - name: 'validatePayment', - outputs: [ - { - name: 'result', - internalType: 'struct IValidator.ValidationResult', - type: 'tuple', - components: [ - { name: 'modifiedAmount', internalType: 'uint256', type: 'uint256' }, - { name: 'settleUpto', internalType: 'uint256', type: 'uint256' }, - { name: 'note', internalType: 'string', type: 'string' }, - ], - }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'keysLength', internalType: 'uint256', type: 'uint256' }, ], - stateMutability: 'nonpayable', + name: 'TooManyMetadataKeys', }, { - type: 'function', - inputs: [], - name: 'viewContractAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'v', internalType: 'uint8', type: 'uint8' }], + name: 'UnsupportedSignatureV', }, { - type: 'event', - anonymous: false, + type: 'error', inputs: [ { - name: 'dataSetId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'endEpoch', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'cacheMissRailId', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'cdnRailId', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'field', + internalType: 'enum Errors.AddressField', + type: 'uint8', }, ], - name: 'CDNPaymentTerminated', + name: 'ZeroAddress', + }, +] as const + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x0000000000000000000000000000000000000000) + */ +export const errorsAddress = { + 314: '0x0000000000000000000000000000000000000000', + 314159: '0x0000000000000000000000000000000000000000', +} as const + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x0000000000000000000000000000000000000000) + */ +export const errorsConfig = { address: errorsAddress, abi: errorsAbi } as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// FilecoinPayV1 +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0) + */ +export const filecoinPayV1Abi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [], + name: 'COMMISSION_MAX_BPS', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [], + name: 'NETWORK_FEE_DENOMINATOR', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'NETWORK_FEE_NUMERATOR', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ - { - name: 'caller', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'dataSetId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'cacheMissRailId', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'cdnRailId', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, ], - name: 'CDNServiceTerminated', + name: 'accounts', + outputs: [ + { name: 'funds', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupCurrent', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupRate', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupLastSettledAt', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { - name: 'version', - internalType: 'string', - type: 'string', - indexed: false, - }, - { - name: 'implementation', - internalType: 'address', - type: 'address', - indexed: false, - }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, ], - name: 'ContractUpgraded', + name: 'auctionInfo', + outputs: [ + { name: 'startPrice', internalType: 'uint88', type: 'uint88' }, + { name: 'startTime', internalType: 'uint168', type: 'uint168' }, + ], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'requested', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burnForFees', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'validator', internalType: 'address', type: 'address' }, + { name: 'commissionRateBps', internalType: 'uint256', type: 'uint256' }, + { name: 'serviceFeeRecipient', internalType: 'address', type: 'address' }, + ], + name: 'createRail', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC3009', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'validAfter', internalType: 'uint256', type: 'uint256' }, + { name: 'validBefore', internalType: 'uint256', type: 'uint256' }, + { name: 'nonce', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'depositWithAuthorization', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC3009', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'validAfter', internalType: 'uint256', type: 'uint256' }, + { name: 'validBefore', internalType: 'uint256', type: 'uint256' }, + { name: 'nonce', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + ], + name: 'depositWithAuthorizationAndApproveOperator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', inputs: [ + { name: 'token', internalType: 'contract IERC3009', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'validAfter', internalType: 'uint256', type: 'uint256' }, + { name: 'validBefore', internalType: 'uint256', type: 'uint256' }, + { name: 'nonce', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'operator', internalType: 'address', type: 'address' }, { - name: 'dataSetId', + name: 'rateAllowanceIncrease', internalType: 'uint256', type: 'uint256', - indexed: true, }, { - name: 'providerId', + name: 'lockupAllowanceIncrease', internalType: 'uint256', type: 'uint256', - indexed: true, }, + ], + name: 'depositWithAuthorizationAndIncreaseOperatorApproval', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'depositWithPermit', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + ], + name: 'depositWithPermitAndApproveOperator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'operator', internalType: 'address', type: 'address' }, { - name: 'pdpRailId', + name: 'rateAllowanceIncrease', internalType: 'uint256', type: 'uint256', - indexed: false, }, { - name: 'cacheMissRailId', + name: 'lockupAllowanceIncrease', internalType: 'uint256', type: 'uint256', - indexed: false, - }, - { - name: 'cdnRailId', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'payer', - internalType: 'address', - type: 'address', - indexed: false, - }, - { - name: 'serviceProvider', - internalType: 'address', - type: 'address', - indexed: false, - }, - { - name: 'payee', - internalType: 'address', - type: 'address', - indexed: false, - }, - { - name: 'metadataKeys', - internalType: 'string[]', - type: 'string[]', - indexed: false, - }, - { - name: 'metadataValues', - internalType: 'string[]', - type: 'string[]', - indexed: false, }, ], - name: 'DataSetCreated', + name: 'depositWithPermitAndIncreaseOperatorApproval', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, + ], + name: 'getAccountInfoIfSettled', + outputs: [ + { name: 'fundedUntilEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'currentFunds', internalType: 'uint256', type: 'uint256' }, + { name: 'availableFunds', internalType: 'uint256', type: 'uint256' }, + { name: 'currentLockupRate', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'getRail', + outputs: [ { - name: 'dataSetId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'oldServiceProvider', - internalType: 'address', - type: 'address', - indexed: true, + name: '', + internalType: 'struct FilecoinPayV1.RailView', + type: 'tuple', + components: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'validator', internalType: 'address', type: 'address' }, + { name: 'paymentRate', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupFixed', internalType: 'uint256', type: 'uint256' }, + { name: 'settledUpTo', internalType: 'uint256', type: 'uint256' }, + { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, + { + name: 'commissionRateBps', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'serviceFeeRecipient', + internalType: 'address', + type: 'address', + }, + ], }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getRailsForPayeeAndToken', + outputs: [ { - name: 'newServiceProvider', - internalType: 'address', - type: 'address', - indexed: true, + name: 'results', + internalType: 'struct FilecoinPayV1.RailInfo[]', + type: 'tuple[]', + components: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'isTerminated', internalType: 'bool', type: 'bool' }, + { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, + ], }, + { name: 'nextOffset', internalType: 'uint256', type: 'uint256' }, + { name: 'total', internalType: 'uint256', type: 'uint256' }, ], - name: 'DataSetServiceProviderChanged', + stateMutability: 'view', }, - { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ + { name: 'payer', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getRailsForPayerAndToken', + outputs: [ { - name: 'dataSetId', - internalType: 'uint256', - type: 'uint256', - indexed: true, + name: 'results', + internalType: 'struct FilecoinPayV1.RailInfo[]', + type: 'tuple[]', + components: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'isTerminated', internalType: 'bool', type: 'bool' }, + { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, + ], }, + { name: 'nextOffset', internalType: 'uint256', type: 'uint256' }, + { name: 'total', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'getRateChangeQueueSize', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, { - name: 'periodsFaulted', + name: 'rateAllowanceIncrease', internalType: 'uint256', type: 'uint256', - indexed: false, }, { - name: 'deadline', + name: 'lockupAllowanceIncrease', internalType: 'uint256', type: 'uint256', - indexed: false, }, ], - name: 'FaultRecord', + name: 'increaseOperatorApproval', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { - name: 'oldController', - internalType: 'address', - type: 'address', - indexed: false, - }, - { - name: 'newController', - internalType: 'address', - type: 'address', - indexed: false, - }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'period', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupFixed', internalType: 'uint256', type: 'uint256' }, ], - name: 'FilCDNControllerChanged', + name: 'modifyRailLockup', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { name: 'name', internalType: 'string', type: 'string', indexed: false }, - { - name: 'description', - internalType: 'string', - type: 'string', - indexed: false, - }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'newRate', internalType: 'uint256', type: 'uint256' }, + { name: 'oneTimePayment', internalType: 'uint256', type: 'uint256' }, ], - name: 'FilecoinServiceDeployed', + name: 'modifyRailPayment', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { - name: 'version', - internalType: 'uint64', - type: 'uint64', - indexed: false, - }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'client', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, ], - name: 'Initialized', + name: 'operatorApprovals', + outputs: [ + { name: 'isApproved', internalType: 'bool', type: 'bool' }, + { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'rateUsage', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupUsage', internalType: 'uint256', type: 'uint256' }, + { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { - name: 'previousOwner', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'newOwner', - internalType: 'address', - type: 'address', - indexed: true, - }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'approved', internalType: 'bool', type: 'bool' }, + { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, ], - name: 'OwnershipTransferred', + name: 'setOperatorApproval', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'untilEpoch', internalType: 'uint256', type: 'uint256' }, + ], + name: 'settleRail', + outputs: [ + { name: 'totalSettledAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'totalNetPayeeAmount', internalType: 'uint256', type: 'uint256' }, { - name: 'dataSetId', + name: 'totalOperatorCommission', internalType: 'uint256', type: 'uint256', - indexed: true, - }, - { - name: 'endEpoch', - internalType: 'uint256', - type: 'uint256', - indexed: false, }, + { name: 'totalNetworkFee', internalType: 'uint256', type: 'uint256' }, + { name: 'finalSettledEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'note', internalType: 'string', type: 'string' }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'settleTerminatedRailWithoutValidation', + outputs: [ + { name: 'totalSettledAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'totalNetPayeeAmount', internalType: 'uint256', type: 'uint256' }, { - name: 'pdpRailId', + name: 'totalOperatorCommission', internalType: 'uint256', type: 'uint256', - indexed: false, }, + { name: 'totalNetworkFee', internalType: 'uint256', type: 'uint256' }, + { name: 'finalSettledEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'note', internalType: 'string', type: 'string' }, ], - name: 'PDPPaymentTerminated', + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'terminateRail', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'withdraw', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'withdrawTo', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'event', anonymous: false, inputs: [ { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, }, { - name: 'dataSetId', + name: 'owner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'lockupCurrent', internalType: 'uint256', type: 'uint256', indexed: false, }, { - name: 'originalAmount', + name: 'lockupRate', internalType: 'uint256', type: 'uint256', indexed: false, }, { - name: 'modifiedAmount', + name: 'lockupLastSettledAt', internalType: 'uint256', type: 'uint256', indexed: false, }, + ], + name: 'AccountLockupSettled', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, { - name: 'faultedEpochs', + name: 'amount', internalType: 'uint256', type: 'uint256', indexed: false, }, ], - name: 'PaymentArbitrated', + name: 'DepositRecorded', }, { type: 'event', anonymous: false, inputs: [ { - name: 'dataSetId', - internalType: 'uint256', - type: 'uint256', + name: 'token', + internalType: 'contract IERC20', + type: 'address', indexed: true, }, { - name: 'pieceId', - internalType: 'uint256', - type: 'uint256', + name: 'client', + internalType: 'address', + type: 'address', indexed: true, }, { - name: 'pieceCid', - internalType: 'struct Cids.Cid', - type: 'tuple', - components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + name: 'operator', + internalType: 'address', + type: 'address', + indexed: true, + }, + { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, + { + name: 'rateAllowance', + internalType: 'uint256', + type: 'uint256', indexed: false, }, { - name: 'keys', - internalType: 'string[]', - type: 'string[]', + name: 'lockupAllowance', + internalType: 'uint256', + type: 'uint256', indexed: false, }, { - name: 'values', - internalType: 'string[]', - type: 'string[]', + name: 'maxLockupPeriod', + internalType: 'uint256', + type: 'uint256', indexed: false, }, ], - name: 'PieceAdded', + name: 'OperatorApprovalUpdated', }, { type: 'event', anonymous: false, inputs: [ { - name: 'providerId', + name: 'railId', internalType: 'uint256', type: 'uint256', indexed: true, }, + { + name: 'payer', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'payee', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: false, + }, + { + name: 'operator', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'validator', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'serviceFeeRecipient', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'commissionRateBps', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'ProviderApproved', + name: 'RailCreated', }, { type: 'event', anonymous: false, inputs: [ { - name: 'providerId', + name: 'railId', internalType: 'uint256', type: 'uint256', indexed: true, }, ], - name: 'ProviderUnapproved', + name: 'RailFinalized', }, { type: 'event', anonymous: false, inputs: [ { - name: 'dataSetId', + name: 'railId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'railId', + name: 'oldLockupPeriod', internalType: 'uint256', type: 'uint256', indexed: false, }, { - name: 'newRate', + name: 'newLockupPeriod', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'oldLockupFixed', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newLockupFixed', internalType: 'uint256', type: 'uint256', indexed: false, }, ], - name: 'RailRateUpdated', + name: 'RailLockupModified', }, { type: 'event', anonymous: false, inputs: [ { - name: 'caller', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'dataSetId', + name: 'railId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'pdpRailId', + name: 'netPayeeAmount', internalType: 'uint256', type: 'uint256', indexed: false, }, { - name: 'cacheMissRailId', + name: 'operatorCommission', internalType: 'uint256', type: 'uint256', indexed: false, }, { - name: 'cdnRailId', + name: 'networkFee', internalType: 'uint256', type: 'uint256', indexed: false, }, ], - name: 'ServiceTerminated', + name: 'RailOneTimePaymentProcessed', }, { type: 'event', anonymous: false, inputs: [ { - name: 'implementation', - internalType: 'address', - type: 'address', + name: 'railId', + internalType: 'uint256', + type: 'uint256', indexed: true, }, + { + name: 'oldRate', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newRate', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'Upgraded', + name: 'RailRateModified', }, { type: 'event', anonymous: false, inputs: [ { - name: 'viewContract', - internalType: 'address', - type: 'address', + name: 'railId', + internalType: 'uint256', + type: 'uint256', indexed: true, }, - ], - name: 'ViewContractSet', - }, - { - type: 'error', - inputs: [{ name: 'target', internalType: 'address', type: 'address' }], - name: 'AddressEmptyCode', - }, - { - type: 'error', - inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'expectedPayer', internalType: 'address', type: 'address' }, - { name: 'expectedPayee', internalType: 'address', type: 'address' }, - { name: 'caller', internalType: 'address', type: 'address' }, - ], - name: 'CallerNotPayerOrPayee', - }, - { - type: 'error', - inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, - ], - name: 'CallerNotPayments', + { + name: 'totalSettledAmount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'totalNetPayeeAmount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'operatorCommission', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'networkFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'settledUpTo', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'RailSettled', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'windowStart', internalType: 'uint256', type: 'uint256' }, - { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, + { + name: 'railId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'by', internalType: 'address', type: 'address', indexed: true }, + { + name: 'endEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'ChallengeWindowTooEarly', + name: 'RailTerminated', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ { - name: 'commissionType', - internalType: 'enum Errors.CommissionType', - type: 'uint8', + name: 'token', + internalType: 'contract IERC20', + type: 'address', + indexed: true, + }, + { name: 'from', internalType: 'address', type: 'address', indexed: true }, + { name: 'to', internalType: 'address', type: 'address', indexed: true }, + { + name: 'amount', + internalType: 'uint256', + type: 'uint256', + indexed: false, }, - { name: 'max', internalType: 'uint256', type: 'uint256' }, - { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'CommissionExceedsMaximum', - }, - { - type: 'error', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'DataSetNotFoundForRail', + name: 'WithdrawRecorded', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'DataSetNotRegistered', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'maxSettlementEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'blockNumber', internalType: 'uint256', type: 'uint256' }, + ], + name: 'CannotModifyTerminatedRailBeyondEndEpoch', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'DataSetPaymentAlreadyTerminated', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowedEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedEpoch', internalType: 'uint256', type: 'uint256' }, + ], + name: 'CannotSettleFutureEpochs', }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'requiredBlock', internalType: 'uint256', type: 'uint256' }, { name: 'currentBlock', internalType: 'uint256', type: 'uint256' }, ], - name: 'DataSetPaymentBeyondEndEpoch', + name: 'CannotSettleTerminatedRailBeforeMaxEpoch', }, - { type: 'error', inputs: [], name: 'DivisionByZero' }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'key', internalType: 'string', type: 'string' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'DuplicateMetadataKey', - }, - { - type: 'error', - inputs: [{ name: 'implementation', internalType: 'address', type: 'address' }], - name: 'ERC1967InvalidImplementation', + name: 'CommissionRateTooHigh', }, - { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, - { type: 'error', inputs: [], name: 'ExtraDataRequired' }, - { type: 'error', inputs: [], name: 'FailedCall' }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'FilCDNPaymentAlreadyTerminated', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'oldLockup', internalType: 'uint256', type: 'uint256' }, + { name: 'currentLockup', internalType: 'uint256', type: 'uint256' }, + ], + name: 'CurrentLockupLessThanOldLockup', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'FilCDNServiceNotConfigured', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'currentLockup', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupReduction', internalType: 'uint256', type: 'uint256' }, + ], + name: 'InsufficientCurrentLockup', }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'minExpected', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'required', internalType: 'uint256', type: 'uint256' }, { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'InvalidChallengeCount', + name: 'InsufficientFundsForOneTimePayment', }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'minAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'actual', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'available', internalType: 'uint256', type: 'uint256' }, + { name: 'required', internalType: 'uint256', type: 'uint256' }, ], - name: 'InvalidChallengeEpoch', + name: 'InsufficientFundsForSettlement', }, { type: 'error', inputs: [ - { name: 'maxProvingPeriod', internalType: 'uint256', type: 'uint256' }, - { name: 'challengeWindowSize', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'available', internalType: 'uint256', type: 'uint256' }, + { name: 'required', internalType: 'uint256', type: 'uint256' }, ], - name: 'InvalidChallengeWindowSize', + name: 'InsufficientLockupForSettlement', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'InvalidDataSetId', + inputs: [ + { name: 'required', internalType: 'uint256', type: 'uint256' }, + { name: 'sent', internalType: 'uint256', type: 'uint256' }, + ], + name: 'InsufficientNativeTokenForBurn', }, { type: 'error', inputs: [ - { name: 'fromEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'toEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'available', internalType: 'uint256', type: 'uint256' }, + { name: 'requested', internalType: 'uint256', type: 'uint256' }, ], - name: 'InvalidEpochRange', + name: 'InsufficientUnlockedFunds', }, - { type: 'error', inputs: [], name: 'InvalidInitialization' }, { type: 'error', inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, + { + name: 'nextRateChangeUntilEpoch', + internalType: 'uint256', + type: 'uint256', + }, + { name: 'processedEpoch', internalType: 'uint256', type: 'uint256' }, ], - name: 'InvalidSignature', + name: 'InvalidRateChangeQueueState', }, { type: 'error', inputs: [ - { name: 'expectedLength', internalType: 'uint256', type: 'uint256' }, - { name: 'actualLength', internalType: 'uint256', type: 'uint256' }, + { name: 'actualPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'actualLockupFixed', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedPeriod', internalType: 'uint256', type: 'uint256' }, + { + name: 'attemptedLockupFixed', + internalType: 'uint256', + type: 'uint256', + }, ], - name: 'InvalidSignatureLength', + name: 'InvalidTerminatedRailModification', }, - { type: 'error', inputs: [], name: 'MaxProvingPeriodZero' }, { type: 'error', inputs: [ - { name: 'metadataArrayCount', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceCount', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'account', internalType: 'address', type: 'address' }, + { name: 'lockupCurrent', internalType: 'uint256', type: 'uint256' }, + { name: 'fundsCurrent', internalType: 'uint256', type: 'uint256' }, ], - name: 'MetadataArrayCountMismatch', + name: 'LockupExceedsFundsInvariant', }, { type: 'error', inputs: [ - { name: 'keysLength', internalType: 'uint256', type: 'uint256' }, - { name: 'valuesLength', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'actualLockupFixed', internalType: 'uint256', type: 'uint256' }, + { + name: 'attemptedLockupFixed', + internalType: 'uint256', + type: 'uint256', + }, ], - name: 'MetadataKeyAndValueLengthMismatch', + name: 'LockupFixedIncreaseNotAllowedDueToInsufficientFunds', }, { type: 'error', inputs: [ - { name: 'index', internalType: 'uint256', type: 'uint256' }, - { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'length', internalType: 'uint256', type: 'uint256' }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'expectedLockup', internalType: 'uint256', type: 'uint256' }, + { name: 'actualLockup', internalType: 'uint256', type: 'uint256' }, ], - name: 'MetadataKeyExceedsMaxLength', + name: 'LockupInconsistencyDuringRailFinalization', }, { type: 'error', inputs: [ - { name: 'index', internalType: 'uint256', type: 'uint256' }, - { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'length', internalType: 'uint256', type: 'uint256' }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'isSettled', internalType: 'bool', type: 'bool' }, + { name: 'currentRate', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedRate', internalType: 'uint256', type: 'uint256' }, ], - name: 'MetadataValueExceedsMaxLength', + name: 'LockupNotSettledRateChangeNotAllowed', }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'periodDeadline', internalType: 'uint256', type: 'uint256' }, - { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'actualLockupPeriod', internalType: 'uint256', type: 'uint256' }, + { + name: 'attemptedLockupPeriod', + internalType: 'uint256', + type: 'uint256', + }, ], - name: 'NextProvingPeriodAlreadyCalled', + name: 'LockupPeriodChangeNotAllowedDueToInsufficientFunds', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'NoPDPPaymentRail', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'maxAllowedPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'requestedPeriod', internalType: 'uint256', type: 'uint256' }, + ], + name: 'LockupPeriodExceedsOperatorMaximum', }, - { type: 'error', inputs: [], name: 'NotInitializing' }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'paymentRate', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupRate', internalType: 'uint256', type: 'uint256' }, ], - name: 'OldServiceProviderMismatch', + name: 'LockupRateInconsistent', }, { type: 'error', inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'lockupRate', internalType: 'uint256', type: 'uint256' }, + { name: 'oldRate', internalType: 'uint256', type: 'uint256' }, ], - name: 'OnlyFilCDNControllerAllowed', + name: 'LockupRateLessThanOldRate', }, + { type: 'error', inputs: [], name: 'MissingServiceFeeRecipient' }, { type: 'error', inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, + { name: 'required', internalType: 'uint256', type: 'uint256' }, + { name: 'sent', internalType: 'uint256', type: 'uint256' }, ], - name: 'OnlyPDPVerifierAllowed', + name: 'MustSendExactNativeAmount', + }, + { + type: 'error', + inputs: [{ name: 'sent', internalType: 'uint256', type: 'uint256' }], + name: 'NativeTokenNotAccepted', }, + { type: 'error', inputs: [], name: 'NativeTokenNotSupported' }, { type: 'error', inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, ], - name: 'OnlySelf', + name: 'NativeTransferFailed', }, { type: 'error', - inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], - name: 'OwnableInvalidOwner', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'expectedSettledUpTo', internalType: 'uint256', type: 'uint256' }, + { name: 'actualSettledUpTo', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NoProgressInSettlement', }, { type: 'error', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'OwnableUnauthorizedAccount', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'allowedClient', internalType: 'address', type: 'address' }, + { name: 'allowedOperator', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, + ], + name: 'NotAuthorizedToTerminateRail', }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'available', internalType: 'uint256', type: 'uint256' }, + { name: 'required', internalType: 'uint256', type: 'uint256' }, ], - name: 'PaymentRailsNotFinalized', + name: 'OneTimePaymentExceedsLockup', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'ProofAlreadySubmitted', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, + ], + name: 'OnlyRailClientAllowed', }, { type: 'error', - inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], - name: 'ProviderAlreadyApproved', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, + ], + name: 'OnlyRailOperatorAllowed', }, { type: 'error', inputs: [ - { name: 'provider', internalType: 'address', type: 'address' }, - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { name: 'allowed', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedUsage', internalType: 'uint256', type: 'uint256' }, ], - name: 'ProviderNotApproved', + name: 'OperatorLockupAllowanceExceeded', }, { type: 'error', - inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], - name: 'ProviderNotInApprovedList', + inputs: [ + { name: 'from', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, + ], + name: 'OperatorNotApproved', }, { type: 'error', - inputs: [{ name: 'provider', internalType: 'address', type: 'address' }], - name: 'ProviderNotRegistered', + inputs: [ + { name: 'allowed', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedUsage', internalType: 'uint256', type: 'uint256' }, + ], + name: 'OperatorRateAllowanceExceeded', }, { type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'ProvingNotStarted', + inputs: [ + { name: 'x', internalType: 'uint256', type: 'uint256' }, + { name: 'y', internalType: 'uint256', type: 'uint256' }, + { name: 'denominator', internalType: 'uint256', type: 'uint256' }, + ], + name: 'PRBMath_MulDiv_Overflow', + }, + { + type: 'error', + inputs: [{ name: 'x', internalType: 'UD60x18', type: 'uint256' }], + name: 'PRBMath_UD60x18_Exp2_InputTooBig', + }, + { + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'RailAlreadyTerminated', + }, + { + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'RailInactiveOrSettled', + }, + { + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'RailNotTerminated', + }, + { + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'RateChangeNotAllowedOnTerminatedRail', }, { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'deadline', internalType: 'uint256', type: 'uint256' }, - { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'nextUntilEpoch', internalType: 'uint256', type: 'uint256' }, ], - name: 'ProvingPeriodPassed', + name: 'RateChangeQueueNotEmpty', }, + { type: 'error', inputs: [], name: 'ReentrancyGuardReentrantCall' }, { type: 'error', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'RailNotAssociated', + inputs: [{ name: 'token', internalType: 'address', type: 'address' }], + name: 'SafeERC20FailedOperation', + }, + { + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, + ], + name: 'SignerMustBeMsgSender', }, - { type: 'error', inputs: [], name: 'ServiceContractMustTerminateRail' }, { type: 'error', inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'keysLength', internalType: 'uint256', type: 'uint256' }, + { name: 'attempted', internalType: 'uint256', type: 'uint256' }, ], - name: 'TooManyMetadataKeys', + name: 'ValidatorModifiedAmountExceedsMaximum', }, - { type: 'error', inputs: [], name: 'UUPSUnauthorizedCallContext' }, { type: 'error', - inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], - name: 'UUPSUnsupportedProxiableUUID', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'allowedStart', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedStart', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ValidatorSettledBeforeSegmentStart', }, { type: 'error', - inputs: [{ name: 'v', internalType: 'uint8', type: 'uint8' }], - name: 'UnsupportedSignatureV', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'allowedEnd', internalType: 'uint256', type: 'uint256' }, + { name: 'attemptedEnd', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ValidatorSettledBeyondSegmentEnd', }, { type: 'error', inputs: [ - { - name: 'field', - internalType: 'enum Errors.AddressField', - type: 'uint8', - }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'available', internalType: 'uint256', type: 'uint256' }, + { name: 'requested', internalType: 'uint256', type: 'uint256' }, ], - name: 'ZeroAddress', + name: 'WithdrawAmountExceedsAccumulatedFees', + }, + { + type: 'error', + inputs: [{ name: 'varName', internalType: 'string', type: 'string' }], + name: 'ZeroAddressNotAllowed', }, ] as const /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x80617b65FD2EEa1D7fDe2B4F85977670690ed348) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0) */ -export const filecoinWarmStorageServiceAddress = { +export const filecoinPayV1Address = { 314: '0x0000000000000000000000000000000000000000', - 314159: '0x80617b65FD2EEa1D7fDe2B4F85977670690ed348', + 314159: '0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0', } as const /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x80617b65FD2EEa1D7fDe2B4F85977670690ed348) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0) */ -export const filecoinWarmStorageServiceConfig = { - address: filecoinWarmStorageServiceAddress, - abi: filecoinWarmStorageServiceAbi, +export const filecoinPayV1Config = { + address: filecoinPayV1Address, + abi: filecoinPayV1Abi, } as const ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FilecoinWarmStorageServiceStateView +// FilecoinWarmStorageService ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x87EDE87cEF4BfeFE0374c3470cB3F5be18b739d5) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xD3De778C05f89e1240ef70100Fb0d9e5b2eFD258) */ -export const filecoinWarmStorageServiceStateViewAbi = [ +export const filecoinWarmStorageServiceAbi = [ { type: 'constructor', inputs: [ + { name: '_pdpVerifierAddress', internalType: 'address', type: 'address' }, { - name: '_service', - internalType: 'contract FilecoinWarmStorageService', + name: '_paymentsContractAddress', + internalType: 'address', + type: 'address', + }, + { + name: '_usdfc', + internalType: 'contract IERC20Metadata', + type: 'address', + }, + { + name: '_filBeamBeneficiaryAddress', + internalType: 'address', + type: 'address', + }, + { + name: '_serviceProviderRegistry', + internalType: 'contract ServiceProviderRegistry', + type: 'address', + }, + { + name: '_sessionKeyRegistry', + internalType: 'contract SessionKeyRegistry', type: 'address', }, ], @@ -1324,160 +1653,138 @@ export const filecoinWarmStorageServiceStateViewAbi = [ { type: 'function', inputs: [], - name: 'challengeWindow', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + name: 'UPGRADE_INTERFACE_VERSION', + outputs: [{ name: '', internalType: 'string', type: 'string' }], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'payer', internalType: 'address', type: 'address' }], - name: 'clientDataSetIDs', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + inputs: [], + name: 'VERSION', + outputs: [{ name: '', internalType: 'string', type: 'string' }], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'payer', internalType: 'address', type: 'address' }], - name: 'clientDataSets', - outputs: [{ name: 'dataSetIds', internalType: 'uint256[]', type: 'uint256[]' }], - stateMutability: 'view', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'addApprovedProvider', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [], - name: 'filCDNControllerAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + inputs: [ + { + name: 'plannedUpgrade', + internalType: 'struct FilecoinWarmStorageService.PlannedUpgrade', + type: 'tuple', + components: [ + { + name: 'nextImplementation', + internalType: 'address', + type: 'address', + }, + { name: 'afterEpoch', internalType: 'uint96', type: 'uint96' }, + ], + }, + ], + name: 'announcePlannedUpgrade', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'getAllDataSetMetadata', + inputs: [{ name: 'totalBytes', internalType: 'uint256', type: 'uint256' }], + name: 'calculateRatesPerEpoch', outputs: [ - { name: 'keys', internalType: 'string[]', type: 'string[]' }, - { name: 'values', internalType: 'string[]', type: 'string[]' }, + { name: 'storageRate', internalType: 'uint256', type: 'uint256' }, + { name: 'cacheMissRate', internalType: 'uint256', type: 'uint256' }, + { name: 'cdnRate', internalType: 'uint256', type: 'uint256' }, ], stateMutability: 'view', }, { type: 'function', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - ], - name: 'getAllPieceMetadata', - outputs: [ - { name: 'keys', internalType: 'string[]', type: 'string[]' }, - { name: 'values', internalType: 'string[]', type: 'string[]' }, + { name: '_maxProvingPeriod', internalType: 'uint64', type: 'uint64' }, + { + name: '_challengeWindowSize', + internalType: 'uint256', + type: 'uint256', + }, ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'getApprovedProviders', - outputs: [{ name: 'providerIds', internalType: 'uint256[]', type: 'uint256[]' }], - stateMutability: 'view', + name: 'configureProvingPeriod', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [], - name: 'getChallengesPerProof', - outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], - stateMutability: 'pure', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'serviceProvider', internalType: 'address', type: 'address' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'dataSetCreated', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'client', internalType: 'address', type: 'address' }], - name: 'getClientDataSets', - outputs: [ - { - name: 'infos', - internalType: 'struct FilecoinWarmStorageService.DataSetInfo[]', - type: 'tuple[]', - components: [ - { name: 'pdpRailId', internalType: 'uint256', type: 'uint256' }, - { name: 'cacheMissRailId', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnRailId', internalType: 'uint256', type: 'uint256' }, - { name: 'payer', internalType: 'address', type: 'address' }, - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'commissionBps', internalType: 'uint256', type: 'uint256' }, - { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnEndEpoch', internalType: 'uint256', type: 'uint256' }, - ], - }, + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'bytes', type: 'bytes' }, ], - stateMutability: 'view', + name: 'dataSetDeleted', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'getDataSet', + inputs: [], + name: 'eip712Domain', outputs: [ - { - name: 'info', - internalType: 'struct FilecoinWarmStorageService.DataSetInfo', - type: 'tuple', - components: [ - { name: 'pdpRailId', internalType: 'uint256', type: 'uint256' }, - { name: 'cacheMissRailId', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnRailId', internalType: 'uint256', type: 'uint256' }, - { name: 'payer', internalType: 'address', type: 'address' }, - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'commissionBps', internalType: 'uint256', type: 'uint256' }, - { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnEndEpoch', internalType: 'uint256', type: 'uint256' }, - ], - }, + { name: 'fields', internalType: 'bytes1', type: 'bytes1' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'version', internalType: 'string', type: 'string' }, + { name: 'chainId', internalType: 'uint256', type: 'uint256' }, + { name: 'verifyingContract', internalType: 'address', type: 'address' }, + { name: 'salt', internalType: 'bytes32', type: 'bytes32' }, + { name: 'extensions', internalType: 'uint256[]', type: 'uint256[]' }, ], stateMutability: 'view', }, { type: 'function', - inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'key', internalType: 'string', type: 'string' }, - ], - name: 'getDataSetMetadata', - outputs: [ - { name: 'exists', internalType: 'bool', type: 'bool' }, - { name: 'value', internalType: 'string', type: 'string' }, - ], + inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], + name: 'extsload', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'leafCount', internalType: 'uint256', type: 'uint256' }], - name: 'getDataSetSizeInBytes', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'pure', + inputs: [ + { name: 'slot', internalType: 'bytes32', type: 'bytes32' }, + { name: 'size', internalType: 'uint256', type: 'uint256' }, + ], + name: 'extsloadStruct', + outputs: [{ name: '', internalType: 'bytes32[]', type: 'bytes32[]' }], + stateMutability: 'view', }, { type: 'function', inputs: [], - name: 'getMaxProvingPeriod', - outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + name: 'filBeamBeneficiaryAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, { type: 'function', inputs: [], - name: 'getPDPConfig', + name: 'getEffectiveRates', outputs: [ - { name: 'maxProvingPeriod', internalType: 'uint64', type: 'uint64' }, - { name: 'challengeWindowSize', internalType: 'uint256', type: 'uint256' }, - { name: 'challengesPerProof', internalType: 'uint256', type: 'uint256' }, - { - name: 'initChallengeWindowStart', - internalType: 'uint256', - type: 'uint256', - }, + { name: 'serviceFee', internalType: 'uint256', type: 'uint256' }, + { name: 'spPayment', internalType: 'uint256', type: 'uint256' }, ], stateMutability: 'view', }, @@ -1485,1974 +1792,2287 @@ export const filecoinWarmStorageServiceStateViewAbi = [ type: 'function', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - { name: 'key', internalType: 'string', type: 'string' }, - ], - name: 'getPieceMetadata', - outputs: [ - { name: 'exists', internalType: 'bool', type: 'bool' }, - { name: 'value', internalType: 'string', type: 'string' }, + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, ], + name: 'getProvingPeriodForEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], - name: 'isProviderApproved', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + inputs: [], + name: 'getServicePrice', + outputs: [ + { + name: 'pricing', + internalType: 'struct FilecoinWarmStorageService.ServicePricing', + type: 'tuple', + components: [ + { + name: 'pricePerTiBPerMonthNoCDN', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'pricePerTiBPerMonthWithCDN', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'tokenAddress', + internalType: 'contract IERC20', + type: 'address', + }, + { name: 'epochsPerMonth', internalType: 'uint256', type: 'uint256' }, + ], + }, + ], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'nextPDPChallengeWindowStart', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: '_maxProvingPeriod', internalType: 'uint64', type: 'uint64' }, + { + name: '_challengeWindowSize', + internalType: 'uint256', + type: 'uint256', + }, + { + name: '_filBeamControllerAddress', + internalType: 'address', + type: 'address', + }, + { name: '_name', internalType: 'string', type: 'string' }, + { name: '_description', internalType: 'string', type: 'string' }, + ], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'periodId', internalType: 'uint256', type: 'uint256' }, + { name: 'epoch', internalType: 'uint256', type: 'uint256' }, ], - name: 'provenPeriods', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'provenThisPeriod', + name: 'isEpochProven', outputs: [{ name: '', internalType: 'bool', type: 'bool' }], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'provingActivationEpoch', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'provingDeadline', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'railToDataSet', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: '_viewContract', internalType: 'address', type: 'address' }, + ], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [], - name: 'service', - outputs: [ - { - name: '', - internalType: 'contract FilecoinWarmStorageService', - type: 'address', - }, + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'challengeEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'leafCount', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'bytes', type: 'bytes' }, ], - stateMutability: 'view', - }, - { - type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'ProvingPeriodNotInitialized', + name: 'nextProvingPeriod', + outputs: [], + stateMutability: 'nonpayable', }, -] as const - -/** - * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x87EDE87cEF4BfeFE0374c3470cB3F5be18b739d5) - */ -export const filecoinWarmStorageServiceStateViewAddress = { - 314: '0x0000000000000000000000000000000000000000', - 314159: '0x87EDE87cEF4BfeFE0374c3470cB3F5be18b739d5', -} as const - -/** - * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x87EDE87cEF4BfeFE0374c3470cB3F5be18b739d5) - */ -export const filecoinWarmStorageServiceStateViewConfig = { - address: filecoinWarmStorageServiceStateViewAddress, - abi: filecoinWarmStorageServiceStateViewAbi, -} as const - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// PDPVerifier -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137) - */ -export const pdpVerifierAbi = [ - { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, { type: 'function', inputs: [], - name: 'BURN_ACTOR', + name: 'owner', outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, { type: 'function', inputs: [], - name: 'EXTRA_DATA_MAX_SIZE', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + name: 'paymentsContractAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, { type: 'function', inputs: [], - name: 'FIL_USD_PRICE_FEED_ID', - outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + name: 'pdpVerifierAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, { type: 'function', - inputs: [], - name: 'LEAF_SIZE', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'MAX_ENQUEUED_REMOVALS', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'firstAdded', internalType: 'uint256', type: 'uint256' }, + { + name: 'pieceData', + internalType: 'struct Cids.Cid[]', + type: 'tuple[]', + components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'piecesAdded', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [], - name: 'MAX_PIECE_SIZE_LOG2', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + ], + name: 'piecesScheduledRemove', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [], - name: 'NO_CHALLENGE_SCHEDULED', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: 'challengeCount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'possessionProven', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', inputs: [], - name: 'NO_PROVEN_EPOCH', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + name: 'proxiableUUID', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], stateMutability: 'view', }, { type: 'function', - inputs: [], - name: 'PYTH', - outputs: [{ name: '', internalType: 'contract IPyth', type: 'address' }], - stateMutability: 'view', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'terminator', internalType: 'address', type: 'address' }, + { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, + ], + name: 'railTerminated', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [], - name: 'RANDOMNESS_PRECOMPILE', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', + inputs: [ + { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { name: 'index', internalType: 'uint256', type: 'uint256' }, + ], + name: 'removeApprovedProvider', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', inputs: [], - name: 'SECONDS_IN_DAY', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [{ name: '', internalType: 'string', type: 'string' }], + name: 'serviceProviderRegistry', + outputs: [ + { + name: '', + internalType: 'contract ServiceProviderRegistry', + type: 'address', + }, + ], stateMutability: 'view', }, { type: 'function', inputs: [], - name: 'VERSION', - outputs: [{ name: '', internalType: 'string', type: 'string' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, + name: 'sessionKeyRegistry', + outputs: [ { - name: 'pieceData', - internalType: 'struct Cids.Cid[]', - type: 'tuple[]', - components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + name: '', + internalType: 'contract SessionKeyRegistry', + type: 'address', }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'addPieces', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'nonpayable', + stateMutability: 'view', }, { type: 'function', inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'estimatedGasFee', internalType: 'uint256', type: 'uint256' }, + { name: '_viewContract', internalType: 'address', type: 'address' }, ], - name: 'calculateProofFee', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'setViewContract', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'cdnAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'cacheMissAmount', internalType: 'uint256', type: 'uint256' }, ], - name: 'claimDataSetStorageProvider', + name: 'settleFilBeamPaymentRails', outputs: [], stateMutability: 'nonpayable', }, { type: 'function', inputs: [ - { name: 'listenerAddr', internalType: 'address', type: 'address' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'bytes', type: 'bytes' }, ], - name: 'createDataSet', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'payable', + name: 'storageProviderChanged', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'dataSetLive', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'terminateCDNService', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, - ], - name: 'deleteDataSet', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'terminateService', outputs: [], stateMutability: 'nonpayable', }, { type: 'function', inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'leafIndexs', internalType: 'uint256[]', type: 'uint256[]' }, - ], - name: 'findPieceIds', - outputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'cdnAmountToAdd', internalType: 'uint256', type: 'uint256' }, { - name: '', - internalType: 'struct IPDPTypes.PieceIdAndOffset[]', - type: 'tuple[]', - components: [ - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - { name: 'offset', internalType: 'uint256', type: 'uint256' }, - ], + name: 'cacheMissAmountToAdd', + internalType: 'uint256', + type: 'uint256', }, ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getActivePieceCount', - outputs: [{ name: 'activeCount', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'topUpCDNPaymentRails', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'offset', internalType: 'uint256', type: 'uint256' }, - { name: 'limit', internalType: 'uint256', type: 'uint256' }, - ], - name: 'getActivePieces', - outputs: [ - { - name: 'pieces', - internalType: 'struct Cids.Cid[]', - type: 'tuple[]', - components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], - }, - { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, - { name: 'rawSizes', internalType: 'uint256[]', type: 'uint256[]' }, - { name: 'hasMore', internalType: 'bool', type: 'bool' }, + { name: 'newController', internalType: 'address', type: 'address' }, ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'getChallengeFinality', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + name: 'transferFilBeamController', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getChallengeRange', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getDataSetLastProvenEpoch', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: 'newCommissionBps', internalType: 'uint256', type: 'uint256' }, + ], + name: 'updateServiceCommission', + outputs: [], + stateMutability: 'nonpayable', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getDataSetLeafCount', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + inputs: [ + { name: 'newImplementation', internalType: 'address', type: 'address' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getDataSetListener', - outputs: [{ name: '', internalType: 'address', type: 'address' }], + inputs: [], + name: 'usdfcTokenAddress', + outputs: [ + { name: '', internalType: 'contract IERC20Metadata', type: 'address' }, + ], stateMutability: 'view', }, { type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getDataSetStorageProvider', + inputs: [ + { name: 'railId', internalType: 'uint256', type: 'uint256' }, + { name: 'proposedAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'fromEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'toEpoch', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'uint256', type: 'uint256' }, + ], + name: 'validatePayment', outputs: [ - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, + { + name: 'result', + internalType: 'struct IValidator.ValidationResult', + type: 'tuple', + components: [ + { name: 'modifiedAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'settleUpto', internalType: 'uint256', type: 'uint256' }, + { name: 'note', internalType: 'string', type: 'string' }, + ], + }, ], stateMutability: 'view', }, { type: 'function', inputs: [], - name: 'getFILUSDPrice', - outputs: [ - { name: '', internalType: 'uint64', type: 'uint64' }, - { name: '', internalType: 'int32', type: 'int32' }, - ], + name: 'viewContractAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, - { - type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getNextChallengeEpoch', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'getNextDataSetId', - outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getNextPieceId', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - ], - name: 'getPieceCid', - outputs: [ - { - name: '', - internalType: 'struct Cids.Cid', - type: 'tuple', - components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], - }, - ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - ], - name: 'getPieceLeafCount', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'epoch', internalType: 'uint256', type: 'uint256' }], - name: 'getRandomness', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], - name: 'getScheduledRemovals', - outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: '_challengeFinality', internalType: 'uint256', type: 'uint256' }], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [], - name: 'migrate', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'challengeEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, - ], - name: 'nextProvingPeriod', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [], - name: 'owner', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - ], - name: 'pieceChallengable', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - ], - name: 'pieceLive', - outputs: [{ name: '', internalType: 'bool', type: 'bool' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'newStorageProvider', internalType: 'address', type: 'address' }, - ], - name: 'proposeDataSetStorageProvider', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { - name: 'proofs', - internalType: 'struct IPDPTypes.Proof[]', - type: 'tuple[]', - components: [ - { name: 'leaf', internalType: 'bytes32', type: 'bytes32' }, - { name: 'proof', internalType: 'bytes32[]', type: 'bytes32[]' }, - ], - }, - ], - name: 'provePossession', - outputs: [], - stateMutability: 'payable', - }, - { - type: 'function', - inputs: [], - name: 'proxiableUUID', - outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'renounceOwnership', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, - ], - name: 'schedulePieceDeletions', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], - name: 'transferOwnership', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [ - { name: 'newImplementation', internalType: 'address', type: 'address' }, - { name: 'data', internalType: 'bytes', type: 'bytes' }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - }, { type: 'event', anonymous: false, inputs: [ { - name: 'version', - internalType: 'string', - type: 'string', + name: 'dataSetId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'cdnAmountAdded', + internalType: 'uint256', + type: 'uint256', indexed: false, }, { - name: 'implementation', - internalType: 'address', - type: 'address', + name: 'totalCdnLockup', + internalType: 'uint256', + type: 'uint256', indexed: false, }, - ], - name: 'ContractUpgraded', - }, - { - type: 'event', - anonymous: false, - inputs: [ { - name: 'setId', + name: 'cacheMissAmountAdded', internalType: 'uint256', type: 'uint256', - indexed: true, + indexed: false, }, { - name: 'storageProvider', - internalType: 'address', - type: 'address', - indexed: true, + name: 'totalCacheMissLockup', + internalType: 'uint256', + type: 'uint256', + indexed: false, }, ], - name: 'DataSetCreated', + name: 'CDNPaymentRailsToppedUp', }, { type: 'event', anonymous: false, inputs: [ { - name: 'setId', + name: 'dataSetId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'deletedLeafCount', + name: 'endEpoch', internalType: 'uint256', type: 'uint256', indexed: false, }, - ], - name: 'DataSetDeleted', - }, - { - type: 'event', - anonymous: false, - inputs: [ { - name: 'setId', + name: 'cacheMissRailId', internalType: 'uint256', type: 'uint256', - indexed: true, + indexed: false, }, - ], - name: 'DataSetEmpty', - }, - { - type: 'event', - anonymous: false, - inputs: [ { - name: 'version', - internalType: 'uint64', - type: 'uint64', + name: 'cdnRailId', + internalType: 'uint256', + type: 'uint256', indexed: false, }, ], - name: 'Initialized', + name: 'CDNPaymentTerminated', }, { type: 'event', anonymous: false, inputs: [ { - name: 'setId', + name: 'caller', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'dataSetId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'challengeEpoch', + name: 'cacheMissRailId', internalType: 'uint256', type: 'uint256', indexed: false, }, { - name: 'leafCount', + name: 'cdnRailId', internalType: 'uint256', type: 'uint256', indexed: false, }, ], - name: 'NextProvingPeriod', + name: 'CDNServiceTerminated', }, { type: 'event', anonymous: false, inputs: [ { - name: 'previousOwner', - internalType: 'address', - type: 'address', - indexed: true, + name: 'version', + internalType: 'string', + type: 'string', + indexed: false, }, { - name: 'newOwner', + name: 'implementation', internalType: 'address', type: 'address', - indexed: true, + indexed: false, }, ], - name: 'OwnershipTransferred', + name: 'ContractUpgraded', }, { type: 'event', anonymous: false, inputs: [ { - name: 'setId', + name: 'dataSetId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'pieceIds', - internalType: 'uint256[]', - type: 'uint256[]', + name: 'providerId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'pdpRailId', + internalType: 'uint256', + type: 'uint256', indexed: false, }, { - name: 'pieceCids', - internalType: 'struct Cids.Cid[]', - type: 'tuple[]', - components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + name: 'cacheMissRailId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'cdnRailId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'payer', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'payee', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'metadataKeys', + internalType: 'string[]', + type: 'string[]', + indexed: false, + }, + { + name: 'metadataValues', + internalType: 'string[]', + type: 'string[]', indexed: false, }, ], - name: 'PiecesAdded', + name: 'DataSetCreated', }, { type: 'event', anonymous: false, inputs: [ { - name: 'setId', + name: 'dataSetId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'pieceIds', - internalType: 'uint256[]', - type: 'uint256[]', - indexed: false, + name: 'oldServiceProvider', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newServiceProvider', + internalType: 'address', + type: 'address', + indexed: true, }, ], - name: 'PiecesRemoved', + name: 'DataSetServiceProviderChanged', }, + { type: 'event', anonymous: false, inputs: [], name: 'EIP712DomainChanged' }, { type: 'event', anonymous: false, inputs: [ { - name: 'setId', + name: 'dataSetId', internalType: 'uint256', type: 'uint256', indexed: true, }, { - name: 'challenges', - internalType: 'struct IPDPTypes.PieceIdAndOffset[]', - type: 'tuple[]', - components: [ - { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, - { name: 'offset', internalType: 'uint256', type: 'uint256' }, - ], + name: 'periodsFaulted', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'deadline', + internalType: 'uint256', + type: 'uint256', indexed: false, }, ], - name: 'PossessionProven', + name: 'FaultRecord', }, { type: 'event', anonymous: false, inputs: [ { - name: 'setId', - internalType: 'uint256', - type: 'uint256', - indexed: true, + name: 'oldController', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'newController', + internalType: 'address', + type: 'address', + indexed: false, }, - { name: 'fee', internalType: 'uint256', type: 'uint256', indexed: false }, - { name: 'price', internalType: 'uint64', type: 'uint64', indexed: false }, - { name: 'expo', internalType: 'int32', type: 'int32', indexed: false }, ], - name: 'ProofFeePaid', + name: 'FilBeamControllerChanged', }, { type: 'event', anonymous: false, inputs: [ + { name: 'name', internalType: 'string', type: 'string', indexed: false }, { - name: 'setId', - internalType: 'uint256', - type: 'uint256', - indexed: true, + name: 'description', + internalType: 'string', + type: 'string', + indexed: false, + }, + ], + name: 'FilecoinServiceDeployed', + }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'version', + internalType: 'uint64', + type: 'uint64', + indexed: false, }, + ], + name: 'Initialized', + }, + { + type: 'event', + anonymous: false, + inputs: [ { - name: 'oldStorageProvider', + name: 'previousOwner', internalType: 'address', type: 'address', indexed: true, }, { - name: 'newStorageProvider', + name: 'newOwner', internalType: 'address', type: 'address', indexed: true, }, ], - name: 'StorageProviderChanged', + name: 'OwnershipTransferred', }, { type: 'event', anonymous: false, inputs: [ { - name: 'implementation', - internalType: 'address', - type: 'address', + name: 'dataSetId', + internalType: 'uint256', + type: 'uint256', indexed: true, }, + { + name: 'endEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'pdpRailId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'Upgraded', + name: 'PDPPaymentTerminated', }, { - type: 'error', - inputs: [{ name: 'target', internalType: 'address', type: 'address' }], - name: 'AddressEmptyCode', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'dataSetId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'pieceId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'pieceCid', + internalType: 'struct Cids.Cid', + type: 'tuple', + components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + indexed: false, + }, + { + name: 'keys', + internalType: 'string[]', + type: 'string[]', + indexed: false, + }, + { + name: 'values', + internalType: 'string[]', + type: 'string[]', + indexed: false, + }, + ], + name: 'PieceAdded', }, { - type: 'error', - inputs: [{ name: 'implementation', internalType: 'address', type: 'address' }], - name: 'ERC1967InvalidImplementation', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'providerId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + ], + name: 'ProviderApproved', }, - { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, - { type: 'error', inputs: [], name: 'FailedCall' }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'idx', internalType: 'uint256', type: 'uint256' }, - { name: 'msg', internalType: 'string', type: 'string' }, + { + name: 'providerId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, ], - name: 'IndexedError', + name: 'ProviderUnapproved', }, - { type: 'error', inputs: [], name: 'InvalidInitialization' }, - { type: 'error', inputs: [], name: 'NotInitializing' }, { - type: 'error', - inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], - name: 'OwnableInvalidOwner', - }, - { - type: 'error', - inputs: [{ name: 'account', internalType: 'address', type: 'address' }], - name: 'OwnableUnauthorizedAccount', - }, - { type: 'error', inputs: [], name: 'UUPSUnauthorizedCallContext' }, - { - type: 'error', - inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], - name: 'UUPSUnsupportedProxiableUUID', - }, -] as const - -/** - * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137) - */ -export const pdpVerifierAddress = { - 314: '0x0000000000000000000000000000000000000000', - 314159: '0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137', -} as const - -/** - * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137) - */ -export const pdpVerifierConfig = { - address: pdpVerifierAddress, - abi: pdpVerifierAbi, -} as const - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Payments -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x1096025c9D6B29E12E2f04965F6E64d564Ce0750) - */ -export const paymentsAbi = [ - { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, - { - type: 'function', - inputs: [], - name: 'COMMISSION_MAX_BPS', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'NETWORK_FEE', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, - ], - name: 'accounts', - outputs: [ - { name: 'funds', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupCurrent', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupRate', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupLastSettledAt', internalType: 'uint256', type: 'uint256' }, - ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'validator', internalType: 'address', type: 'address' }, - { name: 'commissionRateBps', internalType: 'uint256', type: 'uint256' }, - { name: 'serviceFeeRecipient', internalType: 'address', type: 'address' }, - ], - name: 'createRail', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'nonpayable', - }, - { - type: 'function', - inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, - ], - name: 'deposit', - outputs: [], - stateMutability: 'payable', - }, - { - type: 'function', - inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, - { name: 'deadline', internalType: 'uint256', type: 'uint256' }, - { name: 'v', internalType: 'uint8', type: 'uint8' }, - { name: 'r', internalType: 'bytes32', type: 'bytes32' }, - { name: 's', internalType: 'bytes32', type: 'bytes32' }, - ], - name: 'depositWithPermit', - outputs: [], - stateMutability: 'nonpayable', - }, - { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, - { name: 'deadline', internalType: 'uint256', type: 'uint256' }, - { name: 'v', internalType: 'uint8', type: 'uint8' }, - { name: 'r', internalType: 'bytes32', type: 'bytes32' }, - { name: 's', internalType: 'bytes32', type: 'bytes32' }, - { name: 'operator', internalType: 'address', type: 'address' }, - { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, - { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + { + name: 'dataSetId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'railId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newRate', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'depositWithPermitAndApproveOperator', - outputs: [], - stateMutability: 'nonpayable', + name: 'RailRateUpdated', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, - { name: 'deadline', internalType: 'uint256', type: 'uint256' }, - { name: 'v', internalType: 'uint8', type: 'uint8' }, - { name: 'r', internalType: 'bytes32', type: 'bytes32' }, - { name: 's', internalType: 'bytes32', type: 'bytes32' }, - { name: 'operator', internalType: 'address', type: 'address' }, { - name: 'rateAllowanceIncrease', + name: 'caller', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'dataSetId', internalType: 'uint256', type: 'uint256', + indexed: true, }, { - name: 'lockupAllowanceIncrease', + name: 'pdpRailId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'cacheMissRailId', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'cdnRailId', internalType: 'uint256', type: 'uint256', + indexed: false, }, ], - name: 'depositWithPermitAndIncreaseOperatorApproval', - outputs: [], - stateMutability: 'nonpayable', + name: 'ServiceTerminated', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'owner', internalType: 'address', type: 'address' }, - ], - name: 'getAccountInfoIfSettled', - outputs: [ - { name: 'fundedUntilEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'currentFunds', internalType: 'uint256', type: 'uint256' }, - { name: 'availableFunds', internalType: 'uint256', type: 'uint256' }, - { name: 'currentLockupRate', internalType: 'uint256', type: 'uint256' }, - ], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'getRail', - outputs: [ { - name: '', - internalType: 'struct Payments.RailView', + name: 'plannedUpgrade', + internalType: 'struct FilecoinWarmStorageService.PlannedUpgrade', type: 'tuple', components: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'operator', internalType: 'address', type: 'address' }, - { name: 'validator', internalType: 'address', type: 'address' }, - { name: 'paymentRate', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupPeriod', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupFixed', internalType: 'uint256', type: 'uint256' }, - { name: 'settledUpTo', internalType: 'uint256', type: 'uint256' }, - { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, - { - name: 'commissionRateBps', - internalType: 'uint256', - type: 'uint256', - }, { - name: 'serviceFeeRecipient', + name: 'nextImplementation', internalType: 'address', type: 'address', }, + { name: 'afterEpoch', internalType: 'uint96', type: 'uint96' }, ], + indexed: false, }, ], - stateMutability: 'view', + name: 'UpgradeAnnounced', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'token', internalType: 'address', type: 'address' }, - ], - name: 'getRailsForPayeeAndToken', - outputs: [ { - name: '', - internalType: 'struct Payments.RailInfo[]', - type: 'tuple[]', - components: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'isTerminated', internalType: 'bool', type: 'bool' }, - { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, - ], + name: 'implementation', + internalType: 'address', + type: 'address', + indexed: true, }, ], - stateMutability: 'view', + name: 'Upgraded', }, { - type: 'function', + type: 'event', + anonymous: false, inputs: [ - { name: 'payer', internalType: 'address', type: 'address' }, - { name: 'token', internalType: 'address', type: 'address' }, - ], - name: 'getRailsForPayerAndToken', - outputs: [ { - name: '', - internalType: 'struct Payments.RailInfo[]', - type: 'tuple[]', - components: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'isTerminated', internalType: 'bool', type: 'bool' }, - { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, - ], + name: 'viewContract', + internalType: 'address', + type: 'address', + indexed: true, }, ], - stateMutability: 'view', + name: 'ViewContractSet', }, { - type: 'function', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'getRateChangeQueueSize', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', + type: 'error', + inputs: [{ name: 'target', internalType: 'address', type: 'address' }], + name: 'AddressEmptyCode', }, { - type: 'function', + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'CDNPaymentAlreadyTerminated', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'CacheMissPaymentAlreadyTerminated', + }, + { + type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'operator', internalType: 'address', type: 'address' }, - { - name: 'rateAllowanceIncrease', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'lockupAllowanceIncrease', - internalType: 'uint256', - type: 'uint256', - }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'expectedPayer', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, ], - name: 'increaseOperatorApproval', - outputs: [], - stateMutability: 'nonpayable', + name: 'CallerNotPayer', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'period', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupFixed', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'expectedPayer', internalType: 'address', type: 'address' }, + { name: 'expectedPayee', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, ], - name: 'modifyRailLockup', - outputs: [], - stateMutability: 'nonpayable', + name: 'CallerNotPayerOrPayee', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'newRate', internalType: 'uint256', type: 'uint256' }, - { name: 'oneTimePayment', internalType: 'uint256', type: 'uint256' }, + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, ], - name: 'modifyRailPayment', - outputs: [], - stateMutability: 'nonpayable', + name: 'CallerNotPayments', }, { - type: 'function', + type: 'error', inputs: [ - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, - ], - name: 'operatorApprovals', - outputs: [ - { name: 'isApproved', internalType: 'bool', type: 'bool' }, - { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, - { name: 'rateUsage', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupUsage', internalType: 'uint256', type: 'uint256' }, - { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'windowStart', internalType: 'uint256', type: 'uint256' }, + { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, ], - stateMutability: 'view', + name: 'ChallengeWindowTooEarly', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'operator', internalType: 'address', type: 'address' }, - { name: 'approved', internalType: 'bool', type: 'bool' }, - { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, - { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, ], - name: 'setOperatorApproval', - outputs: [], - stateMutability: 'nonpayable', + name: 'ClientDataSetAlreadyRegistered', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'untilEpoch', internalType: 'uint256', type: 'uint256' }, - ], - name: 'settleRail', - outputs: [ - { name: 'totalSettledAmount', internalType: 'uint256', type: 'uint256' }, - { name: 'totalNetPayeeAmount', internalType: 'uint256', type: 'uint256' }, { - name: 'totalOperatorCommission', - internalType: 'uint256', - type: 'uint256', + name: 'commissionType', + internalType: 'enum Errors.CommissionType', + type: 'uint8', }, - { name: 'finalSettledEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'note', internalType: 'string', type: 'string' }, + { name: 'max', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - stateMutability: 'payable', + name: 'CommissionExceedsMaximum', }, { - type: 'function', + type: 'error', inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'settleTerminatedRailWithoutValidation', - outputs: [ - { name: 'totalSettledAmount', internalType: 'uint256', type: 'uint256' }, - { name: 'totalNetPayeeAmount', internalType: 'uint256', type: 'uint256' }, - { - name: 'totalOperatorCommission', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'finalSettledEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'note', internalType: 'string', type: 'string' }, + name: 'DataSetNotFoundForRail', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'DataSetNotRegistered', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'DataSetPaymentAlreadyTerminated', + }, + { + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'currentBlock', internalType: 'uint256', type: 'uint256' }, ], - stateMutability: 'nonpayable', + name: 'DataSetPaymentBeyondEndEpoch', }, + { type: 'error', inputs: [], name: 'DivisionByZero' }, { - type: 'function', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'terminateRail', - outputs: [], - stateMutability: 'nonpayable', + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'string', type: 'string' }, + ], + name: 'DuplicateMetadataKey', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'implementation', internalType: 'address', type: 'address' }, ], - name: 'withdraw', - outputs: [], - stateMutability: 'nonpayable', + name: 'ERC1967InvalidImplementation', + }, + { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, + { type: 'error', inputs: [], name: 'ExtraDataRequired' }, + { type: 'error', inputs: [], name: 'FailedCall' }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'FilBeamServiceNotConfigured', }, { - type: 'function', + type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'minExpected', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'withdrawTo', - outputs: [], - stateMutability: 'nonpayable', + name: 'InvalidChallengeCount', }, { - type: 'event', - anonymous: false, + type: 'error', inputs: [ - { - name: 'token', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'owner', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'lockupCurrent', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'lockupRate', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'lockupLastSettledAt', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'minAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'actual', internalType: 'uint256', type: 'uint256' }, ], - name: 'AccountLockupSettled', + name: 'InvalidChallengeEpoch', }, { - type: 'event', - anonymous: false, + type: 'error', inputs: [ - { - name: 'token', - internalType: 'address', - type: 'address', - indexed: true, - }, - { name: 'from', internalType: 'address', type: 'address', indexed: true }, - { name: 'to', internalType: 'address', type: 'address', indexed: true }, - { - name: 'amount', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'usedPermit', - internalType: 'bool', - type: 'bool', - indexed: false, - }, + { name: 'maxProvingPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'challengeWindowSize', internalType: 'uint256', type: 'uint256' }, ], - name: 'DepositRecorded', + name: 'InvalidChallengeWindowSize', }, { - type: 'event', - anonymous: false, + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidDataSetId', + }, + { + type: 'error', inputs: [ - { - name: 'token', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'client', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'operator', - internalType: 'address', - type: 'address', - indexed: true, - }, - { name: 'approved', internalType: 'bool', type: 'bool', indexed: false }, - { - name: 'rateAllowance', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'lockupAllowance', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'maxLockupPeriod', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, + { name: 'fromEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'toEpoch', internalType: 'uint256', type: 'uint256' }, ], - name: 'OperatorApprovalUpdated', + name: 'InvalidEpochRange', }, + { type: 'error', inputs: [], name: 'InvalidInitialization' }, { - type: 'event', - anonymous: false, + type: 'error', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidServiceDescriptionLength', + }, + { + type: 'error', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidServiceNameLength', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidTopUpAmount', + }, + { type: 'error', inputs: [], name: 'MaxProvingPeriodZero' }, + { + type: 'error', + inputs: [ + { name: 'metadataArrayCount', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceCount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'MetadataArrayCountMismatch', + }, + { + type: 'error', + inputs: [ + { name: 'keysLength', internalType: 'uint256', type: 'uint256' }, + { name: 'valuesLength', internalType: 'uint256', type: 'uint256' }, + ], + name: 'MetadataKeyAndValueLengthMismatch', + }, + { + type: 'error', + inputs: [ + { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'length', internalType: 'uint256', type: 'uint256' }, + ], + name: 'MetadataKeyExceedsMaxLength', + }, + { + type: 'error', + inputs: [ + { name: 'index', internalType: 'uint256', type: 'uint256' }, + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'length', internalType: 'uint256', type: 'uint256' }, + ], + name: 'MetadataValueExceedsMaxLength', + }, + { + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'periodDeadline', internalType: 'uint256', type: 'uint256' }, + { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, + ], + name: 'NextProvingPeriodAlreadyCalled', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'NoPDPPaymentRail', + }, + { type: 'error', inputs: [], name: 'NotInitializing' }, + { + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, + ], + name: 'OnlyFilBeamControllerAllowed', + }, + { + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, + ], + name: 'OnlyPDPVerifierAllowed', + }, + { + type: 'error', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'OwnableInvalidOwner', + }, + { + type: 'error', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'OwnableUnauthorizedAccount', + }, + { + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, + ], + name: 'PaymentRailsNotFinalized', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'ProofAlreadySubmitted', + }, + { + type: 'error', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'ProviderAlreadyApproved', + }, + { + type: 'error', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'ProviderNotInApprovedList', + }, + { + type: 'error', + inputs: [{ name: 'provider', internalType: 'address', type: 'address' }], + name: 'ProviderNotRegistered', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'ProvingNotStarted', + }, + { + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'deadline', internalType: 'uint256', type: 'uint256' }, + { name: 'nowBlock', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ProvingPeriodPassed', + }, + { + type: 'error', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'RailNotAssociated', + }, + { type: 'error', inputs: [], name: 'ServiceContractMustTerminateRail' }, + { + type: 'error', + inputs: [ + { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, + { name: 'keysLength', internalType: 'uint256', type: 'uint256' }, + ], + name: 'TooManyMetadataKeys', + }, + { type: 'error', inputs: [], name: 'UUPSUnauthorizedCallContext' }, + { + type: 'error', + inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], + name: 'UUPSUnsupportedProxiableUUID', + }, + { + type: 'error', inputs: [ { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'payer', - internalType: 'address', - type: 'address', - indexed: true, - }, - { - name: 'payee', - internalType: 'address', - type: 'address', - indexed: true, + name: 'field', + internalType: 'enum Errors.AddressField', + type: 'uint8', }, + ], + name: 'ZeroAddress', + }, +] as const + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xD3De778C05f89e1240ef70100Fb0d9e5b2eFD258) + */ +export const filecoinWarmStorageServiceAddress = { + 314: '0x0000000000000000000000000000000000000000', + 314159: '0xD3De778C05f89e1240ef70100Fb0d9e5b2eFD258', +} as const + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xD3De778C05f89e1240ef70100Fb0d9e5b2eFD258) + */ +export const filecoinWarmStorageServiceConfig = { + address: filecoinWarmStorageServiceAddress, + abi: filecoinWarmStorageServiceAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// FilecoinWarmStorageServiceStateView +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x0295Ac959317391656fB7fFaA046046eF9C7E18F) + */ +export const filecoinWarmStorageServiceStateViewAbi = [ + { + type: 'constructor', + inputs: [ { - name: 'token', - internalType: 'address', + name: '_service', + internalType: 'contract FilecoinWarmStorageService', type: 'address', - indexed: false, }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [], + name: 'challengeWindow', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'payer', internalType: 'address', type: 'address' }, + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'clientDataSetIds', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'payer', internalType: 'address', type: 'address' }], + name: 'clientDataSets', + outputs: [ + { name: 'dataSetIds', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'filBeamControllerAddress', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'getAllDataSetMetadata', + outputs: [ + { name: 'keys', internalType: 'string[]', type: 'string[]' }, + { name: 'values', internalType: 'string[]', type: 'string[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getAllPieceMetadata', + outputs: [ + { name: 'keys', internalType: 'string[]', type: 'string[]' }, + { name: 'values', internalType: 'string[]', type: 'string[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getApprovedProviders', + outputs: [ + { name: 'providerIds', internalType: 'uint256[]', type: 'uint256[]' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getApprovedProvidersLength', + outputs: [{ name: 'count', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getChallengesPerProof', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'client', internalType: 'address', type: 'address' }], + name: 'getClientDataSets', + outputs: [ { - name: 'operator', - internalType: 'address', - type: 'address', - indexed: false, + name: 'infos', + internalType: 'struct FilecoinWarmStorageService.DataSetInfoView[]', + type: 'tuple[]', + components: [ + { name: 'pdpRailId', internalType: 'uint256', type: 'uint256' }, + { name: 'cacheMissRailId', internalType: 'uint256', type: 'uint256' }, + { name: 'cdnRailId', internalType: 'uint256', type: 'uint256' }, + { name: 'payer', internalType: 'address', type: 'address' }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'serviceProvider', internalType: 'address', type: 'address' }, + { name: 'commissionBps', internalType: 'uint256', type: 'uint256' }, + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + ], }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSet', + outputs: [ { - name: 'validator', - internalType: 'address', - type: 'address', - indexed: false, + name: 'info', + internalType: 'struct FilecoinWarmStorageService.DataSetInfoView', + type: 'tuple', + components: [ + { name: 'pdpRailId', internalType: 'uint256', type: 'uint256' }, + { name: 'cacheMissRailId', internalType: 'uint256', type: 'uint256' }, + { name: 'cdnRailId', internalType: 'uint256', type: 'uint256' }, + { name: 'payer', internalType: 'address', type: 'address' }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'serviceProvider', internalType: 'address', type: 'address' }, + { name: 'commissionBps', internalType: 'uint256', type: 'uint256' }, + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + ], }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'string', type: 'string' }, + ], + name: 'getDataSetMetadata', + outputs: [ + { name: 'exists', internalType: 'bool', type: 'bool' }, + { name: 'value', internalType: 'string', type: 'string' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'leafCount', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetSizeInBytes', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'pure', + }, + { + type: 'function', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetStatus', + outputs: [ { - name: 'serviceFeeRecipient', - internalType: 'address', - type: 'address', - indexed: false, + name: 'status', + internalType: 'enum FilecoinWarmStorageService.DataSetStatus', + type: 'uint8', }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getMaxProvingPeriod', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getPDPConfig', + outputs: [ + { name: 'maxProvingPeriod', internalType: 'uint64', type: 'uint64' }, + { name: 'challengeWindowSize', internalType: 'uint256', type: 'uint256' }, + { name: 'challengesPerProof', internalType: 'uint256', type: 'uint256' }, { - name: 'commissionRateBps', + name: 'initChallengeWindowStart', internalType: 'uint256', type: 'uint256', - indexed: false, }, ], - name: 'RailCreated', + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, + { name: 'key', internalType: 'string', type: 'string' }, ], - name: 'RailFinalized', + name: 'getPieceMetadata', + outputs: [ + { name: 'exists', internalType: 'bool', type: 'bool' }, + { name: 'value', internalType: 'string', type: 'string' }, + ], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'isProviderApproved', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'nextPDPChallengeWindowStart', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'nextUpgrade', + outputs: [ + { name: 'nextImplementation', internalType: 'address', type: 'address' }, + { name: 'afterEpoch', internalType: 'uint96', type: 'uint96' }, + ], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'periodId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'provenPeriods', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'provenThisPeriod', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'provingActivationEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'provingDeadline', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], + name: 'railToDataSet', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'service', + outputs: [ { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'oldLockupPeriod', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'newLockupPeriod', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'oldLockupFixed', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: '', + internalType: 'contract FilecoinWarmStorageService', + type: 'address', }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'serviceCommissionBps', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'ProvingPeriodNotInitialized', + }, +] as const + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x0295Ac959317391656fB7fFaA046046eF9C7E18F) + */ +export const filecoinWarmStorageServiceStateViewAddress = { + 314: '0x0000000000000000000000000000000000000000', + 314159: '0x0295Ac959317391656fB7fFaA046046eF9C7E18F', +} as const + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x0295Ac959317391656fB7fFaA046046eF9C7E18F) + */ +export const filecoinWarmStorageServiceStateViewConfig = { + address: filecoinWarmStorageServiceStateViewAddress, + abi: filecoinWarmStorageServiceStateViewAbi, +} as const + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// PDPVerifier +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x06279D540BDCd6CA33B073cEAeA1425B6C68c93d) + */ +export const pdpVerifierAbi = [ + { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, + { + type: 'function', + inputs: [], + name: 'MAX_ENQUEUED_REMOVALS', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'MAX_PIECE_SIZE_LOG2', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'NO_CHALLENGE_SCHEDULED', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'NO_PROVEN_EPOCH', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'UPGRADE_INTERFACE_VERSION', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'VERSION', + outputs: [{ name: '', internalType: 'string', type: 'string' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'listenerAddr', internalType: 'address', type: 'address' }, { - name: 'newLockupFixed', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'pieceData', + internalType: 'struct Cids.Cid[]', + type: 'tuple[]', + components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'RailLockupModified', + name: 'addPieces', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'calculateProofFee', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [{ name: 'proofSize', internalType: 'uint256', type: 'uint256' }], + name: 'calculateProofFeeForSize', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ - { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'netPayeeAmount', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'operatorCommission', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'RailOneTimePaymentProcessed', + name: 'claimDataSetStorageProvider', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', inputs: [ - { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'oldRate', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'newRate', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, + { name: 'listenerAddr', internalType: 'address', type: 'address' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'RailRateModified', + name: 'createDataSet', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'payable', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'dataSetLive', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ - { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { - name: 'totalSettledAmount', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'totalNetPayeeAmount', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'operatorCommission', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'settledUpTo', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'RailSettled', + name: 'deleteDataSet', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [], + name: 'feeEffectiveTime', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'feePerTiB', + outputs: [{ name: '', internalType: 'uint96', type: 'uint96' }], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'leafIndexs', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'findPieceIds', + outputs: [ { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: true, - }, - { name: 'by', internalType: 'address', type: 'address', indexed: true }, - { - name: 'endEpoch', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: '', + internalType: 'struct IPDPTypes.PieceIdAndOffset[]', + type: 'tuple[]', + components: [ + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + ], }, ], - name: 'RailTerminated', + stateMutability: 'view', }, { - type: 'event', - anonymous: false, + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getActivePieceCount', + outputs: [ + { name: 'activeCount', internalType: 'uint256', type: 'uint256' }, + ], + stateMutability: 'view', + }, + { + type: 'function', inputs: [ + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + ], + name: 'getActivePieces', + outputs: [ { - name: 'token', - internalType: 'address', - type: 'address', - indexed: true, - }, - { name: 'from', internalType: 'address', type: 'address', indexed: true }, - { name: 'to', internalType: 'address', type: 'address', indexed: true }, - { - name: 'amount', - internalType: 'uint256', - type: 'uint256', - indexed: false, + name: 'pieces', + internalType: 'struct Cids.Cid[]', + type: 'tuple[]', + components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], }, + { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'hasMore', internalType: 'bool', type: 'bool' }, ], - name: 'WithdrawRecorded', + stateMutability: 'view', }, { - type: 'error', - inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'maxSettlementEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'blockNumber', internalType: 'uint256', type: 'uint256' }, - ], - name: 'CannotModifyTerminatedRailBeyondEndEpoch', + type: 'function', + inputs: [], + name: 'getChallengeFinality', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', }, { - type: 'error', - inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'maxAllowedEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedEpoch', internalType: 'uint256', type: 'uint256' }, + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getChallengeRange', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetLastProvenEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetLeafCount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetListener', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetStorageProvider', + outputs: [ + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'address', type: 'address' }, ], - name: 'CannotSettleFutureEpochs', + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getNextChallengeEpoch', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'getNextDataSetId', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getNextPieceId', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'requiredBlock', internalType: 'uint256', type: 'uint256' }, - { name: 'currentBlock', internalType: 'uint256', type: 'uint256' }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, ], - name: 'CannotSettleTerminatedRailBeforeMaxEpoch', + name: 'getPieceCid', + outputs: [ + { + name: '', + internalType: 'struct Cids.Cid', + type: 'tuple', + components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + }, + ], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'actual', internalType: 'uint256', type: 'uint256' }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, ], - name: 'CommissionRateTooHigh', + name: 'getPieceLeafCount', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', }, { - type: 'error', - inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'oldLockup', internalType: 'uint256', type: 'uint256' }, - { name: 'currentLockup', internalType: 'uint256', type: 'uint256' }, - ], - name: 'CurrentLockupLessThanOldLockup', + type: 'function', + inputs: [{ name: 'epoch', internalType: 'uint256', type: 'uint256' }], + name: 'getRandomness', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', }, { - type: 'error', - inputs: [ - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'currentLockup', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupReduction', internalType: 'uint256', type: 'uint256' }, - ], - name: 'InsufficientCurrentLockup', + type: 'function', + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], + name: 'getScheduledRemovals', + outputs: [{ name: '', internalType: 'uint256[]', type: 'uint256[]' }], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'required', internalType: 'uint256', type: 'uint256' }, - { name: 'actual', internalType: 'uint256', type: 'uint256' }, + { name: '_challengeFinality', internalType: 'uint256', type: 'uint256' }, ], - name: 'InsufficientFundsForOneTimePayment', + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', - inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'available', internalType: 'uint256', type: 'uint256' }, - { name: 'required', internalType: 'uint256', type: 'uint256' }, - ], - name: 'InsufficientFundsForSettlement', + type: 'function', + inputs: [], + name: 'migrate', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'available', internalType: 'uint256', type: 'uint256' }, - { name: 'required', internalType: 'uint256', type: 'uint256' }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'challengeEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'InsufficientLockupForSettlement', + name: 'nextProvingPeriod', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', - inputs: [ - { name: 'required', internalType: 'uint256', type: 'uint256' }, - { name: 'sent', internalType: 'uint256', type: 'uint256' }, - ], - name: 'InsufficientNativeTokenForBurn', + type: 'function', + inputs: [], + name: 'owner', + outputs: [{ name: '', internalType: 'address', type: 'address' }], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'available', internalType: 'uint256', type: 'uint256' }, - { name: 'requested', internalType: 'uint256', type: 'uint256' }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, ], - name: 'InsufficientUnlockedFunds', + name: 'pieceChallengable', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { - name: 'nextRateChangeUntilEpoch', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'processedEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, ], - name: 'InvalidRateChangeQueueState', + name: 'pieceLive', + outputs: [{ name: '', internalType: 'bool', type: 'bool' }], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'actualPeriod', internalType: 'uint256', type: 'uint256' }, - { name: 'actualLockupFixed', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedPeriod', internalType: 'uint256', type: 'uint256' }, - { - name: 'attemptedLockupFixed', - internalType: 'uint256', - type: 'uint256', - }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'newStorageProvider', internalType: 'address', type: 'address' }, ], - name: 'InvalidTerminatedRailModification', + name: 'proposeDataSetStorageProvider', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', - inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'account', internalType: 'address', type: 'address' }, - { name: 'lockupCurrent', internalType: 'uint256', type: 'uint256' }, - { name: 'fundsCurrent', internalType: 'uint256', type: 'uint256' }, - ], - name: 'LockupExceedsFundsInvariant', + type: 'function', + inputs: [], + name: 'proposedFeePerTiB', + outputs: [{ name: '', internalType: 'uint96', type: 'uint96' }], + stateMutability: 'view', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'actualLockupFixed', internalType: 'uint256', type: 'uint256' }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, { - name: 'attemptedLockupFixed', - internalType: 'uint256', - type: 'uint256', + name: 'proofs', + internalType: 'struct IPDPTypes.Proof[]', + type: 'tuple[]', + components: [ + { name: 'leaf', internalType: 'bytes32', type: 'bytes32' }, + { name: 'proof', internalType: 'bytes32[]', type: 'bytes32[]' }, + ], }, ], - name: 'LockupFixedIncreaseNotAllowedDueToInsufficientFunds', + name: 'provePossession', + outputs: [], + stateMutability: 'payable', }, { - type: 'error', - inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'expectedLockup', internalType: 'uint256', type: 'uint256' }, - { name: 'actualLockup', internalType: 'uint256', type: 'uint256' }, - ], - name: 'LockupInconsistencyDuringRailFinalization', + type: 'function', + inputs: [], + name: 'proxiableUUID', + outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], + stateMutability: 'view', }, { - type: 'error', - inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'isSettled', internalType: 'bool', type: 'bool' }, - { name: 'currentRate', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedRate', internalType: 'uint256', type: 'uint256' }, - ], - name: 'LockupNotSettledRateChangeNotAllowed', + type: 'function', + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'actualLockupPeriod', internalType: 'uint256', type: 'uint256' }, - { - name: 'attemptedLockupPeriod', - internalType: 'uint256', - type: 'uint256', - }, + { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, + { name: 'extraData', internalType: 'bytes', type: 'bytes' }, ], - name: 'LockupPeriodChangeNotAllowedDueToInsufficientFunds', + name: 'schedulePieceDeletions', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', + inputs: [{ name: 'newOwner', internalType: 'address', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, - { name: 'operator', internalType: 'address', type: 'address' }, - { name: 'maxAllowedPeriod', internalType: 'uint256', type: 'uint256' }, - { name: 'requestedPeriod', internalType: 'uint256', type: 'uint256' }, + { name: 'newFeePerTiB', internalType: 'uint256', type: 'uint256' }, ], - name: 'LockupPeriodExceedsOperatorMaximum', + name: 'updateProofFee', + outputs: [], + stateMutability: 'nonpayable', }, { - type: 'error', + type: 'function', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'paymentRate', internalType: 'uint256', type: 'uint256' }, - { name: 'lockupRate', internalType: 'uint256', type: 'uint256' }, + { name: 'newImplementation', internalType: 'address', type: 'address' }, + { name: 'data', internalType: 'bytes', type: 'bytes' }, ], - name: 'LockupRateInconsistent', + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'lockupRate', internalType: 'uint256', type: 'uint256' }, - { name: 'oldRate', internalType: 'uint256', type: 'uint256' }, + { + name: 'version', + internalType: 'string', + type: 'string', + indexed: false, + }, + { + name: 'implementation', + internalType: 'address', + type: 'address', + indexed: false, + }, ], - name: 'LockupRateLessThanOldRate', + name: 'ContractUpgraded', }, - { type: 'error', inputs: [], name: 'MissingServiceFeeRecipient' }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'required', internalType: 'uint256', type: 'uint256' }, - { name: 'sent', internalType: 'uint256', type: 'uint256' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'storageProvider', + internalType: 'address', + type: 'address', + indexed: true, + }, ], - name: 'MustSendExactNativeAmount', - }, - { - type: 'error', - inputs: [{ name: 'sent', internalType: 'uint256', type: 'uint256' }], - name: 'NativeTokenNotAccepted', + name: 'DataSetCreated', }, - { type: 'error', inputs: [], name: 'NativeTokenNotSupported' }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'to', internalType: 'address', type: 'address' }, - { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'deletedLeafCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'NativeTransferFailed', + name: 'DataSetDeleted', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'expectedSettledUpTo', internalType: 'uint256', type: 'uint256' }, - { name: 'actualSettledUpTo', internalType: 'uint256', type: 'uint256' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, ], - name: 'NoProgressInSettlement', + name: 'DataSetEmpty', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'allowedClient', internalType: 'address', type: 'address' }, - { name: 'allowedOperator', internalType: 'address', type: 'address' }, - { name: 'caller', internalType: 'address', type: 'address' }, + { + name: 'currentFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'effectiveTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'NotAuthorizedToTerminateRail', + name: 'FeeUpdateProposed', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'available', internalType: 'uint256', type: 'uint256' }, - { name: 'required', internalType: 'uint256', type: 'uint256' }, + { + name: 'version', + internalType: 'uint64', + type: 'uint64', + indexed: false, + }, ], - name: 'OneTimePaymentExceedsLockup', + name: 'Initialized', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'caller', internalType: 'address', type: 'address' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'challengeEpoch', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'leafCount', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], - name: 'OnlyRailClientAllowed', + name: 'NextProvingPeriod', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'caller', internalType: 'address', type: 'address' }, + { + name: 'previousOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newOwner', + internalType: 'address', + type: 'address', + indexed: true, + }, ], - name: 'OnlyRailOperatorAllowed', + name: 'OwnershipTransferred', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'expectedFrom', internalType: 'address', type: 'address' }, - { name: 'expectedOperator', internalType: 'address', type: 'address' }, - { name: 'expectedTo', internalType: 'address', type: 'address' }, - { name: 'caller', internalType: 'address', type: 'address' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'pieceIds', + internalType: 'uint256[]', + type: 'uint256[]', + indexed: false, + }, + { + name: 'pieceCids', + internalType: 'struct Cids.Cid[]', + type: 'tuple[]', + components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], + indexed: false, + }, ], - name: 'OnlyRailParticipantAllowed', + name: 'PiecesAdded', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'allowed', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedUsage', internalType: 'uint256', type: 'uint256' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'pieceIds', + internalType: 'uint256[]', + type: 'uint256[]', + indexed: false, + }, ], - name: 'OperatorLockupAllowanceExceeded', + name: 'PiecesRemoved', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'from', internalType: 'address', type: 'address' }, - { name: 'operator', internalType: 'address', type: 'address' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'challenges', + internalType: 'struct IPDPTypes.PieceIdAndOffset[]', + type: 'tuple[]', + components: [ + { name: 'pieceId', internalType: 'uint256', type: 'uint256' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + ], + indexed: false, + }, ], - name: 'OperatorNotApproved', + name: 'PossessionProven', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'allowed', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedUsage', internalType: 'uint256', type: 'uint256' }, + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { name: 'fee', internalType: 'uint256', type: 'uint256', indexed: false }, ], - name: 'OperatorRateAllowanceExceeded', + name: 'ProofFeePaid', }, { - type: 'error', + type: 'event', + anonymous: false, inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, - ], - name: 'PermitRecipientMustBeMsgSender', - }, - { - type: 'error', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'RailAlreadyTerminated', - }, - { - type: 'error', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'RailInactiveOrSettled', - }, - { - type: 'error', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'RailNotTerminated', + { + name: 'setId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'oldStorageProvider', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'newStorageProvider', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'StorageProviderChanged', }, { - type: 'error', - inputs: [{ name: 'railId', internalType: 'uint256', type: 'uint256' }], - name: 'RateChangeNotAllowedOnTerminatedRail', + type: 'event', + anonymous: false, + inputs: [ + { + name: 'implementation', + internalType: 'address', + type: 'address', + indexed: true, + }, + ], + name: 'Upgraded', }, { type: 'error', - inputs: [{ name: 'nextUntilEpoch', internalType: 'uint256', type: 'uint256' }], - name: 'RateChangeQueueNotEmpty', + inputs: [{ name: 'target', internalType: 'address', type: 'address' }], + name: 'AddressEmptyCode', }, - { type: 'error', inputs: [], name: 'ReentrancyGuardReentrantCall' }, { type: 'error', - inputs: [{ name: 'token', internalType: 'address', type: 'address' }], - name: 'SafeERC20FailedOperation', + inputs: [ + { name: 'implementation', internalType: 'address', type: 'address' }, + ], + name: 'ERC1967InvalidImplementation', }, + { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, + { type: 'error', inputs: [], name: 'FailedCall' }, { type: 'error', inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'maxAllowed', internalType: 'uint256', type: 'uint256' }, - { name: 'attempted', internalType: 'uint256', type: 'uint256' }, + { name: 'idx', internalType: 'uint256', type: 'uint256' }, + { name: 'msg', internalType: 'string', type: 'string' }, ], - name: 'ValidatorModifiedAmountExceedsMaximum', + name: 'IndexedError', }, + { type: 'error', inputs: [], name: 'InvalidInitialization' }, + { type: 'error', inputs: [], name: 'NotInitializing' }, { type: 'error', - inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'allowedStart', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedStart', internalType: 'uint256', type: 'uint256' }, - ], - name: 'ValidatorSettledBeforeSegmentStart', + inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], + name: 'OwnableInvalidOwner', }, { type: 'error', - inputs: [ - { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'allowedEnd', internalType: 'uint256', type: 'uint256' }, - { name: 'attemptedEnd', internalType: 'uint256', type: 'uint256' }, - ], - name: 'ValidatorSettledBeyondSegmentEnd', + inputs: [{ name: 'account', internalType: 'address', type: 'address' }], + name: 'OwnableUnauthorizedAccount', }, + { type: 'error', inputs: [], name: 'UUPSUnauthorizedCallContext' }, { type: 'error', - inputs: [{ name: 'varName', internalType: 'string', type: 'string' }], - name: 'ZeroAddressNotAllowed', + inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], + name: 'UUPSUnsupportedProxiableUUID', }, ] as const /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x1096025c9D6B29E12E2f04965F6E64d564Ce0750) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x06279D540BDCd6CA33B073cEAeA1425B6C68c93d) */ -export const paymentsAddress = { +export const pdpVerifierAddress = { 314: '0x0000000000000000000000000000000000000000', - 314159: '0x1096025c9D6B29E12E2f04965F6E64d564Ce0750', + 314159: '0x06279D540BDCd6CA33B073cEAeA1425B6C68c93d', } as const /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x1096025c9D6B29E12E2f04965F6E64d564Ce0750) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0x06279D540BDCd6CA33B073cEAeA1425B6C68c93d) */ -export const paymentsConfig = { - address: paymentsAddress, - abi: paymentsAbi, +export const pdpVerifierConfig = { + address: pdpVerifierAddress, + abi: pdpVerifierAbi, } as const ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -3461,17 +4081,10 @@ export const paymentsConfig = { /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xc758dB755f59189d8FB3C166Ee372b77d7CFA9D3) */ export const serviceProviderRegistryAbi = [ { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, - { - type: 'function', - inputs: [], - name: 'BURN_ACTOR', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, { type: 'function', inputs: [], @@ -3552,55 +4165,13 @@ export const serviceProviderRegistryAbi = [ }, { type: 'function', - inputs: [{ name: 'providerAddress', internalType: 'address', type: 'address' }], + inputs: [ + { name: 'providerAddress', internalType: 'address', type: 'address' }, + ], name: 'addressToProviderId', outputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, - { - type: 'function', - inputs: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], - name: 'decodePDPOffering', - outputs: [ - { - name: '', - internalType: 'struct ServiceProviderRegistryStorage.PDPOffering', - type: 'tuple', - components: [ - { name: 'serviceURL', internalType: 'string', type: 'string' }, - { - name: 'minPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'maxPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'ipniPiece', internalType: 'bool', type: 'bool' }, - { name: 'ipniIpfs', internalType: 'bool', type: 'bool' }, - { - name: 'storagePricePerTibPerMonth', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'minProvingPeriodInEpochs', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'location', internalType: 'string', type: 'string' }, - { - name: 'paymentTokenAddress', - internalType: 'contract IERC20', - type: 'address', - }, - ], - }, - ], - stateMutability: 'pure', - }, { type: 'function', inputs: [], @@ -3616,50 +4187,6 @@ export const serviceProviderRegistryAbi = [ ], stateMutability: 'view', }, - { - type: 'function', - inputs: [ - { - name: 'pdpOffering', - internalType: 'struct ServiceProviderRegistryStorage.PDPOffering', - type: 'tuple', - components: [ - { name: 'serviceURL', internalType: 'string', type: 'string' }, - { - name: 'minPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'maxPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'ipniPiece', internalType: 'bool', type: 'bool' }, - { name: 'ipniIpfs', internalType: 'bool', type: 'bool' }, - { - name: 'storagePricePerTibPerMonth', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'minProvingPeriodInEpochs', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'location', internalType: 'string', type: 'string' }, - { - name: 'paymentTokenAddress', - internalType: 'contract IERC20', - type: 'address', - }, - ], - }, - ], - name: 'encodePDPOffering', - outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], - stateMutability: 'pure', - }, { type: 'function', inputs: [ @@ -3675,18 +4202,21 @@ export const serviceProviderRegistryAbi = [ outputs: [ { name: 'result', - internalType: 'struct ServiceProviderRegistryStorage.PaginatedProviders', + internalType: + 'struct ServiceProviderRegistryStorage.PaginatedProviders', type: 'tuple', components: [ { name: 'providers', - internalType: 'struct ServiceProviderRegistryStorage.ProviderWithProduct[]', + internalType: + 'struct ServiceProviderRegistryStorage.ProviderWithProduct[]', type: 'tuple[]', components: [ { name: 'providerId', internalType: 'uint256', type: 'uint256' }, { name: 'providerInfo', - internalType: 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', type: 'tuple', components: [ { @@ -3702,21 +4232,18 @@ export const serviceProviderRegistryAbi = [ type: 'string', }, { name: 'isActive', internalType: 'bool', type: 'bool' }, - { - name: 'providerId', - internalType: 'uint256', - type: 'uint256', - }, ], }, { name: 'product', - internalType: 'struct ServiceProviderRegistryStorage.ServiceProduct', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProduct', type: 'tuple', components: [ { name: 'productType', - internalType: 'enum ServiceProviderRegistryStorage.ProductType', + internalType: + 'enum ServiceProviderRegistryStorage.ProductType', type: 'uint8', }, { name: 'productData', internalType: 'bytes', type: 'bytes' }, @@ -3863,15 +4390,27 @@ export const serviceProviderRegistryAbi = [ outputs: [ { name: 'info', - internalType: 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + internalType: 'struct ServiceProviderRegistry.ServiceProviderInfoView', type: 'tuple', components: [ - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'name', internalType: 'string', type: 'string' }, - { name: 'description', internalType: 'string', type: 'string' }, - { name: 'isActive', internalType: 'bool', type: 'bool' }, { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { + name: 'info', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + type: 'tuple', + components: [ + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'description', internalType: 'string', type: 'string' }, + { name: 'isActive', internalType: 'bool', type: 'bool' }, + ], + }, ], }, ], @@ -3879,20 +4418,34 @@ export const serviceProviderRegistryAbi = [ }, { type: 'function', - inputs: [{ name: 'providerAddress', internalType: 'address', type: 'address' }], + inputs: [ + { name: 'providerAddress', internalType: 'address', type: 'address' }, + ], name: 'getProviderByAddress', outputs: [ { name: 'info', - internalType: 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + internalType: 'struct ServiceProviderRegistry.ServiceProviderInfoView', type: 'tuple', components: [ - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'name', internalType: 'string', type: 'string' }, - { name: 'description', internalType: 'string', type: 'string' }, - { name: 'isActive', internalType: 'bool', type: 'bool' }, { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { + name: 'info', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + type: 'tuple', + components: [ + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'description', internalType: 'string', type: 'string' }, + { name: 'isActive', internalType: 'bool', type: 'bool' }, + ], + }, ], }, ], @@ -3907,11 +4460,57 @@ export const serviceProviderRegistryAbi = [ }, { type: 'function', - inputs: [{ name: 'providerAddress', internalType: 'address', type: 'address' }], + inputs: [ + { name: 'providerAddress', internalType: 'address', type: 'address' }, + ], name: 'getProviderIdByAddress', outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, + { + type: 'function', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'getProviderPayee', + outputs: [{ name: 'payee', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'providerIds', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'getProvidersByIds', + outputs: [ + { + name: 'providerInfos', + internalType: + 'struct ServiceProviderRegistry.ServiceProviderInfoView[]', + type: 'tuple[]', + components: [ + { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { + name: 'info', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + type: 'tuple', + components: [ + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'description', internalType: 'string', type: 'string' }, + { name: 'isActive', internalType: 'bool', type: 'bool' }, + ], + }, + ], + }, + { name: 'validIds', internalType: 'bool[]', type: 'bool[]' }, + ], + stateMutability: 'view', + }, { type: 'function', inputs: [ @@ -3927,18 +4526,21 @@ export const serviceProviderRegistryAbi = [ outputs: [ { name: 'result', - internalType: 'struct ServiceProviderRegistryStorage.PaginatedProviders', + internalType: + 'struct ServiceProviderRegistryStorage.PaginatedProviders', type: 'tuple', components: [ { name: 'providers', - internalType: 'struct ServiceProviderRegistryStorage.ProviderWithProduct[]', + internalType: + 'struct ServiceProviderRegistryStorage.ProviderWithProduct[]', type: 'tuple[]', components: [ { name: 'providerId', internalType: 'uint256', type: 'uint256' }, { name: 'providerInfo', - internalType: 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', type: 'tuple', components: [ { @@ -3954,21 +4556,18 @@ export const serviceProviderRegistryAbi = [ type: 'string', }, { name: 'isActive', internalType: 'bool', type: 'bool' }, - { - name: 'providerId', - internalType: 'uint256', - type: 'uint256', - }, ], }, { name: 'product', - internalType: 'struct ServiceProviderRegistryStorage.ServiceProduct', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProduct', type: 'tuple', components: [ { name: 'productType', - internalType: 'enum ServiceProviderRegistryStorage.ProductType', + internalType: + 'enum ServiceProviderRegistryStorage.ProductType', type: 'uint8', }, { name: 'productData', internalType: 'bytes', type: 'bytes' }, @@ -4097,7 +4696,6 @@ export const serviceProviderRegistryAbi = [ { name: 'name', internalType: 'string', type: 'string' }, { name: 'description', internalType: 'string', type: 'string' }, { name: 'isActive', internalType: 'bool', type: 'bool' }, - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, ], stateMutability: 'view', }, @@ -4311,18 +4909,18 @@ export const serviceProviderRegistryAbi = [ type: 'uint8', indexed: true, }, - { - name: 'serviceUrl', - internalType: 'string', - type: 'string', - indexed: false, - }, { name: 'serviceProvider', internalType: 'address', type: 'address', indexed: false, }, + { + name: 'productData', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, { name: 'capabilityKeys', internalType: 'string[]', @@ -4373,18 +4971,18 @@ export const serviceProviderRegistryAbi = [ type: 'uint8', indexed: true, }, - { - name: 'serviceUrl', - internalType: 'string', - type: 'string', - indexed: false, - }, { name: 'serviceProvider', internalType: 'address', type: 'address', indexed: false, }, + { + name: 'productData', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, { name: 'capabilityKeys', internalType: 'string[]', @@ -4471,7 +5069,9 @@ export const serviceProviderRegistryAbi = [ }, { type: 'error', - inputs: [{ name: 'implementation', internalType: 'address', type: 'address' }], + inputs: [ + { name: 'implementation', internalType: 'address', type: 'address' }, + ], name: 'ERC1967InvalidImplementation', }, { type: 'error', inputs: [], name: 'ERC1967NonPayable' }, @@ -4498,16 +5098,16 @@ export const serviceProviderRegistryAbi = [ /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xc758dB755f59189d8FB3C166Ee372b77d7CFA9D3) */ export const serviceProviderRegistryAddress = { 314: '0x0000000000000000000000000000000000000000', - 314159: '0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb', + 314159: '0xc758dB755f59189d8FB3C166Ee372b77d7CFA9D3', } as const /** * - [__View Contract on Filecoin Mainnet Filfox__](https://filfox.info/en/address/0x0000000000000000000000000000000000000000) - * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb) + * - [__View Contract on Filecoin Calibration Filscan__](https://calibration.filscan.io/address/0xc758dB755f59189d8FB3C166Ee372b77d7CFA9D3) */ export const serviceProviderRegistryConfig = { address: serviceProviderRegistryAddress, @@ -4540,6 +5140,7 @@ export const sessionKeyRegistryAbi = [ { name: 'signer', internalType: 'address', type: 'address' }, { name: 'expiry', internalType: 'uint256', type: 'uint256' }, { name: 'permissions', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'origin', internalType: 'string', type: 'string' }, ], name: 'login', outputs: [], @@ -4551,6 +5152,7 @@ export const sessionKeyRegistryAbi = [ { name: 'signer', internalType: 'address payable', type: 'address' }, { name: 'expiry', internalType: 'uint256', type: 'uint256' }, { name: 'permissions', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'origin', internalType: 'string', type: 'string' }, ], name: 'loginAndFund', outputs: [], @@ -4561,11 +5163,49 @@ export const sessionKeyRegistryAbi = [ inputs: [ { name: 'signer', internalType: 'address', type: 'address' }, { name: 'permissions', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'origin', internalType: 'string', type: 'string' }, ], name: 'revoke', outputs: [], stateMutability: 'nonpayable', }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'identity', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'signer', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'expiry', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'permissions', + internalType: 'bytes32[]', + type: 'bytes32[]', + indexed: false, + }, + { + name: 'origin', + internalType: 'string', + type: 'string', + indexed: false, + }, + ], + name: 'AuthorizationsUpdated', + }, ] as const /** diff --git a/packages/synapse-core/src/abis/index.ts b/packages/synapse-core/src/abis/index.ts index 647c04ba..0162758b 100644 --- a/packages/synapse-core/src/abis/index.ts +++ b/packages/synapse-core/src/abis/index.ts @@ -12,10 +12,12 @@ export * from './erc20.ts' export * as generated from './generated.ts' +import * as generated from './generated.ts' +export const storage = [...generated.filecoinWarmStorageServiceAbi, ...generated.errorsAbi] as const + export { - filecoinWarmStorageServiceAbi as storage, + filecoinPayV1Abi as payments, filecoinWarmStorageServiceStateViewAbi as storageView, - paymentsAbi as payments, pdpVerifierAbi as pdp, serviceProviderRegistryAbi as serviceProviderRegistry, sessionKeyRegistryAbi as sessionKeyRegistry, diff --git a/packages/synapse-core/src/calibration.ts b/packages/synapse-core/src/calibration.ts new file mode 100644 index 00000000..377a5a0b --- /dev/null +++ b/packages/synapse-core/src/calibration.ts @@ -0,0 +1,42 @@ +import { request } from 'iso-web/http' +import type { Address, Hex } from 'viem' + +export type ClaimTokensOptions = { + address: Address +} + +export type ClaimTokenResponse = [ + { + faucetInfo: 'CalibnetUSDFC' + tx_hash: Hex + }, + { + faucetInfo: 'CalibnetFIL' + tx_hash: Hex + }, +] + +export type ClaimTokenResponseError = [ + { + faucetInfo: 'CalibnetUSDFC' + error: { ServerError: string } + }, + { + faucetInfo: 'CalibnetFIL' + error: { ServerError: string } + }, +] +export async function claimTokens(options: ClaimTokensOptions) { + const response = await request.json.get( + `https://forest-explorer.chainsafe.dev/api/claim_token_all?address=${options.address}`, + { + timeout: 20000, + } + ) + + if (response.error) { + throw new Error((response.error.cause as ClaimTokenResponseError)[0].error.ServerError) + } + + return response.result +} diff --git a/packages/synapse-core/src/chains.ts b/packages/synapse-core/src/chains.ts index 876668fb..cf2c85d9 100644 --- a/packages/synapse-core/src/chains.ts +++ b/packages/synapse-core/src/chains.ts @@ -97,7 +97,7 @@ export const mainnet: Chain = { abi: Abis.erc20WithPermit, }, payments: { - address: Abis.generated.paymentsAddress['314'], + address: Abis.generated.filecoinPayV1Address['314'], abi: Abis.payments, }, storage: { @@ -171,7 +171,7 @@ export const calibration: Chain = { abi: Abis.erc20WithPermit, }, payments: { - address: Abis.generated.paymentsAddress['314159'], + address: Abis.generated.filecoinPayV1Address['314159'], abi: Abis.payments, }, storage: { diff --git a/packages/synapse-core/src/constants.ts b/packages/synapse-core/src/constants.ts index 5cb742ef..09d1d505 100644 --- a/packages/synapse-core/src/constants.ts +++ b/packages/synapse-core/src/constants.ts @@ -76,4 +76,4 @@ export const SIZE_CONSTANTS = { DEFAULT_UPLOAD_BATCH_SIZE: 32, } as const -export const LOCKUP_PERIOD = 10n * TIME_CONSTANTS.EPOCHS_PER_DAY +export const LOCKUP_PERIOD = 30n * TIME_CONSTANTS.EPOCHS_PER_DAY diff --git a/packages/synapse-core/src/errors/base.ts b/packages/synapse-core/src/errors/base.ts index 59917659..676784a7 100644 --- a/packages/synapse-core/src/errors/base.ts +++ b/packages/synapse-core/src/errors/base.ts @@ -18,17 +18,22 @@ export class SynapseError extends Error { override name = 'SynapseError' override cause?: Error - + details?: string shortMessage: string constructor(message: string, options?: SynapseErrorOptions) { const details = options?.cause instanceof Error ? options.cause.message : options?.details ? options.details : undefined - const msg = [message || 'An error occurred.', '', ...(details ? [`Details: ${details}`] : [])].join('\n') + const msg = [ + message || 'An error occurred.', + ...(details ? [''] : []), + ...(details ? [`Details: ${details}`] : []), + ].join('\n') super(msg, options) this.cause = options?.cause ?? undefined + this.details = details ?? undefined this.shortMessage = message } diff --git a/packages/synapse-core/src/errors/pdp.ts b/packages/synapse-core/src/errors/pdp.ts index b6ca97bf..ef79d096 100644 --- a/packages/synapse-core/src/errors/pdp.ts +++ b/packages/synapse-core/src/errors/pdp.ts @@ -1,15 +1,15 @@ import { decodePDPError } from '../utils/decode-pdp-errors.ts' import { isSynapseError, SynapseError } from './base.ts' -export class InvalidPDPLocationHeaderError extends SynapseError { - override name: 'InvalidPDPLocationHeaderError' = 'InvalidPDPLocationHeaderError' +export class LocationHeaderError extends SynapseError { + override name: 'LocationHeaderError' = 'LocationHeaderError' - constructor(location: string) { - super(`Invalid PDP location header format: ${location}`) + constructor(location?: string | null) { + super(`Location header format is invalid: ${location ?? ''}`) } - static override is(value: unknown): value is InvalidPDPLocationHeaderError { - return isSynapseError(value) && value.name === 'InvalidPDPLocationHeaderError' + static override is(value: unknown): value is LocationHeaderError { + return isSynapseError(value) && value.name === 'LocationHeaderError' } } @@ -47,9 +47,8 @@ export class GetDataSetError extends SynapseError { override name: 'GetDataSetError' = 'GetDataSetError' constructor(error: string) { - const decodedError = decodePDPError(error) - super(`Failed to get data set.`, { - details: decodedError, + super(error ? 'Failed to get data set.' : 'Data set not found.', { + details: error ? decodePDPError(error) : undefined, }) } @@ -63,7 +62,7 @@ export class PostPieceError extends SynapseError { constructor(error: string) { const decodedError = decodePDPError(error) - super(`Failed to post piece.`, { + super(`Failed to create upload session.`, { details: decodedError, }) } @@ -132,3 +131,18 @@ export class PollForAddPiecesStatusError extends SynapseError { return isSynapseError(value) && value.name === 'PollForAddPiecesStatusError' } } + +export class DeletePieceError extends SynapseError { + override name: 'DeletePieceError' = 'DeletePieceError' + + constructor(error: string) { + const decodedError = decodePDPError(error) + super(`Failed to delete piece.`, { + details: decodedError, + }) + } + + static override is(value: unknown): value is DeletePieceError { + return isSynapseError(value) && value.name === 'DeletePieceError' + } +} diff --git a/packages/synapse-core/src/index.ts b/packages/synapse-core/src/index.ts index aebebb9e..052b0aea 100644 --- a/packages/synapse-core/src/index.ts +++ b/packages/synapse-core/src/index.ts @@ -10,13 +10,14 @@ */ export * as abis from './abis/index.ts' +export * from './calibration.ts' export * as chains from './chains.ts' export * from './constants.ts' -export * as curio from './curio.ts' export * as erc20 from './erc20.ts' export * as errors from './errors/index.ts' export * as pay from './pay/index.ts' export * as sessionKey from './session-key/index.ts' +export * as curio from './sp.ts' export * as typedData from './typed-data/index.ts' export * as usdfc from './usdfc.ts' export * from './utils/decode-pdp-errors.ts' diff --git a/packages/synapse-core/src/piece.ts b/packages/synapse-core/src/piece.ts index 009b85af..13f08e28 100644 --- a/packages/synapse-core/src/piece.ts +++ b/packages/synapse-core/src/piece.ts @@ -48,11 +48,15 @@ export function getSize(pieceCid: PieceCID): number { } export function parse(pieceCid: string): PieceCID { - const cid = CID.parse(pieceCid).toV1() - if (!isPieceCID(cid)) { - throw new Error('Invalid PieceCID: input must be a valid PieceCIDv2') + try { + const cid = CID.parse(pieceCid).toV1() + if (!isPieceCID(cid)) { + throw new Error('Invalid PieceCID: input must be a valid PieceCIDv2') + } + return cid + } catch { + throw new Error(`Invalid CID string: ${pieceCid}`) } - return cid } /** diff --git a/packages/synapse-core/src/session-key/actions.ts b/packages/synapse-core/src/session-key/actions.ts index 566c00ba..c6d11db3 100644 --- a/packages/synapse-core/src/session-key/actions.ts +++ b/packages/synapse-core/src/session-key/actions.ts @@ -73,6 +73,7 @@ export async function login(client: Client, options: options.sessionAddress, options.expiresAt ?? expiresAt, [...new Set(options.permissions)].map((permission) => SESSION_KEY_PERMISSIONS[permission]), + 'synapse', ], }) @@ -81,8 +82,11 @@ export async function login(client: Client, options: } export type RevokeOptions = { - sessionAddress: Address + identity: Address + signer: Address + expiresAt: bigint permissions: SessionKeyPermissions[] + origin: string } /** @@ -96,13 +100,20 @@ export type RevokeOptions = { */ export async function revoke(client: Client, options: RevokeOptions) { const chain = getChain(client.chain.id) + const expiresAt = BigInt(Math.floor(Date.now() / 1000) + 3600) + const { request } = await simulateContract(client, { address: chain.contracts.sessionKeyRegistry.address, abi: chain.contracts.sessionKeyRegistry.abi, functionName: 'revoke', args: [ - options.sessionAddress, + options.identity, + // @ts-ignore + options.signer, + // @ts-ignore + options.expiresAt ?? expiresAt, [...new Set(options.permissions)].map((permission) => SESSION_KEY_PERMISSIONS[permission]), + options.origin, ], }) const hash = await writeContract(client, request) diff --git a/packages/synapse-core/src/curio.ts b/packages/synapse-core/src/sp.ts similarity index 82% rename from packages/synapse-core/src/curio.ts rename to packages/synapse-core/src/sp.ts index 741d006e..140c3b15 100644 --- a/packages/synapse-core/src/curio.ts +++ b/packages/synapse-core/src/sp.ts @@ -1,23 +1,24 @@ /** - * Synapse Core - Curio HTTP Operations + * Synapse Core - Service Provider HTTP Operations * * @example * ```ts - * import * as Curio from '@filoz/synapse-core/curio' + * import * as SP from '@filoz/synapse-core/sp' * ``` * * @packageDocumentation */ -import { HttpError, request } from 'iso-web/http' -import type { Simplify as Curio } from 'type-fest' -import type { Address, Hex } from 'viem' +import { HttpError, request, TimeoutError } from 'iso-web/http' +import type { Simplify } from 'type-fest' +import { type Address, type Hex, isHex } from 'viem' import { AddPiecesError, CreateDataSetError, + DeletePieceError, FindPieceError, GetDataSetError, - InvalidPDPLocationHeaderError, + LocationHeaderError, PollDataSetCreationStatusError, PollForAddPiecesStatusError, PostPieceError, @@ -27,10 +28,15 @@ import type { PieceCID } from './piece.ts' import * as Piece from './piece.ts' import { createPieceUrl } from './utils/piece-url.ts' -const TIMEOUT = 180000 -const RETRIES = Infinity -const FACTOR = 1 -const MIN_TIMEOUT = 4000 // interval between retries in milliseconds +let TIMEOUT = 1000 * 60 * 5 // 5 minutes +export const RETRIES = Infinity +export const FACTOR = 1 +export const MIN_TIMEOUT = 4000 // interval between retries in milliseconds + +// Just for testing purposes +export function setTimeout(timeout: number) { + TIMEOUT = timeout +} /** * The options for the create data set on PDP API. @@ -76,14 +82,14 @@ export async function createDataSet(options: PDPCreateDataSetOptions) { throw response.error } - const location = response.result.headers.get('Location') ?? '' - const hash = location.split('/').pop() - if (!hash) { - throw new InvalidPDPLocationHeaderError(location) + const location = response.result.headers.get('Location') + const hash = location?.split('/').pop() + if (!location || !hash || !isHex(hash)) { + throw new LocationHeaderError(location) } return { - hash: hash as `0x${string}`, + txHash: hash, statusUrl: new URL(location, options.endpoint).toString(), } } @@ -156,12 +162,14 @@ export type GetDataSetOptions = { export type GetDataSetResponse = { id: number nextChallengeEpoch: number - pieces: CurioPiece[] + pieces: SPPiece[] } -export type CurioPiece = { +export type SPPiece = { pieceCid: string pieceId: number + subPieceCid: string + subPieceOffset: number } /** @@ -184,6 +192,7 @@ export async function getDataSet(options: GetDataSetOptions) { } throw response.error } + return response.result } @@ -195,8 +204,8 @@ export type GetPiecesForDataSetOptions = { cdn: boolean } -export type CurioPieceWithUrl = Curio< - CurioPiece & { +export type SPPieceWithUrl = Simplify< + SPPiece & { pieceUrl: string } > @@ -212,12 +221,14 @@ export type CurioPieceWithUrl = Curio< * @param options.address - The address of the user. * @param options.cdn - Whether the CDN is enabled. */ -export async function getPiecesForDataSet(options: GetPiecesForDataSetOptions) { +export async function getPiecesForDataSet(options: GetPiecesForDataSetOptions): Promise { const dataSet = await getDataSet(options) const pieces = dataSet.pieces.map((piece) => ({ pieceCid: piece.pieceCid, pieceId: piece.pieceId, pieceUrl: createPieceUrl(piece.pieceCid, options.cdn, options.address, options.chainId, options.endpoint), + subPieceCid: piece.subPieceCid, + subPieceOffset: piece.subPieceOffset, })) return pieces @@ -254,7 +265,6 @@ export async function uploadPiece(options: UploadPieceOptions) { headers: { 'Content-Type': 'application/json', }, - timeout: TIMEOUT, }) if (response.error) { @@ -272,10 +282,10 @@ export async function uploadPiece(options: UploadPieceOptions) { } // Extract upload ID from Location header - const location = response.result.headers.get('Location') ?? '' - const uploadUuid = location.split('/').pop() - if (uploadUuid == null) { - throw new InvalidPDPLocationHeaderError(location) + const location = response.result.headers.get('Location') + const uploadUuid = location?.split('/').pop() + if (!location || !uploadUuid) { + throw new LocationHeaderError(location) } const uploadResponse = await request.put(new URL(`pdp/piece/upload/${uploadUuid}`, options.endpoint), { @@ -284,6 +294,7 @@ export async function uploadPiece(options: UploadPieceOptions) { 'Content-Type': 'application/octet-stream', 'Content-Length': options.data.length.toString(), }, + timeout: false, }) if (uploadResponse.error) { @@ -319,12 +330,8 @@ export async function findPiece(options: FindPieceOptions): Promise { const params = new URLSearchParams({ pieceCid: pieceCid.toString() }) const response = await request.json.get<{ pieceCid: string }>(new URL(`pdp/piece?${params.toString()}`, endpoint), { - onResponse(response) { - if (!response.ok) { - throw new Error(`Piece not found: ${pieceCid.toString()}`) - } - }, retry: { + statusCodes: [404], retries: RETRIES, factor: FACTOR, }, @@ -332,9 +339,12 @@ export async function findPiece(options: FindPieceOptions): Promise { }) if (response.error) { - if (response.error instanceof HttpError) { + if (HttpError.is(response.error)) { throw new FindPieceError(await response.error.response.text()) } + if (TimeoutError.is(response.error)) { + throw new FindPieceError('Timeout waiting for piece to be found') + } throw response.error } const data = response.result @@ -344,7 +354,6 @@ export async function findPiece(options: FindPieceOptions): Promise { export type AddPiecesOptions = { endpoint: string dataSetId: bigint - clientDataSetId: bigint nextPieceId: bigint pieces: PieceCID[] extraData: Hex @@ -358,7 +367,6 @@ export type AddPiecesOptions = { * @param options - The options for the add pieces. * @param options.endpoint - The endpoint of the PDP API. * @param options.dataSetId - The ID of the data set. - * @param options.clientDataSetId - The ID of the client data set. * @param options.nextPieceId - The next piece ID. * @param options.pieces - The pieces to add. * @param options.extraData - The extra data for the add pieces. @@ -386,10 +394,10 @@ export async function addPieces(options: AddPiecesOptions) { } throw response.error } - const location = response.result.headers.get('Location') ?? '' - const txHash = location.split('/').pop() - if (!txHash) { - throw new InvalidPDPLocationHeaderError(location) + const location = response.result.headers.get('Location') + const txHash = location?.split('/').pop() + if (!location || !txHash || !isHex(txHash)) { + throw new LocationHeaderError(location) } return { @@ -469,3 +477,38 @@ export async function pollForAddPiecesStatus(options: PollForAddPiecesStatusOpti } return response.result as AddPiecesSuccess } + +export type DeletePieceOptions = { + endpoint: string + dataSetId: bigint + pieceId: bigint + extraData: Hex +} + +export type DeletePieceResponse = { + txHash: Hex +} + +/** + * Delete a piece from a data set on the PDP API. + * + * DELETE /pdp/data-sets/{dataSetId}/pieces/{pieceId} + */ +export async function deletePiece(options: DeletePieceOptions) { + const { endpoint, dataSetId, pieceId, extraData } = options + const response = await request.json.delete( + new URL(`pdp/data-sets/${dataSetId}/pieces/${pieceId}`, endpoint), + { + body: { extraData }, + } + ) + + if (response.error) { + if (HttpError.is(response.error)) { + throw new DeletePieceError(await response.error.response.text()) + } + throw response.error + } + + return response.result +} diff --git a/packages/synapse-core/src/typed-data/sign-create-dataset.ts b/packages/synapse-core/src/typed-data/sign-create-dataset.ts index 1cfefed1..b65d429c 100644 --- a/packages/synapse-core/src/typed-data/sign-create-dataset.ts +++ b/packages/synapse-core/src/typed-data/sign-create-dataset.ts @@ -34,8 +34,8 @@ export async function signCreateDataSet(client: Client item.value) const extraData = encodeAbiParameters( - [{ type: 'address' }, { type: 'string[]' }, { type: 'string[]' }, { type: 'bytes' }], - [client.account.address, keys, values, signature] + [{ type: 'address' }, { type: 'uint256' }, { type: 'string[]' }, { type: 'string[]' }, { type: 'bytes' }], + [client.account.address, options.clientDataSetId, keys, values, signature] ) return extraData diff --git a/packages/synapse-core/src/typed-data/sign-schedule-piece-removals.ts b/packages/synapse-core/src/typed-data/sign-schedule-piece-removals.ts new file mode 100644 index 00000000..e929fa43 --- /dev/null +++ b/packages/synapse-core/src/typed-data/sign-schedule-piece-removals.ts @@ -0,0 +1,34 @@ +import { type Account, type Chain, type Client, encodeAbiParameters, type Transport } from 'viem' +import { signTypedData } from 'viem/actions' +import { getChain } from '../chains.ts' +import { EIP712Types, getStorageDomain } from './type-definitions.ts' + +export type SignSchedulePieceRemovalsOptions = { + clientDataSetId: bigint + pieceIds: bigint[] +} + +/** + * Sign the schedule piece removals and abi encode the signature + * + * @param client - The client to use to sign the message. + * @param options - The options for the schedule piece removals message. + */ +export async function signSchedulePieceRemovals( + client: Client, + options: SignSchedulePieceRemovalsOptions +) { + const chain = getChain(client.chain.id) + const signature = await signTypedData(client, { + account: client.account, + domain: getStorageDomain({ chain }), + types: EIP712Types, + primaryType: 'SchedulePieceRemovals', + message: { + clientDataSetId: options.clientDataSetId, + pieceIds: options.pieceIds, + }, + }) + const extraData = encodeAbiParameters([{ type: 'bytes' }], [signature]) + return extraData +} diff --git a/packages/synapse-core/src/utils/decode-pdp-errors.ts b/packages/synapse-core/src/utils/decode-pdp-errors.ts index 6d5e7621..9ce9a800 100644 --- a/packages/synapse-core/src/utils/decode-pdp-errors.ts +++ b/packages/synapse-core/src/utils/decode-pdp-errors.ts @@ -55,7 +55,7 @@ export function decodePDPError(error: string) { } else if (extractedContent?.startsWith('Error(')) { return `\n${extractedContent.replace('Error(', '').replace(')', '')}` } else { - return `Curio PDP\n${error}` + return `Service Provider PDP\n${error}` } } @@ -80,9 +80,9 @@ function formatPDPError(error: { abiItem: AbiError; args: readonly unknown[] | u : undefined return [ - errorWithParams ? `Error: ${errorWithParams}` : '', + errorWithParams ? `${errorWithParams}` : '', formattedArgs && formattedArgs !== '()' - ? ` ${[...Array(error.errorName?.length ?? 0).keys()].map(() => ' ').join('')}${formattedArgs}` + ? `${[...Array(error.errorName?.length ?? 0).keys()].map(() => ' ').join('')}${formattedArgs}` : '', ].join('\n') } diff --git a/packages/synapse-core/src/utils/rand.ts b/packages/synapse-core/src/utils/rand.ts new file mode 100644 index 00000000..e682615a --- /dev/null +++ b/packages/synapse-core/src/utils/rand.ts @@ -0,0 +1,47 @@ +const crypto = globalThis.crypto + +export function fallbackRandU256(): bigint { + let result = 0n + for (let i = 0; i < 32; i++) { + result <<= 8n + result |= BigInt(fallbackRandIndex(256)) + } + return result +} + +/** + * @returns a random unsigned big integer between `0` and `2**256-1` inclusive + */ +export function randU256(): bigint { + if (crypto?.getRandomValues != null) { + const randU64s = new BigUint64Array(4) + crypto.getRandomValues(randU64s) + let result = 0n + randU64s.forEach((randU64) => { + result <<= 64n + result |= randU64 + }) + return result + } else { + return fallbackRandU256() + } +} + +export function fallbackRandIndex(length: number): number { + return Math.floor(Math.random() * length) +} + +/** + * Provides a random index into an array of supplied length (0 <= index < length) + * @param length - exclusive upper boundary + * @returns a valid index + */ +export function randIndex(length: number): number { + if (crypto?.getRandomValues != null) { + const randomBytes = new Uint32Array(1) + crypto.getRandomValues(randomBytes) + return randomBytes[0] % length + } else { + return fallbackRandIndex(length) + } +} diff --git a/packages/synapse-core/src/warm-storage/data-sets.ts b/packages/synapse-core/src/warm-storage/data-sets.ts index 86cd3356..3496ae86 100644 --- a/packages/synapse-core/src/warm-storage/data-sets.ts +++ b/packages/synapse-core/src/warm-storage/data-sets.ts @@ -1,12 +1,13 @@ import type { AbiParametersToPrimitiveTypes, ExtractAbiFunction } from 'abitype' import { type Account, type Address, type Chain, type Client, isAddressEqual, type Transport } from 'viem' -import { multicall, readContract } from 'viem/actions' +import { multicall, readContract, simulateContract, writeContract } from 'viem/actions' import type * as Abis from '../abis/index.ts' import { getChain } from '../chains.ts' -import * as PDP from '../curio.ts' +import * as PDP from '../sp.ts' import { signCreateDataSet } from '../typed-data/sign-create-dataset.ts' import { datasetMetadataObjectToEntry, type MetadataObject, metadataArrayToObject } from '../utils/metadata.ts' -import type { PDPProvider } from './providers.ts' +import { randU256 } from '../utils/rand.ts' +import type { PDPOffering, PDPProvider } from './providers.ts' /** * ABI function to get the client data sets @@ -22,11 +23,11 @@ export type ClientDataSet = AbiParametersToPrimitiveTypes, options: Get }) const promises = data.map(async (dataSet) => { - const pdpDatasetId = await readContract(client, { - address: chain.contracts.storageView.address, - abi: chain.contracts.storageView.abi, - functionName: 'railToDataSet', - args: [dataSet.pdpRailId], - }) - - const [live, listener, metadata] = await multicall(client, { + const [live, listener, metadata, pdpOffering] = await multicall(client, { allowFailure: false, contracts: [ { abi: chain.contracts.pdp.abi, address: chain.contracts.pdp.address, functionName: 'dataSetLive', - args: [pdpDatasetId], + args: [dataSet.dataSetId], }, { abi: chain.contracts.pdp.abi, address: chain.contracts.pdp.address, functionName: 'getDataSetListener', - args: [pdpDatasetId], + args: [dataSet.dataSetId], }, { address: chain.contracts.storageView.address, abi: chain.contracts.storageView.abi, functionName: 'getAllDataSetMetadata', - args: [pdpDatasetId], + args: [dataSet.dataSetId], + }, + { + address: chain.contracts.serviceProviderRegistry.address, + abi: chain.contracts.serviceProviderRegistry.abi, + functionName: 'getPDPService', + args: [dataSet.providerId], }, ], }) return { ...dataSet, - pdpDatasetId, live, managed: isAddressEqual(listener, chain.contracts.storage.address), cdn: dataSet.cdnRailId !== 0n, metadata: metadataArrayToObject(metadata), + pdp: pdpOffering[0], } }) const proofs = await Promise.all(promises) @@ -95,6 +95,71 @@ export async function getDataSets(client: Client, options: Get return proofs } +export type GetDataSetOptions = { + /** + * The ID of the data set to get. + */ + dataSetId: bigint +} + +/** + * Get a data set by ID + * + * @param client - The client to use to get the data set. + * @param options - The options for the get data set. + * @param options.dataSetId - The ID of the data set to get. + * @returns The data set + */ +export async function getDataSet(client: Client, options: GetDataSetOptions): Promise { + const chain = getChain(client.chain.id) + + const dataSet = await readContract(client, { + address: chain.contracts.storageView.address, + abi: chain.contracts.storageView.abi, + functionName: 'getDataSet', + args: [options.dataSetId], + }) + + const [live, listener, metadata, pdpOffering] = await multicall(client, { + allowFailure: false, + contracts: [ + { + abi: chain.contracts.pdp.abi, + address: chain.contracts.pdp.address, + functionName: 'dataSetLive', + args: [options.dataSetId], + }, + { + abi: chain.contracts.pdp.abi, + address: chain.contracts.pdp.address, + functionName: 'getDataSetListener', + args: [options.dataSetId], + }, + { + address: chain.contracts.storageView.address, + abi: chain.contracts.storageView.abi, + functionName: 'getAllDataSetMetadata', + args: [options.dataSetId], + }, + { + address: chain.contracts.serviceProviderRegistry.address, + abi: chain.contracts.serviceProviderRegistry.abi, + functionName: 'getPDPService', + args: [dataSet.providerId], + }, + ], + }) + + return { + ...dataSet, + live, + managed: isAddressEqual(listener, chain.contracts.storage.address), + cdn: dataSet.cdnRailId !== 0n, + metadata: metadataArrayToObject(metadata), + pdp: pdpOffering[0], + } +} + /** * Get the metadata for a data set * @@ -119,25 +184,26 @@ export type CreateDataSetOptions = { */ provider: PDPProvider cdn: boolean - publicClient?: Client metadata?: MetadataObject } +/** + * Create a data set + * + * @param client - The client to use to create the data set. + * @param options - The options for the create data set. + * @param options.provider - The PDP provider to use to create the data set. + * @param options.cdn - Whether the data set should use CDN. + * @param options.metadata - The metadata for the data set. + * @returns The response from the create data set on PDP API. + */ export async function createDataSet(client: Client, options: CreateDataSetOptions) { const chain = getChain(client.chain.id) - const endpoint = options.provider.pdp.serviceURL - - // Get the next client data set id - const nextClientDataSetId = await readContract(client, { - address: chain.contracts.storageView.address, - abi: chain.contracts.storageView.abi, - functionName: 'clientDataSetIDs', - args: [client.account.address], - }) + const endpoint = options.provider.product.productData.serviceURL // Sign and encode the create data set message const extraData = await signCreateDataSet(client, { - clientDataSetId: nextClientDataSetId, + clientDataSetId: randU256(), payee: options.provider.payee, metadata: datasetMetadataObjectToEntry(options.metadata, { cdn: options.cdn, @@ -150,3 +216,24 @@ export async function createDataSet(client: Client, o extraData, }) } + +export type TerminateDataSetOptions = { + /** + * The ID of the data set to terminate. + */ + dataSetId: bigint +} + +export async function terminateDataSet(client: Client, options: TerminateDataSetOptions) { + const chain = getChain(client.chain.id) + + const { request } = await simulateContract(client, { + address: chain.contracts.storage.address, + abi: chain.contracts.storage.abi, + functionName: 'terminateService', + args: [options.dataSetId], + }) + + const tx = await writeContract(client, request) + return tx +} diff --git a/packages/synapse-core/src/warm-storage/index.ts b/packages/synapse-core/src/warm-storage/index.ts index 4b105321..2642168a 100644 --- a/packages/synapse-core/src/warm-storage/index.ts +++ b/packages/synapse-core/src/warm-storage/index.ts @@ -9,6 +9,7 @@ * @packageDocumentation */ export * from './data-sets.ts' +export * from './pieces.ts' export * from './providers.ts' export * from './read-addresses.ts' export * from './service-price.ts' diff --git a/packages/synapse-core/src/warm-storage/pieces.ts b/packages/synapse-core/src/warm-storage/pieces.ts new file mode 100644 index 00000000..65dc6739 --- /dev/null +++ b/packages/synapse-core/src/warm-storage/pieces.ts @@ -0,0 +1,140 @@ +import { CID } from 'multiformats' +import pRetry from 'p-retry' +import { type Account, type Address, type Chain, type Client, type Hex, hexToBytes, type Transport } from 'viem' +import { getTransaction, readContract, waitForTransactionReceipt } from 'viem/actions' +import { getChain } from '../chains.ts' +import type { PieceCID } from '../piece.ts' +import * as PDP from '../sp.ts' +import { signSchedulePieceRemovals } from '../typed-data/sign-schedule-piece-removals.ts' +import { createPieceUrl } from '../utils/piece-url.ts' +import type { DataSet } from './data-sets.ts' + +export type DeletePieceOptions = { + pieceId: bigint + dataSet: DataSet +} + +/** + * Delete a piece from a data set + * + * Call the Service Provider API to delete the piece. + * + * @param client - The client to use to delete the piece. + * @param options - The options for the delete piece. + * @param options.dataSetId - The ID of the data set. + * @param options.clientDataSetId - The ID of the client data set. + * @param options.pieceId - The ID of the piece. + * @param options.endpoint - The endpoint of the PDP API. + * @returns The transaction hash of the delete operation. + */ +export async function deletePiece(client: Client, options: DeletePieceOptions) { + return PDP.deletePiece({ + endpoint: options.dataSet.pdp.serviceURL, + dataSetId: options.dataSet.dataSetId, + pieceId: options.pieceId, + extraData: await signSchedulePieceRemovals(client, { + clientDataSetId: options.dataSet.clientDataSetId, + pieceIds: [options.pieceId], + }), + }) +} + +export type PollForDeletePieceStatusOptions = { + txHash: Hex +} + +/** + * Poll for the delete piece status. + * + * Waits for the transaction to be mined and then polls for the transaction receipt. + * + * @param client - The client to use to poll for the delete piece status. + * @param options - The options for the poll for the delete piece status. + * @param options.txHash - The hash of the transaction to poll for. + * @returns + */ +export async function pollForDeletePieceStatus( + client: Client, + options: PollForDeletePieceStatusOptions +) { + try { + await pRetry( + async () => { + const transaction = await getTransaction(client, { + hash: options.txHash, + }) + if (transaction.blockNumber === null) { + throw new Error('Transaction not found') + } + return transaction + }, + { + factor: 1, + minTimeout: 4000, + retries: Infinity, + maxRetryTime: 180000, + } + ) + } catch { + // no-op + } + const receipt = await waitForTransactionReceipt(client, { + hash: options.txHash, + }) + return receipt +} + +export type GetPiecesOptions = { + dataSet: DataSet + address: Address +} + +export type Piece = { + cid: PieceCID + id: bigint + url: string +} + +/** + * Get the pieces for a data set + * + * Calls the PDP Verifier contract to get the pieces. + * + * @param client - The client to use to get the pieces. + * @param options - The options for the get pieces. + * @param options.dataSet - The data set to get the pieces from. + * @param options.address - The address of the user. + */ +export async function getPieces(client: Client, options: GetPiecesOptions) { + const chain = getChain(client.chain.id) + const address = options.address + const [data, ids, hasMore] = await readContract(client, { + address: chain.contracts.pdp.address, + abi: chain.contracts.pdp.abi, + functionName: 'getActivePieces', + args: [options.dataSet.dataSetId, 0n, 100n], + }) + + const removals = await readContract(client, { + address: chain.contracts.pdp.address, + abi: chain.contracts.pdp.abi, + functionName: 'getScheduledRemovals', + args: [options.dataSet.dataSetId], + }) + + const removalsDeduped = Array.from(new Set(removals)) + + return { + pieces: data + .map((piece, index) => { + const cid = CID.decode(hexToBytes(piece.data)) as PieceCID + return { + cid, + id: ids[index], + url: createPieceUrl(cid.toString(), options.dataSet.cdn, address, chain.id, options.dataSet.pdp.serviceURL), + } + }) + .filter((piece) => !removalsDeduped.includes(piece.id)), + hasMore, + } +} diff --git a/packages/synapse-core/src/warm-storage/providers.ts b/packages/synapse-core/src/warm-storage/providers.ts index fe1c98d1..fe2e30a5 100644 --- a/packages/synapse-core/src/warm-storage/providers.ts +++ b/packages/synapse-core/src/warm-storage/providers.ts @@ -1,11 +1,24 @@ import type { AbiParametersToPrimitiveTypes, ExtractAbiFunction } from 'abitype' +import type { Simplify } from 'type-fest' import { type Chain, type Client, decodeAbiParameters, type Transport } from 'viem' import { readContract } from 'viem/actions' import * as Abis from '../abis/index.ts' import { getChain } from '../chains.ts' +export interface Provider extends ServiceProviderInfo { + id: bigint + product: ServiceProduct +} + +export type PDPServiceProduct = Simplify< + Omit & { + productData: PDPOffering + } +> + export interface PDPProvider extends ServiceProviderInfo { - pdp: PDPOffering + id: bigint + product: PDPServiceProduct } export type getProvidersByProductTypeType = ExtractAbiFunction< @@ -13,25 +26,25 @@ export type getProvidersByProductTypeType = ExtractAbiFunction< 'getProvidersByProductType' > -export type ProviderWithProduct = AbiParametersToPrimitiveTypes< +export type ContractProviderWithProduct = AbiParametersToPrimitiveTypes< getProvidersByProductTypeType['outputs'] >[0]['providers'][0] -export type decodePDPOfferingType = ExtractAbiFunction - -export type getProviderType = ExtractAbiFunction - +type decodePDPOfferingType = ExtractAbiFunction export type PDPOffering = AbiParametersToPrimitiveTypes[0] -export type ServiceProviderInfo = AbiParametersToPrimitiveTypes[0] +type getProviderType = ExtractAbiFunction + +export type ServiceProviderInfo = AbiParametersToPrimitiveTypes[0]['info'] +export type ServiceProduct = ContractProviderWithProduct['product'] // biome-ignore lint/style/noNonNullAssertion: its there const PDPOfferingAbi = Abis.serviceProviderRegistry.find( - (abi) => abi.type === 'function' && abi.name === 'decodePDPOffering' -)!.outputs + (abi) => abi.type === 'function' && abi.name === 'getPDPService' +)!.outputs[0] export function decodePDPOffering(data: `0x${string}`): PDPOffering { - return decodeAbiParameters(PDPOfferingAbi, data)[0] + return decodeAbiParameters([PDPOfferingAbi], data)[0] } /** @@ -42,17 +55,19 @@ export function decodePDPOffering(data: `0x${string}`): PDPOffering { */ export async function readProviders(client: Client): Promise { const chain = getChain(client.chain.id) + const providersIds = await readContract(client, { address: chain.contracts.storageView.address, abi: chain.contracts.storageView.abi, functionName: 'getApprovedProviders', + args: [0n, 100n], }) const p = await readContract(client, { address: chain.contracts.serviceProviderRegistry.address, abi: chain.contracts.serviceProviderRegistry.abi, functionName: 'getActiveProvidersByProductType', - args: [0, 0n, 1000n], + args: [0, 0n, 100n], }) const providers = [] as PDPProvider[] @@ -60,11 +75,15 @@ export async function readProviders(client: Client): Promise

): Promise, options: const addPieces = await PDP.addPieces({ dataSetId: options.dataSetId, - clientDataSetId: dataSet.clientDataSetId, nextPieceId: nextPieceId, pieces: uploadResponses.map((response) => response.pieceCid), endpoint: provider[0].serviceURL, diff --git a/packages/synapse-core/wagmi.config.ts b/packages/synapse-core/wagmi.config.ts index 30bd1097..886c9f8b 100644 --- a/packages/synapse-core/wagmi.config.ts +++ b/packages/synapse-core/wagmi.config.ts @@ -2,41 +2,53 @@ import { defineConfig } from '@wagmi/cli' import { fetch } from '@wagmi/cli/plugins' import type { Address } from 'viem' +// const REF = 'refs/tags/v0.3.0' +// const REF = '15eeb6dc87db236507add5553a0c76c009705525' +const REF = 'refs/heads/kubuxu/devnode-contracts' +const URL = `https://raw.githubusercontent.com/FilOzone/filecoin-services/${REF}/service_contracts/abi` + const config: ReturnType = defineConfig(() => { const contracts = [ { - name: 'Payments', + name: 'FilecoinPayV1', address: { 314: '0x0000000000000000000000000000000000000000' as Address, - 314159: '0x1096025c9D6B29E12E2f04965F6E64d564Ce0750' as Address, + 314159: '0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0' as Address, }, }, { name: 'FilecoinWarmStorageService', address: { 314: '0x0000000000000000000000000000000000000000' as Address, - 314159: '0x80617b65FD2EEa1D7fDe2B4F85977670690ed348' as Address, + 314159: '0xD3De778C05f89e1240ef70100Fb0d9e5b2eFD258' as Address, + }, + }, + { + name: 'Errors', + address: { + 314: '0x0000000000000000000000000000000000000000' as Address, + 314159: '0x0000000000000000000000000000000000000000' as Address, }, }, { name: 'FilecoinWarmStorageServiceStateView', address: { 314: '0x0000000000000000000000000000000000000000' as Address, - 314159: '0x87EDE87cEF4BfeFE0374c3470cB3F5be18b739d5' as Address, + 314159: '0x0295Ac959317391656fB7fFaA046046eF9C7E18F' as Address, }, }, { name: 'PDPVerifier', address: { 314: '0x0000000000000000000000000000000000000000' as Address, - 314159: '0x445238Eca6c6aB8Dff1Aa6087d9c05734D22f137' as Address, + 314159: '0x06279D540BDCd6CA33B073cEAeA1425B6C68c93d' as Address, }, }, { name: 'ServiceProviderRegistry', address: { 314: '0x0000000000000000000000000000000000000000' as Address, - 314159: '0xA8a7e2130C27e4f39D1aEBb3D538D5937bCf8ddb' as Address, + 314159: '0xc758dB755f59189d8FB3C166Ee372b77d7CFA9D3' as Address, }, }, { @@ -54,13 +66,11 @@ const config: ReturnType = defineConfig(() => { plugins: [ fetch({ contracts, + cacheDuration: 100, request(contract) { - const baseUrl = - 'https://raw.githubusercontent.com/FilOzone/filecoin-services/refs/tags/alpha/calibnet/0x80617b65FD2EEa1D7fDe2B4F85977670690ed348-v2/service_contracts/abi' - return { - url: `${baseUrl}/${contract.name}.abi.json`, + url: `${URL}/${contract.name}.abi.json`, } }, }), diff --git a/packages/synapse-react/package.json b/packages/synapse-react/package.json index 8d1ceb67..707b1e91 100644 --- a/packages/synapse-react/package.json +++ b/packages/synapse-react/package.json @@ -51,6 +51,9 @@ ], "output": [ "dist/**" + ], + "dependencies": [ + "../../packages/synapse-core:build" ] }, "lint": { diff --git a/packages/synapse-react/src/warm-storage/index.ts b/packages/synapse-react/src/warm-storage/index.ts index 313a8a56..afe8eab1 100644 --- a/packages/synapse-react/src/warm-storage/index.ts +++ b/packages/synapse-react/src/warm-storage/index.ts @@ -1,5 +1,6 @@ export * from './use-create-data-set.ts' export * from './use-data-sets.ts' +export * from './use-delete-piece.ts' export * from './use-providers.ts' export * from './use-service-price.ts' export * from './use-upload.ts' diff --git a/packages/synapse-react/src/warm-storage/use-create-data-set.ts b/packages/synapse-react/src/warm-storage/use-create-data-set.ts index 88bdd7c3..fd11b683 100644 --- a/packages/synapse-react/src/warm-storage/use-create-data-set.ts +++ b/packages/synapse-react/src/warm-storage/use-create-data-set.ts @@ -1,5 +1,5 @@ -import type { DataSetCreatedResponse } from '@filoz/synapse-core/curio' -import * as Curio from '@filoz/synapse-core/curio' +import type { DataSetCreatedResponse } from '@filoz/synapse-core/sp' +import * as SP from '@filoz/synapse-core/sp' import type { PDPProvider } from '@filoz/synapse-core/warm-storage' import { createDataSet } from '@filoz/synapse-core/warm-storage' import { type MutateOptions, useMutation, useQueryClient } from '@tanstack/react-query' @@ -37,8 +37,7 @@ export function useCreateDataSet(props: UseCreateDataSetProps) { chainId, }) - const { hash, statusUrl } = await createDataSet(connectorClient, { - publicClient: config.getClient(), + const { txHash, statusUrl } = await createDataSet(connectorClient, { provider, cdn, // metadata: { @@ -46,9 +45,9 @@ export function useCreateDataSet(props: UseCreateDataSetProps) { // description: 'Test Description', // }, }) - props?.onHash?.(hash) + props?.onHash?.(txHash) - const dataSet = await Curio.pollForDataSetCreationStatus({ statusUrl }) + const dataSet = await SP.pollForDataSetCreationStatus({ statusUrl }) queryClient.invalidateQueries({ queryKey: ['synapse-warm-storage-data-sets', account.address], diff --git a/packages/synapse-react/src/warm-storage/use-data-sets.ts b/packages/synapse-react/src/warm-storage/use-data-sets.ts index 9b1934f3..d15ef295 100644 --- a/packages/synapse-react/src/warm-storage/use-data-sets.ts +++ b/packages/synapse-react/src/warm-storage/use-data-sets.ts @@ -1,16 +1,13 @@ import { type MetadataObject, metadataArrayToObject } from '@filoz/synapse-core' import { getChain } from '@filoz/synapse-core/chains' -import type { CurioPieceWithUrl } from '@filoz/synapse-core/curio' -import * as PDP from '@filoz/synapse-core/curio' -import { type DataSet, getDataSets, readProviders } from '@filoz/synapse-core/warm-storage' +import { type DataSet, getDataSets, getPieces, type Piece } from '@filoz/synapse-core/warm-storage' import { skipToken, type UseQueryOptions, useQuery } from '@tanstack/react-query' import type { Simplify } from 'type-fest' import type { Address } from 'viem' import { readContract } from 'viem/actions' import { useChainId, useConfig } from 'wagmi' -import { useProviders } from './use-providers.ts' -export type PieceWithMetadata = Simplify +export type PieceWithMetadata = Simplify export interface DataSetWithPieces extends DataSet { pieces: PieceWithMetadata[] @@ -27,32 +24,26 @@ export function useDataSets(props: UseDataSetsProps) { const config = useConfig() const chainId = useChainId() const address = props.address - const { data: providersPrefected } = useProviders() const chain = getChain(chainId) return useQuery({ queryKey: ['synapse-warm-storage-data-sets', address], queryFn: address ? async () => { - const providers = providersPrefected ?? (await readProviders(config.getClient())) const dataSets = await getDataSets(config.getClient(), { address }) const dataSetsWithPieces = await Promise.all( dataSets.map(async (dataSet) => { - // TODO: Get the active pieces from the PDP contract instead of the Curio API - const pieces = await PDP.getPiecesForDataSet({ - endpoint: providers.find((p) => p.providerId === dataSet.providerId)?.pdp.serviceURL || '', - dataSetId: dataSet.pdpDatasetId, - chainId, + const piecesPaginated = await getPieces(config.getClient(), { + dataSet, address, - cdn: dataSet.cdn, }) const piecesWithMetadata = await Promise.all( - pieces.map(async (piece) => { + piecesPaginated.pieces.map(async (piece) => { const metadata = await readContract(config.getClient(), { address: chain.contracts.storageView.address, abi: chain.contracts.storageView.abi, functionName: 'getAllPieceMetadata', - args: [dataSet.pdpDatasetId, BigInt(piece.pieceId)], + args: [dataSet.dataSetId, BigInt(piece.id)], }) return { ...piece, diff --git a/packages/synapse-react/src/warm-storage/use-delete-piece.ts b/packages/synapse-react/src/warm-storage/use-delete-piece.ts new file mode 100644 index 00000000..a37c68ce --- /dev/null +++ b/packages/synapse-react/src/warm-storage/use-delete-piece.ts @@ -0,0 +1,56 @@ +import { getChain } from '@filoz/synapse-core/chains' +import type { SessionKey } from '@filoz/synapse-core/session-key' +import { type DataSet, deletePiece, pollForDeletePieceStatus } from '@filoz/synapse-core/warm-storage' +import { type MutateOptions, useMutation, useQueryClient } from '@tanstack/react-query' +import type { TransactionReceipt } from 'viem' +import { useAccount, useChainId, useConfig } from 'wagmi' +import { getConnectorClient } from 'wagmi/actions' + +export interface UseDeletePieceProps { + /** + * The callback to call when the hash is available. + */ + onHash?: (hash: string) => void + sessionKey?: SessionKey + mutation?: Omit, 'mutationFn'> +} + +export interface UseDeletePieceVariables { + dataSet: DataSet + pieceId: bigint +} +export function useDeletePiece(props: UseDeletePieceProps) { + const config = useConfig() + const chainId = useChainId({ config }) + const chain = getChain(chainId) + const account = useAccount({ config }) + const queryClient = useQueryClient() + const client = config.getClient() + + return useMutation({ + ...props?.mutation, + mutationFn: async ({ dataSet, pieceId }: UseDeletePieceVariables) => { + let connectorClient = await getConnectorClient(config, { + account: account.address, + chainId, + }) + + if (props?.sessionKey && (await props?.sessionKey.isValid(connectorClient, 'SchedulePieceRemovals'))) { + connectorClient = props?.sessionKey.client(chain, client.transport) + } + + const deletePieceRsp = await deletePiece(connectorClient, { + dataSet, + pieceId, + }) + + props?.onHash?.(deletePieceRsp.txHash) + const rsp = await pollForDeletePieceStatus(client, deletePieceRsp) + + queryClient.invalidateQueries({ + queryKey: ['synapse-warm-storage-data-sets', account.address], + }) + return rsp + }, + }) +} diff --git a/packages/synapse-react/src/warm-storage/use-upload.ts b/packages/synapse-react/src/warm-storage/use-upload.ts index 8ce4e136..19a472a7 100644 --- a/packages/synapse-react/src/warm-storage/use-upload.ts +++ b/packages/synapse-react/src/warm-storage/use-upload.ts @@ -1,7 +1,7 @@ import { getChain } from '@filoz/synapse-core/chains' -import type { AddPiecesSuccess } from '@filoz/synapse-core/curio' -import * as Curio from '@filoz/synapse-core/curio' import type { SessionKey } from '@filoz/synapse-core/session-key' +import type { AddPiecesSuccess } from '@filoz/synapse-core/sp' +import * as SP from '@filoz/synapse-core/sp' import { upload } from '@filoz/synapse-core/warm-storage' import { type MutateOptions, useMutation, useQueryClient } from '@tanstack/react-query' import { useAccount, useChainId, useConfig } from 'wagmi' @@ -12,13 +12,13 @@ export interface UseUploadProps { * The callback to call when the hash is available. */ onHash?: (hash: string) => void + sessionKey?: SessionKey mutation?: Omit, 'mutationFn'> } export interface UseUploadVariables { files: File[] dataSetId: bigint - sessionKey?: SessionKey } export function useUpload(props: UseUploadProps) { const config = useConfig() @@ -30,24 +30,22 @@ export function useUpload(props: UseUploadProps) { return useMutation({ ...props?.mutation, - mutationFn: async ({ files, dataSetId, sessionKey }: UseUploadVariables) => { + mutationFn: async ({ files, dataSetId }: UseUploadVariables) => { let connectorClient = await getConnectorClient(config, { account: account.address, chainId, }) - if (sessionKey && (await sessionKey.isValid(connectorClient, 'AddPieces'))) { - connectorClient = sessionKey.client(chain, client.transport) + if (props?.sessionKey && (await props?.sessionKey.isValid(connectorClient, 'AddPieces'))) { + connectorClient = props?.sessionKey.client(chain, client.transport) } - const pieces = await upload(connectorClient, { + const uploadRsp = await upload(connectorClient, { dataSetId, data: files, }) - props?.onHash?.(pieces.txHash) - const rsp = await Curio.pollForAddPiecesStatus({ - statusUrl: pieces.statusUrl, - }) + props?.onHash?.(uploadRsp.txHash) + const rsp = await SP.pollForAddPiecesStatus(uploadRsp) queryClient.invalidateQueries({ queryKey: ['synapse-warm-storage-data-sets', account.address], diff --git a/packages/synapse-sdk/package.json b/packages/synapse-sdk/package.json index d3ab0af7..70cd8df8 100644 --- a/packages/synapse-sdk/package.json +++ b/packages/synapse-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@filoz/synapse-sdk", - "version": "0.34.0", + "version": "0.35.0-dev.1", "description": "JavaScript SDK for Filecoin Onchain Cloud", "repository": { "type": "git", @@ -54,16 +54,71 @@ }, "scripts": { "generate-abi": "wagmi generate", - "build": "tsc --build", - "lint": "tsc --build && biome check --no-errors-on-unmatched --files-ignore-unknown=true .", + "build": "wireit", + "lint": "wireit", "lint:fix": "biome check --no-errors-on-unmatched --files-ignore-unknown=true --fix .", - "test": "pnpm run lint && pnpm run test:node", - "test:node": "playwright-test 'src/test/**/!(*.browser).test.ts' --mode node", - "test:browser": "playwright-test 'src/test/**/!(*.node).test.ts' --assets ./src/test/mocks", + "test": "wireit", + "test:node": "wireit", + "test:browser": "wireit", "clean": "rm -rf dist", "prepublishOnly": "pnpm run clean && pnpm run build" }, + "wireit": { + "build": { + "command": "tsc --build --pretty", + "clean": "if-file-deleted", + "files": [ + "src/**/*.ts", + "tsconfig.json" + ], + "output": [ + "dist/**" + ] + }, + "lint": { + "command": "biome check --no-errors-on-unmatched --files-ignore-unknown=true .", + "files": [ + "src/**/*.ts", + "../../biome.json" + ], + "output": [], + "dependencies": [ + "build" + ] + }, + "test": { + "command": "pnpm run test:node && pnpm run test:browser", + "files": [ + "src/**/*.ts" + ], + "output": [], + "dependencies": [ + "lint" + ] + }, + "test:node": { + "command": "playwright-test \"src/test/**/*.test.ts\" --mode node", + "files": [ + "src/**/*.ts" + ], + "output": [], + "dependencies": [ + "../synapse-core:build" + ] + }, + "test:browser": { + "command": "playwright-test \"src/test/**/*.test.ts\" --assets ./src/test/mocks", + "files": [ + "src/**/*.ts" + ], + "output": [], + "dependencies": [ + "../synapse-core:build" + ] + } + }, "dependencies": { + "@filoz/synapse-core": "workspace:^", "@web3-storage/data-segment": "^5.3.0", "ethers": "^6.15.0", "multiformats": "^13.4.1", @@ -78,7 +133,7 @@ "@wagmi/cli": "^2.7.0", "abitype": "^1.1.1", "chai": "^6.2.0", - "iso-web": "^1.4.0", + "iso-web": "^1.4.2", "mocha": "^11.7.4", "msw": "~2.10.5", "p-defer": "^4.0.1", diff --git a/packages/synapse-sdk/src/abis/gen.ts b/packages/synapse-sdk/src/abis/gen.ts index 842a5882..07ebc0fb 100644 --- a/packages/synapse-sdk/src/abis/gen.ts +++ b/packages/synapse-sdk/src/abis/gen.ts @@ -16,9 +16,13 @@ export const filecoinWarmStorageServiceAbi = [ internalType: 'address', type: 'address', }, - { name: '_usdfcTokenAddress', internalType: 'address', type: 'address' }, { - name: '_filCDNBeneficiaryAddress', + name: '_usdfc', + internalType: 'contract IERC20Metadata', + type: 'address', + }, + { + name: '_filBeamBeneficiaryAddress', internalType: 'address', type: 'address', }, @@ -56,6 +60,27 @@ export const filecoinWarmStorageServiceAbi = [ outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [ + { + name: 'plannedUpgrade', + internalType: 'struct FilecoinWarmStorageService.PlannedUpgrade', + type: 'tuple', + components: [ + { + name: 'nextImplementation', + internalType: 'address', + type: 'address', + }, + { name: 'afterEpoch', internalType: 'uint96', type: 'uint96' }, + ], + }, + ], + name: 'announcePlannedUpgrade', + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', inputs: [{ name: 'totalBytes', internalType: 'uint256', type: 'uint256' }], @@ -97,7 +122,7 @@ export const filecoinWarmStorageServiceAbi = [ inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, { name: '', internalType: 'uint256', type: 'uint256' }, - { name: 'extraData', internalType: 'bytes', type: 'bytes' }, + { name: '', internalType: 'bytes', type: 'bytes' }, ], name: 'dataSetDeleted', outputs: [], @@ -138,7 +163,7 @@ export const filecoinWarmStorageServiceAbi = [ { type: 'function', inputs: [], - name: 'filCDNBeneficiaryAddress', + name: 'filBeamBeneficiaryAddress', outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, @@ -182,7 +207,11 @@ export const filecoinWarmStorageServiceAbi = [ internalType: 'uint256', type: 'uint256', }, - { name: 'tokenAddress', internalType: 'address', type: 'address' }, + { + name: 'tokenAddress', + internalType: 'contract IERC20', + type: 'address', + }, { name: 'epochsPerMonth', internalType: 'uint256', type: 'uint256' }, ], }, @@ -199,7 +228,7 @@ export const filecoinWarmStorageServiceAbi = [ type: 'uint256', }, { - name: '_filCDNControllerAddress', + name: '_filBeamControllerAddress', internalType: 'address', type: 'address', }, @@ -337,13 +366,6 @@ export const filecoinWarmStorageServiceAbi = [ outputs: [], stateMutability: 'nonpayable', }, - { - type: 'function', - inputs: [], - name: 'serviceCommissionBps', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, { type: 'function', inputs: [], @@ -383,8 +405,19 @@ export const filecoinWarmStorageServiceAbi = [ type: 'function', inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, - { name: 'oldServiceProvider', internalType: 'address', type: 'address' }, - { name: 'newServiceProvider', internalType: 'address', type: 'address' }, + { name: 'cdnAmount', internalType: 'uint256', type: 'uint256' }, + { name: 'cacheMissAmount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'settleFilBeamPaymentRails', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: '', internalType: 'uint256', type: 'uint256' }, + { name: '', internalType: 'address', type: 'address' }, + { name: '', internalType: 'address', type: 'address' }, { name: '', internalType: 'bytes', type: 'bytes' }, ], name: 'storageProviderChanged', @@ -405,12 +438,27 @@ export const filecoinWarmStorageServiceAbi = [ outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'cdnAmountToAdd', internalType: 'uint256', type: 'uint256' }, + { + name: 'cacheMissAmountToAdd', + internalType: 'uint256', + type: 'uint256', + }, + ], + name: 'topUpCDNPaymentRails', + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', inputs: [ { name: 'newController', internalType: 'address', type: 'address' }, ], - name: 'transferFilCDNController', + name: 'transferFilBeamController', outputs: [], stateMutability: 'nonpayable', }, @@ -444,7 +492,9 @@ export const filecoinWarmStorageServiceAbi = [ type: 'function', inputs: [], name: 'usdfcTokenAddress', - outputs: [{ name: '', internalType: 'address', type: 'address' }], + outputs: [ + { name: '', internalType: 'contract IERC20Metadata', type: 'address' }, + ], stateMutability: 'view', }, { @@ -469,7 +519,7 @@ export const filecoinWarmStorageServiceAbi = [ ], }, ], - stateMutability: 'nonpayable', + stateMutability: 'view', }, { type: 'function', @@ -478,6 +528,43 @@ export const filecoinWarmStorageServiceAbi = [ outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'dataSetId', + internalType: 'uint256', + type: 'uint256', + indexed: true, + }, + { + name: 'cdnAmountAdded', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'totalCdnLockup', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'cacheMissAmountAdded', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'totalCacheMissLockup', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'CDNPaymentRailsToppedUp', + }, { type: 'event', anonymous: false, @@ -694,7 +781,7 @@ export const filecoinWarmStorageServiceAbi = [ indexed: false, }, ], - name: 'FilCDNControllerChanged', + name: 'FilBeamControllerChanged', }, { type: 'event', @@ -767,43 +854,6 @@ export const filecoinWarmStorageServiceAbi = [ ], name: 'PDPPaymentTerminated', }, - { - type: 'event', - anonymous: false, - inputs: [ - { - name: 'railId', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'dataSetId', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'originalAmount', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'modifiedAmount', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - { - name: 'faultedEpochs', - internalType: 'uint256', - type: 'uint256', - indexed: false, - }, - ], - name: 'PaymentArbitrated', - }, { type: 'event', anonymous: false, @@ -930,6 +980,27 @@ export const filecoinWarmStorageServiceAbi = [ ], name: 'ServiceTerminated', }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'plannedUpgrade', + internalType: 'struct FilecoinWarmStorageService.PlannedUpgrade', + type: 'tuple', + components: [ + { + name: 'nextImplementation', + internalType: 'address', + type: 'address', + }, + { name: 'afterEpoch', internalType: 'uint96', type: 'uint96' }, + ], + indexed: false, + }, + ], + name: 'UpgradeAnnounced', + }, { type: 'event', anonymous: false, @@ -961,6 +1032,25 @@ export const filecoinWarmStorageServiceAbi = [ inputs: [{ name: 'target', internalType: 'address', type: 'address' }], name: 'AddressEmptyCode', }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'CDNPaymentAlreadyTerminated', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'CacheMissPaymentAlreadyTerminated', + }, + { + type: 'error', + inputs: [ + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, + { name: 'expectedPayer', internalType: 'address', type: 'address' }, + { name: 'caller', internalType: 'address', type: 'address' }, + ], + name: 'CallerNotPayer', + }, { type: 'error', inputs: [ @@ -988,6 +1078,13 @@ export const filecoinWarmStorageServiceAbi = [ ], name: 'ChallengeWindowTooEarly', }, + { + type: 'error', + inputs: [ + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'ClientDataSetAlreadyRegistered', + }, { type: 'error', inputs: [ @@ -1047,12 +1144,7 @@ export const filecoinWarmStorageServiceAbi = [ { type: 'error', inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'FilCDNPaymentAlreadyTerminated', - }, - { - type: 'error', - inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], - name: 'FilCDNServiceNotConfigured', + name: 'FilBeamServiceNotConfigured', }, { type: 'error', @@ -1097,19 +1189,18 @@ export const filecoinWarmStorageServiceAbi = [ { type: 'error', inputs: [], name: 'InvalidInitialization' }, { type: 'error', - inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, - ], - name: 'InvalidSignature', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidServiceDescriptionLength', }, { type: 'error', - inputs: [ - { name: 'expectedLength', internalType: 'uint256', type: 'uint256' }, - { name: 'actualLength', internalType: 'uint256', type: 'uint256' }, - ], - name: 'InvalidSignatureLength', + inputs: [{ name: 'length', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidServiceNameLength', + }, + { + type: 'error', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'InvalidTopUpAmount', }, { type: 'error', inputs: [], name: 'MaxProvingPeriodZero' }, { @@ -1164,19 +1255,10 @@ export const filecoinWarmStorageServiceAbi = [ { type: 'error', inputs: [ - { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, { name: 'expected', internalType: 'address', type: 'address' }, { name: 'actual', internalType: 'address', type: 'address' }, ], - name: 'OldServiceProviderMismatch', - }, - { - type: 'error', - inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, - ], - name: 'OnlyFilCDNControllerAllowed', + name: 'OnlyFilBeamControllerAllowed', }, { type: 'error', @@ -1186,14 +1268,6 @@ export const filecoinWarmStorageServiceAbi = [ ], name: 'OnlyPDPVerifierAllowed', }, - { - type: 'error', - inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, - ], - name: 'OnlySelf', - }, { type: 'error', inputs: [{ name: 'owner', internalType: 'address', type: 'address' }], @@ -1209,7 +1283,6 @@ export const filecoinWarmStorageServiceAbi = [ inputs: [ { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnEndEpoch', internalType: 'uint256', type: 'uint256' }, ], name: 'PaymentRailsNotFinalized', }, @@ -1223,14 +1296,6 @@ export const filecoinWarmStorageServiceAbi = [ inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], name: 'ProviderAlreadyApproved', }, - { - type: 'error', - inputs: [ - { name: 'provider', internalType: 'address', type: 'address' }, - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, - ], - name: 'ProviderNotApproved', - }, { type: 'error', inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], @@ -1275,11 +1340,6 @@ export const filecoinWarmStorageServiceAbi = [ inputs: [{ name: 'slot', internalType: 'bytes32', type: 'bytes32' }], name: 'UUPSUnsupportedProxiableUUID', }, - { - type: 'error', - inputs: [{ name: 'v', internalType: 'uint8', type: 'uint8' }], - name: 'UnsupportedSignatureV', - }, { type: 'error', inputs: [ @@ -1340,8 +1400,11 @@ export const filecoinWarmStorageServiceStateViewAbi = [ }, { type: 'function', - inputs: [{ name: 'payer', internalType: 'address', type: 'address' }], - name: 'clientDataSetIDs', + inputs: [ + { name: 'payer', internalType: 'address', type: 'address' }, + { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, + ], + name: 'clientDataSetIds', outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, @@ -1357,7 +1420,7 @@ export const filecoinWarmStorageServiceStateViewAbi = [ { type: 'function', inputs: [], - name: 'filCDNControllerAddress', + name: 'filBeamControllerAddress', outputs: [{ name: '', internalType: 'address', type: 'address' }], stateMutability: 'view', }, @@ -1386,13 +1449,23 @@ export const filecoinWarmStorageServiceStateViewAbi = [ }, { type: 'function', - inputs: [], + inputs: [ + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, + ], name: 'getApprovedProviders', outputs: [ { name: 'providerIds', internalType: 'uint256[]', type: 'uint256[]' }, ], stateMutability: 'view', }, + { + type: 'function', + inputs: [], + name: 'getApprovedProvidersLength', + outputs: [{ name: 'count', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, { type: 'function', inputs: [], @@ -1407,7 +1480,7 @@ export const filecoinWarmStorageServiceStateViewAbi = [ outputs: [ { name: 'infos', - internalType: 'struct FilecoinWarmStorageService.DataSetInfo[]', + internalType: 'struct FilecoinWarmStorageService.DataSetInfoView[]', type: 'tuple[]', components: [ { name: 'pdpRailId', internalType: 'uint256', type: 'uint256' }, @@ -1420,7 +1493,7 @@ export const filecoinWarmStorageServiceStateViewAbi = [ { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, { name: 'providerId', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, ], }, ], @@ -1433,7 +1506,7 @@ export const filecoinWarmStorageServiceStateViewAbi = [ outputs: [ { name: 'info', - internalType: 'struct FilecoinWarmStorageService.DataSetInfo', + internalType: 'struct FilecoinWarmStorageService.DataSetInfoView', type: 'tuple', components: [ { name: 'pdpRailId', internalType: 'uint256', type: 'uint256' }, @@ -1446,7 +1519,7 @@ export const filecoinWarmStorageServiceStateViewAbi = [ { name: 'clientDataSetId', internalType: 'uint256', type: 'uint256' }, { name: 'pdpEndEpoch', internalType: 'uint256', type: 'uint256' }, { name: 'providerId', internalType: 'uint256', type: 'uint256' }, - { name: 'cdnEndEpoch', internalType: 'uint256', type: 'uint256' }, + { name: 'dataSetId', internalType: 'uint256', type: 'uint256' }, ], }, ], @@ -1472,6 +1545,19 @@ export const filecoinWarmStorageServiceStateViewAbi = [ outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'pure', }, + { + type: 'function', + inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], + name: 'getDataSetStatus', + outputs: [ + { + name: 'status', + internalType: 'enum FilecoinWarmStorageService.DataSetStatus', + type: 'uint8', + }, + ], + stateMutability: 'view', + }, { type: 'function', inputs: [], @@ -1523,6 +1609,16 @@ export const filecoinWarmStorageServiceStateViewAbi = [ outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, + { + type: 'function', + inputs: [], + name: 'nextUpgrade', + outputs: [ + { name: 'nextImplementation', internalType: 'address', type: 'address' }, + { name: 'afterEpoch', internalType: 'uint96', type: 'uint96' }, + ], + stateMutability: 'view', + }, { type: 'function', inputs: [ @@ -1574,6 +1670,13 @@ export const filecoinWarmStorageServiceStateViewAbi = [ ], stateMutability: 'view', }, + { + type: 'function', + inputs: [], + name: 'serviceCommissionBps', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, { type: 'error', inputs: [{ name: 'dataSetId', internalType: 'uint256', type: 'uint256' }], @@ -1609,34 +1712,6 @@ export const filecoinWarmStorageServiceStateViewConfig = { */ export const pdpVerifierAbi = [ { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, - { - type: 'function', - inputs: [], - name: 'BURN_ACTOR', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'EXTRA_DATA_MAX_SIZE', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'FIL_USD_PRICE_FEED_ID', - outputs: [{ name: '', internalType: 'bytes32', type: 'bytes32' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'LEAF_SIZE', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, { type: 'function', inputs: [], @@ -1665,27 +1740,6 @@ export const pdpVerifierAbi = [ outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, - { - type: 'function', - inputs: [], - name: 'PYTH', - outputs: [{ name: '', internalType: 'contract IPyth', type: 'address' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'RANDOMNESS_PRECOMPILE', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, - { - type: 'function', - inputs: [], - name: 'SECONDS_IN_DAY', - outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'view', - }, { type: 'function', inputs: [], @@ -1704,6 +1758,7 @@ export const pdpVerifierAbi = [ type: 'function', inputs: [ { name: 'setId', internalType: 'uint256', type: 'uint256' }, + { name: 'listenerAddr', internalType: 'address', type: 'address' }, { name: 'pieceData', internalType: 'struct Cids.Cid[]', @@ -1714,18 +1769,22 @@ export const pdpVerifierAbi = [ ], name: 'addPieces', outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], - stateMutability: 'nonpayable', + stateMutability: 'payable', }, { type: 'function', - inputs: [ - { name: 'setId', internalType: 'uint256', type: 'uint256' }, - { name: 'estimatedGasFee', internalType: 'uint256', type: 'uint256' }, - ], + inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], name: 'calculateProofFee', outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, + { + type: 'function', + inputs: [{ name: 'proofSize', internalType: 'uint256', type: 'uint256' }], + name: 'calculateProofFeeForSize', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, { type: 'function', inputs: [ @@ -1763,6 +1822,20 @@ export const pdpVerifierAbi = [ outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [], + name: 'feeEffectiveTime', + outputs: [{ name: '', internalType: 'uint64', type: 'uint64' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'feePerTiB', + outputs: [{ name: '', internalType: 'uint96', type: 'uint96' }], + stateMutability: 'view', + }, { type: 'function', inputs: [ @@ -1808,7 +1881,6 @@ export const pdpVerifierAbi = [ components: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], }, { name: 'pieceIds', internalType: 'uint256[]', type: 'uint256[]' }, - { name: 'rawSizes', internalType: 'uint256[]', type: 'uint256[]' }, { name: 'hasMore', internalType: 'bool', type: 'bool' }, ], stateMutability: 'view', @@ -1858,16 +1930,6 @@ export const pdpVerifierAbi = [ ], stateMutability: 'view', }, - { - type: 'function', - inputs: [], - name: 'getFILUSDPrice', - outputs: [ - { name: '', internalType: 'uint64', type: 'uint64' }, - { name: '', internalType: 'int32', type: 'int32' }, - ], - stateMutability: 'view', - }, { type: 'function', inputs: [{ name: 'setId', internalType: 'uint256', type: 'uint256' }], @@ -1994,6 +2056,13 @@ export const pdpVerifierAbi = [ outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [], + name: 'proposedFeePerTiB', + outputs: [{ name: '', internalType: 'uint96', type: 'uint96' }], + stateMutability: 'view', + }, { type: 'function', inputs: [ @@ -2044,6 +2113,15 @@ export const pdpVerifierAbi = [ outputs: [], stateMutability: 'nonpayable', }, + { + type: 'function', + inputs: [ + { name: 'newFeePerTiB', internalType: 'uint256', type: 'uint256' }, + ], + name: 'updateProofFee', + outputs: [], + stateMutability: 'nonpayable', + }, { type: 'function', inputs: [ @@ -2124,6 +2202,31 @@ export const pdpVerifierAbi = [ ], name: 'DataSetEmpty', }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'currentFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'newFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'effectiveTime', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + ], + name: 'FeeUpdateProposed', + }, { type: 'event', anonymous: false, @@ -2260,8 +2363,6 @@ export const pdpVerifierAbi = [ indexed: true, }, { name: 'fee', internalType: 'uint256', type: 'uint256', indexed: false }, - { name: 'price', internalType: 'uint64', type: 'uint64', indexed: false }, - { name: 'expo', internalType: 'int32', type: 'int32', indexed: false }, ], name: 'ProofFeePaid', }, @@ -2383,15 +2484,22 @@ export const paymentsAbi = [ { type: 'function', inputs: [], - name: 'NETWORK_FEE', + name: 'NETWORK_FEE_DENOMINATOR', + outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [], + name: 'NETWORK_FEE_NUMERATOR', outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, { type: 'function', inputs: [ - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'owner', internalType: 'address', type: 'address' }, ], name: 'accounts', outputs: [ @@ -2405,7 +2513,30 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + ], + name: 'auctionInfo', + outputs: [ + { name: 'startPrice', internalType: 'uint88', type: 'uint88' }, + { name: 'startTime', internalType: 'uint168', type: 'uint168' }, + ], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'recipient', internalType: 'address', type: 'address' }, + { name: 'requested', internalType: 'uint256', type: 'uint256' }, + ], + name: 'burnForFees', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'validator', internalType: 'address', type: 'address' }, @@ -2419,18 +2550,84 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + ], + name: 'deposit', + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC3009', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'validAfter', internalType: 'uint256', type: 'uint256' }, + { name: 'validBefore', internalType: 'uint256', type: 'uint256' }, + { name: 'nonce', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + ], + name: 'depositWithAuthorization', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC3009', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'validAfter', internalType: 'uint256', type: 'uint256' }, + { name: 'validBefore', internalType: 'uint256', type: 'uint256' }, + { name: 'nonce', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'lockupAllowance', internalType: 'uint256', type: 'uint256' }, + { name: 'maxLockupPeriod', internalType: 'uint256', type: 'uint256' }, + ], + name: 'depositWithAuthorizationAndApproveOperator', + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + inputs: [ + { name: 'token', internalType: 'contract IERC3009', type: 'address' }, + { name: 'to', internalType: 'address', type: 'address' }, + { name: 'amount', internalType: 'uint256', type: 'uint256' }, + { name: 'validAfter', internalType: 'uint256', type: 'uint256' }, + { name: 'validBefore', internalType: 'uint256', type: 'uint256' }, + { name: 'nonce', internalType: 'bytes32', type: 'bytes32' }, + { name: 'v', internalType: 'uint8', type: 'uint8' }, + { name: 'r', internalType: 'bytes32', type: 'bytes32' }, + { name: 's', internalType: 'bytes32', type: 'bytes32' }, + { name: 'operator', internalType: 'address', type: 'address' }, + { + name: 'rateAllowanceIncrease', + internalType: 'uint256', + type: 'uint256', + }, + { + name: 'lockupAllowanceIncrease', + internalType: 'uint256', + type: 'uint256', + }, ], - name: 'deposit', + name: 'depositWithAuthorizationAndIncreaseOperatorApproval', outputs: [], - stateMutability: 'payable', + stateMutability: 'nonpayable', }, { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'amount', internalType: 'uint256', type: 'uint256' }, { name: 'deadline', internalType: 'uint256', type: 'uint256' }, @@ -2445,7 +2642,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'amount', internalType: 'uint256', type: 'uint256' }, { name: 'deadline', internalType: 'uint256', type: 'uint256' }, @@ -2464,7 +2661,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'amount', internalType: 'uint256', type: 'uint256' }, { name: 'deadline', internalType: 'uint256', type: 'uint256' }, @@ -2490,7 +2687,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'owner', internalType: 'address', type: 'address' }, ], name: 'getAccountInfoIfSettled', @@ -2512,7 +2709,7 @@ export const paymentsAbi = [ internalType: 'struct Payments.RailView', type: 'tuple', components: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'operator', internalType: 'address', type: 'address' }, @@ -2541,12 +2738,14 @@ export const paymentsAbi = [ type: 'function', inputs: [ { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, ], name: 'getRailsForPayeeAndToken', outputs: [ { - name: '', + name: 'results', internalType: 'struct Payments.RailInfo[]', type: 'tuple[]', components: [ @@ -2555,6 +2754,8 @@ export const paymentsAbi = [ { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, ], }, + { name: 'nextOffset', internalType: 'uint256', type: 'uint256' }, + { name: 'total', internalType: 'uint256', type: 'uint256' }, ], stateMutability: 'view', }, @@ -2562,12 +2763,14 @@ export const paymentsAbi = [ type: 'function', inputs: [ { name: 'payer', internalType: 'address', type: 'address' }, - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'offset', internalType: 'uint256', type: 'uint256' }, + { name: 'limit', internalType: 'uint256', type: 'uint256' }, ], name: 'getRailsForPayerAndToken', outputs: [ { - name: '', + name: 'results', internalType: 'struct Payments.RailInfo[]', type: 'tuple[]', components: [ @@ -2576,6 +2779,8 @@ export const paymentsAbi = [ { name: 'endEpoch', internalType: 'uint256', type: 'uint256' }, ], }, + { name: 'nextOffset', internalType: 'uint256', type: 'uint256' }, + { name: 'total', internalType: 'uint256', type: 'uint256' }, ], stateMutability: 'view', }, @@ -2589,7 +2794,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'operator', internalType: 'address', type: 'address' }, { name: 'rateAllowanceIncrease', @@ -2631,9 +2836,9 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, - { name: '', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'client', internalType: 'address', type: 'address' }, + { name: 'operator', internalType: 'address', type: 'address' }, ], name: 'operatorApprovals', outputs: [ @@ -2649,7 +2854,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'operator', internalType: 'address', type: 'address' }, { name: 'approved', internalType: 'bool', type: 'bool' }, { name: 'rateAllowance', internalType: 'uint256', type: 'uint256' }, @@ -2675,10 +2880,11 @@ export const paymentsAbi = [ internalType: 'uint256', type: 'uint256', }, + { name: 'totalNetworkFee', internalType: 'uint256', type: 'uint256' }, { name: 'finalSettledEpoch', internalType: 'uint256', type: 'uint256' }, { name: 'note', internalType: 'string', type: 'string' }, ], - stateMutability: 'payable', + stateMutability: 'nonpayable', }, { type: 'function', @@ -2692,6 +2898,7 @@ export const paymentsAbi = [ internalType: 'uint256', type: 'uint256', }, + { name: 'totalNetworkFee', internalType: 'uint256', type: 'uint256' }, { name: 'finalSettledEpoch', internalType: 'uint256', type: 'uint256' }, { name: 'note', internalType: 'string', type: 'string' }, ], @@ -2707,7 +2914,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'amount', internalType: 'uint256', type: 'uint256' }, ], name: 'withdraw', @@ -2717,7 +2924,7 @@ export const paymentsAbi = [ { type: 'function', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'to', internalType: 'address', type: 'address' }, { name: 'amount', internalType: 'uint256', type: 'uint256' }, ], @@ -2731,7 +2938,7 @@ export const paymentsAbi = [ inputs: [ { name: 'token', - internalType: 'address', + internalType: 'contract IERC20', type: 'address', indexed: true, }, @@ -2768,7 +2975,7 @@ export const paymentsAbi = [ inputs: [ { name: 'token', - internalType: 'address', + internalType: 'contract IERC20', type: 'address', indexed: true, }, @@ -2780,12 +2987,6 @@ export const paymentsAbi = [ type: 'uint256', indexed: false, }, - { - name: 'usedPermit', - internalType: 'bool', - type: 'bool', - indexed: false, - }, ], name: 'DepositRecorded', }, @@ -2795,7 +2996,7 @@ export const paymentsAbi = [ inputs: [ { name: 'token', - internalType: 'address', + internalType: 'contract IERC20', type: 'address', indexed: true, }, @@ -2857,7 +3058,7 @@ export const paymentsAbi = [ }, { name: 'token', - internalType: 'address', + internalType: 'contract IERC20', type: 'address', indexed: false, }, @@ -2960,6 +3161,12 @@ export const paymentsAbi = [ type: 'uint256', indexed: false, }, + { + name: 'networkFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, ], name: 'RailOneTimePaymentProcessed', }, @@ -3016,6 +3223,12 @@ export const paymentsAbi = [ type: 'uint256', indexed: false, }, + { + name: 'networkFee', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, { name: 'settledUpTo', internalType: 'uint256', @@ -3051,7 +3264,7 @@ export const paymentsAbi = [ inputs: [ { name: 'token', - internalType: 'address', + internalType: 'contract IERC20', type: 'address', indexed: true, }, @@ -3104,7 +3317,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'oldLockup', internalType: 'uint256', type: 'uint256' }, { name: 'currentLockup', internalType: 'uint256', type: 'uint256' }, @@ -3114,8 +3327,8 @@ export const paymentsAbi = [ { type: 'error', inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, - { name: 'token', internalType: 'address', type: 'address' }, { name: 'currentLockup', internalType: 'uint256', type: 'uint256' }, { name: 'lockupReduction', internalType: 'uint256', type: 'uint256' }, ], @@ -3124,7 +3337,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'required', internalType: 'uint256', type: 'uint256' }, { name: 'actual', internalType: 'uint256', type: 'uint256' }, @@ -3134,7 +3347,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'available', internalType: 'uint256', type: 'uint256' }, { name: 'required', internalType: 'uint256', type: 'uint256' }, @@ -3144,7 +3357,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'available', internalType: 'uint256', type: 'uint256' }, { name: 'required', internalType: 'uint256', type: 'uint256' }, @@ -3196,7 +3409,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'account', internalType: 'address', type: 'address' }, { name: 'lockupCurrent', internalType: 'uint256', type: 'uint256' }, { name: 'fundsCurrent', internalType: 'uint256', type: 'uint256' }, @@ -3206,7 +3419,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'actualLockupFixed', internalType: 'uint256', type: 'uint256' }, { @@ -3221,7 +3434,7 @@ export const paymentsAbi = [ type: 'error', inputs: [ { name: 'railId', internalType: 'uint256', type: 'uint256' }, - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'expectedLockup', internalType: 'uint256', type: 'uint256' }, { name: 'actualLockup', internalType: 'uint256', type: 'uint256' }, @@ -3242,7 +3455,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'from', internalType: 'address', type: 'address' }, { name: 'actualLockupPeriod', internalType: 'uint256', type: 'uint256' }, { @@ -3256,7 +3469,7 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'token', internalType: 'address', type: 'address' }, + { name: 'token', internalType: 'contract IERC20', type: 'address' }, { name: 'operator', internalType: 'address', type: 'address' }, { name: 'maxAllowedPeriod', internalType: 'uint256', type: 'uint256' }, { name: 'requestedPeriod', internalType: 'uint256', type: 'uint256' }, @@ -3350,16 +3563,6 @@ export const paymentsAbi = [ ], name: 'OnlyRailOperatorAllowed', }, - { - type: 'error', - inputs: [ - { name: 'expectedFrom', internalType: 'address', type: 'address' }, - { name: 'expectedOperator', internalType: 'address', type: 'address' }, - { name: 'expectedTo', internalType: 'address', type: 'address' }, - { name: 'caller', internalType: 'address', type: 'address' }, - ], - name: 'OnlyRailParticipantAllowed', - }, { type: 'error', inputs: [ @@ -3387,10 +3590,16 @@ export const paymentsAbi = [ { type: 'error', inputs: [ - { name: 'expected', internalType: 'address', type: 'address' }, - { name: 'actual', internalType: 'address', type: 'address' }, + { name: 'x', internalType: 'uint256', type: 'uint256' }, + { name: 'y', internalType: 'uint256', type: 'uint256' }, + { name: 'denominator', internalType: 'uint256', type: 'uint256' }, ], - name: 'PermitRecipientMustBeMsgSender', + name: 'PRBMath_MulDiv_Overflow', + }, + { + type: 'error', + inputs: [{ name: 'x', internalType: 'UD60x18', type: 'uint256' }], + name: 'PRBMath_UD60x18_Exp2_InputTooBig', }, { type: 'error', @@ -3425,6 +3634,14 @@ export const paymentsAbi = [ inputs: [{ name: 'token', internalType: 'address', type: 'address' }], name: 'SafeERC20FailedOperation', }, + { + type: 'error', + inputs: [ + { name: 'expected', internalType: 'address', type: 'address' }, + { name: 'actual', internalType: 'address', type: 'address' }, + ], + name: 'SignerMustBeMsgSender', + }, { type: 'error', inputs: [ @@ -3452,6 +3669,15 @@ export const paymentsAbi = [ ], name: 'ValidatorSettledBeyondSegmentEnd', }, + { + type: 'error', + inputs: [ + { name: 'token', internalType: 'contract IERC20', type: 'address' }, + { name: 'available', internalType: 'uint256', type: 'uint256' }, + { name: 'requested', internalType: 'uint256', type: 'uint256' }, + ], + name: 'WithdrawAmountExceedsAccumulatedFees', + }, { type: 'error', inputs: [{ name: 'varName', internalType: 'string', type: 'string' }], @@ -3487,13 +3713,6 @@ export const paymentsConfig = { */ export const serviceProviderRegistryAbi = [ { type: 'constructor', inputs: [], stateMutability: 'nonpayable' }, - { - type: 'function', - inputs: [], - name: 'BURN_ACTOR', - outputs: [{ name: '', internalType: 'address', type: 'address' }], - stateMutability: 'view', - }, { type: 'function', inputs: [], @@ -3581,50 +3800,6 @@ export const serviceProviderRegistryAbi = [ outputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, - { - type: 'function', - inputs: [{ name: 'data', internalType: 'bytes', type: 'bytes' }], - name: 'decodePDPOffering', - outputs: [ - { - name: '', - internalType: 'struct ServiceProviderRegistryStorage.PDPOffering', - type: 'tuple', - components: [ - { name: 'serviceURL', internalType: 'string', type: 'string' }, - { - name: 'minPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'maxPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'ipniPiece', internalType: 'bool', type: 'bool' }, - { name: 'ipniIpfs', internalType: 'bool', type: 'bool' }, - { - name: 'storagePricePerTibPerMonth', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'minProvingPeriodInEpochs', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'location', internalType: 'string', type: 'string' }, - { - name: 'paymentTokenAddress', - internalType: 'contract IERC20', - type: 'address', - }, - ], - }, - ], - stateMutability: 'pure', - }, { type: 'function', inputs: [], @@ -3640,50 +3815,6 @@ export const serviceProviderRegistryAbi = [ ], stateMutability: 'view', }, - { - type: 'function', - inputs: [ - { - name: 'pdpOffering', - internalType: 'struct ServiceProviderRegistryStorage.PDPOffering', - type: 'tuple', - components: [ - { name: 'serviceURL', internalType: 'string', type: 'string' }, - { - name: 'minPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'maxPieceSizeInBytes', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'ipniPiece', internalType: 'bool', type: 'bool' }, - { name: 'ipniIpfs', internalType: 'bool', type: 'bool' }, - { - name: 'storagePricePerTibPerMonth', - internalType: 'uint256', - type: 'uint256', - }, - { - name: 'minProvingPeriodInEpochs', - internalType: 'uint256', - type: 'uint256', - }, - { name: 'location', internalType: 'string', type: 'string' }, - { - name: 'paymentTokenAddress', - internalType: 'contract IERC20', - type: 'address', - }, - ], - }, - ], - name: 'encodePDPOffering', - outputs: [{ name: '', internalType: 'bytes', type: 'bytes' }], - stateMutability: 'pure', - }, { type: 'function', inputs: [ @@ -3729,11 +3860,6 @@ export const serviceProviderRegistryAbi = [ type: 'string', }, { name: 'isActive', internalType: 'bool', type: 'bool' }, - { - name: 'providerId', - internalType: 'uint256', - type: 'uint256', - }, ], }, { @@ -3892,16 +4018,27 @@ export const serviceProviderRegistryAbi = [ outputs: [ { name: 'info', - internalType: - 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + internalType: 'struct ServiceProviderRegistry.ServiceProviderInfoView', type: 'tuple', components: [ - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'name', internalType: 'string', type: 'string' }, - { name: 'description', internalType: 'string', type: 'string' }, - { name: 'isActive', internalType: 'bool', type: 'bool' }, { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { + name: 'info', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + type: 'tuple', + components: [ + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'description', internalType: 'string', type: 'string' }, + { name: 'isActive', internalType: 'bool', type: 'bool' }, + ], + }, ], }, ], @@ -3916,16 +4053,27 @@ export const serviceProviderRegistryAbi = [ outputs: [ { name: 'info', - internalType: - 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + internalType: 'struct ServiceProviderRegistry.ServiceProviderInfoView', type: 'tuple', components: [ - { name: 'serviceProvider', internalType: 'address', type: 'address' }, - { name: 'payee', internalType: 'address', type: 'address' }, - { name: 'name', internalType: 'string', type: 'string' }, - { name: 'description', internalType: 'string', type: 'string' }, - { name: 'isActive', internalType: 'bool', type: 'bool' }, { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { + name: 'info', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + type: 'tuple', + components: [ + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'description', internalType: 'string', type: 'string' }, + { name: 'isActive', internalType: 'bool', type: 'bool' }, + ], + }, ], }, ], @@ -3947,6 +4095,50 @@ export const serviceProviderRegistryAbi = [ outputs: [{ name: '', internalType: 'uint256', type: 'uint256' }], stateMutability: 'view', }, + { + type: 'function', + inputs: [{ name: 'providerId', internalType: 'uint256', type: 'uint256' }], + name: 'getProviderPayee', + outputs: [{ name: 'payee', internalType: 'address', type: 'address' }], + stateMutability: 'view', + }, + { + type: 'function', + inputs: [ + { name: 'providerIds', internalType: 'uint256[]', type: 'uint256[]' }, + ], + name: 'getProvidersByIds', + outputs: [ + { + name: 'providerInfos', + internalType: + 'struct ServiceProviderRegistry.ServiceProviderInfoView[]', + type: 'tuple[]', + components: [ + { name: 'providerId', internalType: 'uint256', type: 'uint256' }, + { + name: 'info', + internalType: + 'struct ServiceProviderRegistryStorage.ServiceProviderInfo', + type: 'tuple', + components: [ + { + name: 'serviceProvider', + internalType: 'address', + type: 'address', + }, + { name: 'payee', internalType: 'address', type: 'address' }, + { name: 'name', internalType: 'string', type: 'string' }, + { name: 'description', internalType: 'string', type: 'string' }, + { name: 'isActive', internalType: 'bool', type: 'bool' }, + ], + }, + ], + }, + { name: 'validIds', internalType: 'bool[]', type: 'bool[]' }, + ], + stateMutability: 'view', + }, { type: 'function', inputs: [ @@ -3992,11 +4184,6 @@ export const serviceProviderRegistryAbi = [ type: 'string', }, { name: 'isActive', internalType: 'bool', type: 'bool' }, - { - name: 'providerId', - internalType: 'uint256', - type: 'uint256', - }, ], }, { @@ -4137,7 +4324,6 @@ export const serviceProviderRegistryAbi = [ { name: 'name', internalType: 'string', type: 'string' }, { name: 'description', internalType: 'string', type: 'string' }, { name: 'isActive', internalType: 'bool', type: 'bool' }, - { name: 'providerId', internalType: 'uint256', type: 'uint256' }, ], stateMutability: 'view', }, @@ -4351,18 +4537,18 @@ export const serviceProviderRegistryAbi = [ type: 'uint8', indexed: true, }, - { - name: 'serviceUrl', - internalType: 'string', - type: 'string', - indexed: false, - }, { name: 'serviceProvider', internalType: 'address', type: 'address', indexed: false, }, + { + name: 'productData', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, { name: 'capabilityKeys', internalType: 'string[]', @@ -4413,18 +4599,18 @@ export const serviceProviderRegistryAbi = [ type: 'uint8', indexed: true, }, - { - name: 'serviceUrl', - internalType: 'string', - type: 'string', - indexed: false, - }, { name: 'serviceProvider', internalType: 'address', type: 'address', indexed: false, }, + { + name: 'productData', + internalType: 'bytes', + type: 'bytes', + indexed: false, + }, { name: 'capabilityKeys', internalType: 'string[]', @@ -4582,6 +4768,7 @@ export const sessionKeyRegistryAbi = [ { name: 'signer', internalType: 'address', type: 'address' }, { name: 'expiry', internalType: 'uint256', type: 'uint256' }, { name: 'permissions', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'origin', internalType: 'string', type: 'string' }, ], name: 'login', outputs: [], @@ -4593,6 +4780,7 @@ export const sessionKeyRegistryAbi = [ { name: 'signer', internalType: 'address payable', type: 'address' }, { name: 'expiry', internalType: 'uint256', type: 'uint256' }, { name: 'permissions', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'origin', internalType: 'string', type: 'string' }, ], name: 'loginAndFund', outputs: [], @@ -4603,11 +4791,49 @@ export const sessionKeyRegistryAbi = [ inputs: [ { name: 'signer', internalType: 'address', type: 'address' }, { name: 'permissions', internalType: 'bytes32[]', type: 'bytes32[]' }, + { name: 'origin', internalType: 'string', type: 'string' }, ], name: 'revoke', outputs: [], stateMutability: 'nonpayable', }, + { + type: 'event', + anonymous: false, + inputs: [ + { + name: 'identity', + internalType: 'address', + type: 'address', + indexed: true, + }, + { + name: 'signer', + internalType: 'address', + type: 'address', + indexed: false, + }, + { + name: 'expiry', + internalType: 'uint256', + type: 'uint256', + indexed: false, + }, + { + name: 'permissions', + internalType: 'bytes32[]', + type: 'bytes32[]', + indexed: false, + }, + { + name: 'origin', + internalType: 'string', + type: 'string', + indexed: false, + }, + ], + name: 'AuthorizationsUpdated', + }, ] as const /** diff --git a/packages/synapse-sdk/src/payments/service.ts b/packages/synapse-sdk/src/payments/service.ts index 0ad70340..13145da0 100644 --- a/packages/synapse-sdk/src/payments/service.ts +++ b/packages/synapse-sdk/src/payments/service.ts @@ -922,16 +922,15 @@ export class PaymentsService { try { // Use staticCall to simulate the transaction and get the return values // Include the settlement fee (NETWORK_FEE in contract) in the simulation - const result = await paymentsContract.settleRail.staticCall(railIdBigint, untilEpochBigint, { - value: SETTLEMENT_FEE, - }) + const result = await paymentsContract.settleRail.staticCall(railIdBigint, untilEpochBigint) return { totalSettledAmount: result[0], totalNetPayeeAmount: result[1], totalOperatorCommission: result[2], - finalSettledEpoch: result[3], - note: result[4], + totalNetworkFee: result[3], + finalSettledEpoch: result[4], + note: result[5], } } catch (error) { throw createError( @@ -1078,7 +1077,7 @@ export class PaymentsService { const paymentsContract = this._getPaymentsContract() try { - const rails = await paymentsContract.getRailsForPayerAndToken(signerAddress, this._usdfcAddress) + const [rails] = await paymentsContract.getRailsForPayerAndToken(signerAddress, this._usdfcAddress, 0n, 0n) return rails.map((rail: any) => ({ railId: Number(rail.railId), @@ -1108,7 +1107,7 @@ export class PaymentsService { const paymentsContract = this._getPaymentsContract() try { - const rails = await paymentsContract.getRailsForPayeeAndToken(signerAddress, this._usdfcAddress) + const [rails] = await paymentsContract.getRailsForPayeeAndToken(signerAddress, this._usdfcAddress, 0n, 0n) return rails.map((rail: any) => ({ railId: Number(rail.railId), diff --git a/packages/synapse-sdk/src/pdp/auth.ts b/packages/synapse-sdk/src/pdp/auth.ts index f38b1ecc..e9d824e9 100644 --- a/packages/synapse-sdk/src/pdp/auth.ts +++ b/packages/synapse-sdk/src/pdp/auth.ts @@ -204,7 +204,7 @@ export class PDPAuthHelper { * ``` */ async signCreateDataSet( - clientDataSetId: number | bigint, + clientDataSetId: bigint, payee: string, metadata: MetadataEntry[] = [] ): Promise { @@ -226,7 +226,7 @@ export class PDPAuthHelper { } else { // Use standard ethers.js signing (for private keys, etc) const value = { - clientDataSetId: BigInt(clientDataSetId), + clientDataSetId, metadata, payee, } @@ -241,7 +241,7 @@ export class PDPAuthHelper { // For EIP-712, signedData contains the actual message hash that was signed const signedData = ethers.TypedDataEncoder.hash(this.domain, types, { - clientDataSetId: BigInt(clientDataSetId), + clientDataSetId, metadata, payee, }) @@ -282,8 +282,8 @@ export class PDPAuthHelper { * ``` */ async signAddPieces( - clientDataSetId: number | bigint, - firstPieceId: number | bigint, + clientDataSetId: bigint, + firstPieceId: bigint, pieceDataArray: PieceCID[] | string[], metadata: MetadataEntry[][] = [] ): Promise { @@ -341,8 +341,8 @@ export class PDPAuthHelper { } else { // Use standard ethers.js signing with bigint values const value = { - clientDataSetId: BigInt(clientDataSetId), - firstAdded: BigInt(firstPieceId), + clientDataSetId, + firstAdded: firstPieceId, pieceData: formattedPieceData, pieceMetadata: pieceMetadata, } @@ -357,8 +357,8 @@ export class PDPAuthHelper { // For EIP-712, signedData contains the actual message hash that was signed const signedData = ethers.TypedDataEncoder.hash(this.domain, types, { - clientDataSetId: BigInt(clientDataSetId), - firstAdded: BigInt(firstPieceId), + clientDataSetId, + firstAdded: firstPieceId, pieceData: formattedPieceData, pieceMetadata: pieceMetadata, }) @@ -392,13 +392,7 @@ export class PDPAuthHelper { * ) * ``` */ - async signSchedulePieceRemovals( - clientDataSetId: number | bigint, - pieceIds: Array - ): Promise { - // Convert pieceIds to BigInt array for proper encoding - const pieceIdsBigInt = pieceIds.map((id) => BigInt(id)) - + async signSchedulePieceRemovals(clientDataSetId: bigint, pieceIds: Array): Promise { let signature: string // Check if we should use MetaMask-friendly signing @@ -408,16 +402,13 @@ export class PDPAuthHelper { // Use MetaMask-friendly signing for better UX const value = { clientDataSetId: clientDataSetId.toString(), // Keep as string for MetaMask display - pieceIds: pieceIdsBigInt.map((id) => id.toString()), // Convert to string array for display + pieceIds: pieceIds.map((id) => id.toString()), // Convert to string array for display } signature = await this.signWithMetaMask({ SchedulePieceRemovals: EIP712_TYPES.SchedulePieceRemovals }, value) } else { // Use standard ethers.js signing with BigInt values - const value = { - clientDataSetId: BigInt(clientDataSetId), - pieceIds: pieceIdsBigInt, - } + const value = { clientDataSetId, pieceIds } // Use underlying signer for typed data signing (handles NonceManager) const actualSigner = this.getUnderlyingSigner() @@ -434,10 +425,7 @@ export class PDPAuthHelper { const signedData = ethers.TypedDataEncoder.hash( this.domain, { SchedulePieceRemovals: EIP712_TYPES.SchedulePieceRemovals }, - { - clientDataSetId: BigInt(clientDataSetId), - pieceIds: pieceIdsBigInt, - } + { clientDataSetId, pieceIds } ) return { @@ -467,7 +455,7 @@ export class PDPAuthHelper { * ) * ``` */ - async signDeleteDataSet(clientDataSetId: number | bigint): Promise { + async signDeleteDataSet(clientDataSetId: bigint): Promise { let signature: string // Check if we should use MetaMask-friendly signing @@ -482,9 +470,7 @@ export class PDPAuthHelper { signature = await this.signWithMetaMask({ DeleteDataSet: EIP712_TYPES.DeleteDataSet }, value) } else { // Use standard ethers.js signing - const value = { - clientDataSetId: BigInt(clientDataSetId), - } + const value = { clientDataSetId } // Use underlying signer for typed data signing (handles NonceManager) const actualSigner = this.getUnderlyingSigner() @@ -497,9 +483,7 @@ export class PDPAuthHelper { const signedData = ethers.TypedDataEncoder.hash( this.domain, { DeleteDataSet: EIP712_TYPES.DeleteDataSet }, - { - clientDataSetId: BigInt(clientDataSetId), - } + { clientDataSetId } ) return { diff --git a/packages/synapse-sdk/src/pdp/server.ts b/packages/synapse-sdk/src/pdp/server.ts index 3b6e3985..9bdedcb7 100644 --- a/packages/synapse-sdk/src/pdp/server.ts +++ b/packages/synapse-sdk/src/pdp/server.ts @@ -26,18 +26,18 @@ * ``` */ +import * as Piece from '@filoz/synapse-core/piece' +import * as SP from '@filoz/synapse-core/sp' import { ethers } from 'ethers' -import { asPieceCID, calculate as calculatePieceCID, downloadAndValidate } from '../piece/index.ts' +import type { Hex } from 'viem' +import { asPieceCID, downloadAndValidate } from '../piece/index.ts' import type { DataSetData, MetadataEntry, PieceCID } from '../types.ts' import { validateDataSetMetadata, validatePieceMetadata } from '../utils/metadata.ts' -import { constructFindPieceUrl, constructPieceUrl } from '../utils/piece.ts' +import { constructPieceUrl } from '../utils/piece.ts' import type { PDPAuthHelper } from './auth.ts' import { - asDataSetData, validateDataSetCreationStatusResponse, - validateFindPieceResponse, validatePieceAdditionStatusResponse, - validatePieceDeleteResponse, validatePieceStatusResponse, } from './validation.ts' @@ -87,8 +87,6 @@ export interface AddPiecesResponse { export interface FindPieceResponse { /** The piece CID that was found */ pieceCid: PieceCID - /** @deprecated Use pieceCid instead. This field is for backward compatibility and will be removed in a future version */ - piece_cid?: string } /** @@ -146,12 +144,20 @@ export interface PieceAdditionStatusResponse { * Input for adding pieces to a data set */ export interface PDPAddPiecesInput { - pieces: { - pieceCid: string - subPieces: { - subPieceCid: string - }[] + pieces: PDPPieces[] + extraData: string +} + +export interface PDPPieces { + pieceCid: string + subPieces: { + subPieceCid: string }[] +} + +export interface PDPCreateAndAddInput { + recordKeeper: string + pieces: PDPPieces[] extraData: string } @@ -177,12 +183,13 @@ export class PDPServer { * Create a new data set on the PDP server * @param clientDataSetId - Unique ID for the client's dataset * @param payee - Address that will receive payments (service provider) + * @param payer - Address that will pay for the storage (client) * @param metadata - Metadata entries for the data set (key-value pairs) * @param recordKeeper - Address of the Warm Storage contract * @returns Promise that resolves with transaction hash and status URL */ async createDataSet( - clientDataSetId: number, + clientDataSetId: bigint, payee: string, payer: string, metadata: MetadataEntry[], @@ -198,23 +205,87 @@ export class PDPServer { // This needs to match the DataSetCreateData struct in Warm Storage contract const extraData = this._encodeDataSetCreateData({ payer, + clientDataSetId, metadata, signature: authData.signature, }) - // Prepare request body - const requestBody = { - recordKeeper, + return SP.createDataSet({ + endpoint: this._serviceURL, + recordKeeper: recordKeeper as Hex, extraData: `0x${extraData}`, + }) + } + + /** + * Creates a data set and adds pieces to it in a combined operation. + * Users can poll the status of the operation using the returned data set status URL. + * After which the user can use the returned transaction hash and data set ID to check the status of the piece addition. + * @param clientDataSetId - Unique ID for the client's dataset + * @param payee - Address that will receive payments (service provider) + * @param payer - Address that will pay for the storage (client) + * @param recordKeeper - Address of the Warm Storage contract + * @param pieceDataArray - Array of piece data containing PieceCID CIDs and raw sizes + * @param metadata - Optional metadata for dataset and each of the pieces. + * @returns Promise that resolves with transaction hash and status URL + */ + async createAndAddPieces( + clientDataSetId: bigint, + payee: string, + payer: string, + recordKeeper: string, + pieceDataArray: PieceCID[] | string[], + metadata: { + dataset?: MetadataEntry[] + pieces?: MetadataEntry[][] + } + ): Promise { + // Validate metadata against contract limits + if (metadata.dataset == null) { + metadata.dataset = [] } + validateDataSetMetadata(metadata.dataset) + metadata.pieces = PDPServer._processAddPiecesInputs(pieceDataArray, metadata.pieces) + + // Generate the EIP-712 signature for data set creation + const createAuthData = await this.getAuthHelper().signCreateDataSet(clientDataSetId, payee, metadata.dataset) - // Make the POST request to create the data set - const response = await fetch(`${this._serviceURL}/pdp/data-sets`, { + // Prepare the extra data for the contract call + // This needs to match the DataSetCreateData struct in Warm Storage contract + const createExtraData = this._encodeDataSetCreateData({ + payer, + clientDataSetId, + metadata: metadata.dataset, + signature: createAuthData.signature, + }) + + const addAuthData = await this.getAuthHelper().signAddPieces( + clientDataSetId, + BigInt(0), + pieceDataArray, // Pass PieceData[] directly to auth helper + metadata.pieces + ) + + const addExtraData = this._encodeAddPiecesExtraData({ + signature: addAuthData.signature, + metadata: metadata.pieces, + }) + + const abiCoder = ethers.AbiCoder.defaultAbiCoder() + const encoded = abiCoder.encode(['bytes', 'bytes'], [`0x${createExtraData}`, `0x${addExtraData}`]) + const requestJson: PDPCreateAndAddInput = { + recordKeeper: recordKeeper, + pieces: PDPServer._formatPieceDataArrayForCurio(pieceDataArray), + extraData: `${encoded}`, + } + + // Make the POST request to add pieces to the data set + const response = await fetch(`${this._serviceURL}/pdp/data-sets/create-and-add`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify(requestBody), + body: JSON.stringify(requestJson), }) if (response.status !== 201) { @@ -243,37 +314,18 @@ export class PDPServer { } } - /** - * Add pieces to an existing data set - * @param dataSetId - The ID of the data set to add pieces to - * @param clientDataSetId - The client's dataset ID used when creating the data set - * @param nextPieceId - The ID to assign to the first piece being added, this should be - * the next available ID on chain or the signature will fail to be validated - * @param pieceDataArray - Array of piece data containing PieceCID CIDs and raw sizes - * @param metadata - Optional metadata for each piece (array of arrays, one per piece) - * @returns Promise that resolves when the pieces are added (201 Created) - * @throws Error if any CID is invalid - * - * @example - * ```typescript - * const pieceData = ['bafkzcibcd...'] - * const metadata = [[{ key: 'snapshotDate', value: '20250711' }]] - * await pdpTool.addPieces(dataSetId, clientDataSetId, nextPieceId, pieceData, metadata) - * ``` - */ - async addPieces( - dataSetId: number, - clientDataSetId: number, - nextPieceId: number, + private static _processAddPiecesInputs( pieceDataArray: PieceCID[] | string[], metadata?: MetadataEntry[][] - ): Promise { + ): MetadataEntry[][] { if (pieceDataArray.length === 0) { throw new Error('At least one piece must be provided') } - // Validate piece metadata against contract limits if (metadata != null) { + if (metadata.length !== pieceDataArray.length) { + throw new Error(`Metadata length (${metadata.length}) must match pieces length (${pieceDataArray.length})`) + } for (let i = 0; i < metadata.length; i++) { if (metadata[i] != null && metadata[i].length > 0) { try { @@ -292,19 +344,56 @@ export class PDPServer { throw new Error(`Invalid PieceCID: ${String(pieceData)}`) } } - // If no metadata provided, create empty arrays for each piece const finalMetadata = metadata ?? pieceDataArray.map(() => []) + return finalMetadata + } - // Validate metadata length matches pieces - if (finalMetadata.length !== pieceDataArray.length) { - throw new Error(`Metadata length (${finalMetadata.length}) must match pieces length (${pieceDataArray.length})`) - } + private static _formatPieceDataArrayForCurio(pieceDataArray: PieceCID[] | string[]): PDPPieces[] { + return pieceDataArray.map((pieceData) => { + // Convert to string for JSON serialization + const cidString = typeof pieceData === 'string' ? pieceData : pieceData.toString() + return { + pieceCid: cidString, + subPieces: [ + { + subPieceCid: cidString, // Piece is its own subpiece + }, + ], + } + }) + } + /** + * Add pieces to an existing data set + * @param dataSetId - The ID of the data set to add pieces to + * @param clientDataSetId - The client's dataset ID used when creating the data set + * @param nextPieceId - The ID to assign to the first piece being added, this should be + * the next available ID on chain or the signature will fail to be validated + * @param pieceDataArray - Array of piece data containing PieceCID CIDs and raw sizes + * @param metadata - Optional metadata for each piece (array of arrays, one per piece) + * @returns Promise that resolves when the pieces are added (201 Created) + * @throws Error if any CID is invalid + * + * @example + * ```typescript + * const pieceData = ['bafkzcibcd...'] + * const metadata = [[{ key: 'snapshotDate', value: '20250711' }]] + * await pdpTool.addPieces(dataSetId, clientDataSetId, nextPieceId, pieceData, metadata) + * ``` + */ + async addPieces( + dataSetId: number, + clientDataSetId: bigint, + nextPieceId: number, + pieceDataArray: PieceCID[] | string[], + metadata?: MetadataEntry[][] + ): Promise { + const finalMetadata = PDPServer._processAddPiecesInputs(pieceDataArray, metadata) // Generate the EIP-712 signature for adding pieces const authData = await this.getAuthHelper().signAddPieces( clientDataSetId, - nextPieceId, + BigInt(nextPieceId), pieceDataArray, // Pass PieceData[] directly to auth helper finalMetadata ) @@ -316,60 +405,15 @@ export class PDPServer { metadata: finalMetadata, }) - // Prepare request body matching the Curio handler expectation - // Each piece has itself as its only subPiece (internal implementation detail) - const requestBody: PDPAddPiecesInput = { - pieces: pieceDataArray.map((pieceData) => { - // Convert to string for JSON serialization - const cidString = typeof pieceData === 'string' ? pieceData : pieceData.toString() - return { - pieceCid: cidString, - subPieces: [ - { - subPieceCid: cidString, // Piece is its own subpiece - }, - ], - } - }), + const { txHash, statusUrl } = await SP.addPieces({ + endpoint: this._serviceURL, + dataSetId: BigInt(dataSetId), + pieces: pieceDataArray.map(asPieceCID).filter((t) => t != null), extraData: `0x${extraData}`, - } - - // Make the POST request to add pieces to the data set - const response = await fetch(`${this._serviceURL}/pdp/data-sets/${dataSetId}/pieces`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(requestBody), + nextPieceId: BigInt(nextPieceId), }) - - if (response.status !== 201) { - const errorText = await response.text() - throw new Error(`Failed to add pieces to data set: ${response.status} ${response.statusText} - ${errorText}`) - } - - // Check for Location header (backward compatible with old servers) - const location = response.headers.get('Location') - let txHash: string | undefined - let statusUrl: string | undefined - - if (location != null) { - // Expected format: /pdp/data-sets/{dataSetId}/pieces/added/{txHash} - const locationMatch = location.match(/\/pieces\/added\/([0-9a-fA-Fx]+)$/) - if (locationMatch != null) { - txHash = locationMatch[1] - // Ensure txHash has 0x prefix - if (!txHash.startsWith('0x')) { - txHash = `0x${txHash}` - } - statusUrl = `${this._serviceURL}${location}` - } - } - - // Success - pieces have been added - const responseText = await response.text() return { - message: responseText !== '' ? responseText : `Pieces added to data set ID ${dataSetId} successfully`, + message: `Pieces added to data set ID ${dataSetId} successfully`, txHash, statusUrl, } @@ -441,27 +485,20 @@ export class PDPServer { throw new Error(`Invalid PieceCID: ${String(pieceCid)}`) } - const url = constructFindPieceUrl(this._serviceURL, parsedPieceCid) - const response = await fetch(url, { - method: 'GET', - headers: {}, + const piece = await SP.findPiece({ + endpoint: this._serviceURL, + pieceCid: parsedPieceCid, }) - - if (response.status === 404) { - throw new Error(`Piece not found: ${parsedPieceCid.toString()}`) - } - - if (!response.ok) { - const errorText = await response.text() - throw new Error(`Failed to find piece: ${response.status} ${response.statusText} - ${errorText}`) + return { + pieceCid: piece, } - - const data = await response.json() - return validateFindPieceResponse(data) } /** * Get indexing and IPNI status for a piece + * + * TODO: not used anywhere, remove? + * * @param pieceCid - The PieceCID CID (as string or PieceCID object) * @returns Piece status information including indexing and IPNI advertisement status * @throws Error if piece not found or doesn't belong to service (404) @@ -502,87 +539,10 @@ export class PDPServer { // Convert ArrayBuffer to Uint8Array if needed const uint8Data = data instanceof ArrayBuffer ? new Uint8Array(data) : data - // Calculate PieceCID - performance.mark('synapse:calculatePieceCID-start') - const pieceCid = calculatePieceCID(uint8Data) - performance.mark('synapse:calculatePieceCID-end') - performance.measure('synapse:calculatePieceCID', 'synapse:calculatePieceCID-start', 'synapse:calculatePieceCID-end') - const size = uint8Data.length - - const requestBody = { - pieceCid: pieceCid.toString(), - // No notify URL needed - } - - // Create upload session or check if piece exists - performance.mark('synapse:POST.pdp.piece-start') - const createResponse = await fetch(`${this._serviceURL}/pdp/piece`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(requestBody), + return await SP.uploadPiece({ + endpoint: this._serviceURL, + data: uint8Data, }) - performance.mark('synapse:POST.pdp.piece-end') - performance.measure('synapse:POST.pdp.piece', 'synapse:POST.pdp.piece-start', 'synapse:POST.pdp.piece-end') - - if (createResponse.status === 200) { - // Piece already exists on server - return { - pieceCid, - size, - } - } - - if (createResponse.status !== 201) { - const errorText = await createResponse.text() - throw new Error( - `Failed to create upload session: ${createResponse.status} ${createResponse.statusText} - ${errorText}` - ) - } - - // Extract upload ID from Location header - const location = createResponse.headers.get('Location') - if (location == null) { - throw new Error('Server did not provide Location header in response (may be restricted by CORS policy)') - } - - // Validate the location format and extract UUID - // Match /pdp/piece/upload/UUID or /piece/upload/UUID anywhere in the path - const locationMatch = location.match(/\/(?:pdp\/)?piece\/upload\/([a-fA-F0-9-]+)/) - if (locationMatch == null) { - throw new Error(`Invalid Location header format: ${location}`) - } - - const uploadUuid = locationMatch[1] // Extract just the UUID - - // Upload the data - performance.mark('synapse:PUT.pdp.piece.upload-start') - const uploadResponse = await fetch(`${this._serviceURL}/pdp/piece/upload/${uploadUuid}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/octet-stream', - 'Content-Length': uint8Data.length.toString(), - // No Authorization header needed - }, - body: uint8Data, - }) - performance.mark('synapse:PUT.pdp.piece.upload-end') - performance.measure( - 'synapse:PUT.pdp.piece.upload', - 'synapse:PUT.pdp.piece.upload-start', - 'synapse:PUT.pdp.piece.upload-end' - ) - - if (uploadResponse.status !== 204) { - const errorText = await uploadResponse.text() - throw new Error(`Failed to upload piece: ${uploadResponse.status} ${uploadResponse.statusText} - ${errorText}`) - } - - return { - pieceCid, - size, - } } /** @@ -611,29 +571,24 @@ export class PDPServer { * @returns Promise that resolves with data set data */ async getDataSet(dataSetId: number): Promise { - const response = await fetch(`${this._serviceURL}/pdp/data-sets/${dataSetId}`, { - method: 'GET', - headers: { - Accept: 'application/json', - }, + const data = await SP.getDataSet({ + endpoint: this._serviceURL, + dataSetId: BigInt(dataSetId), }) - if (response.status === 404) { - throw new Error(`Data set not found: ${dataSetId}`) - } - - if (!response.ok) { - const errorText = await response.text() - throw new Error(`Failed to fetch data set: ${response.status} ${response.statusText} - ${errorText}`) - } - - const data = await response.json() - const converted = asDataSetData(data) - if (converted == null) { - console.error('Invalid data set data response:', data) - throw new Error('Invalid data set data response format') + return { + id: data.id, + pieces: data.pieces.map((piece) => { + const pieceCid = Piece.parse(piece.pieceCid) + return { + pieceId: piece.pieceId, + pieceCid: pieceCid, + subPieceCid: pieceCid, + subPieceOffset: piece.subPieceOffset, + } + }), + nextChallengeEpoch: data.nextChallengeEpoch, } - return converted } /** @@ -643,46 +598,45 @@ export class PDPServer { * @param pieceID - The ID of the piece to delete * @returns Promise for transaction hash of the delete operation */ - async deletePiece(dataSetId: number, clientDataSetId: number, pieceID: number): Promise { - const authData = await this.getAuthHelper().signSchedulePieceRemovals(clientDataSetId, [pieceID]) - const payload = { - extraData: `0x${authData.signature}`, - } - - const response = await fetch(`${this._serviceURL}/pdp/data-sets/${dataSetId}/pieces/${pieceID}`, { - method: 'DELETE', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(payload), + async deletePiece(dataSetId: number, clientDataSetId: bigint, pieceID: number): Promise { + const authData = await this.getAuthHelper().signSchedulePieceRemovals(clientDataSetId, [BigInt(pieceID)]) + + const { txHash } = await SP.deletePiece({ + endpoint: this._serviceURL, + dataSetId: BigInt(dataSetId), + pieceId: BigInt(pieceID), + extraData: ethers.AbiCoder.defaultAbiCoder().encode(['bytes'], [authData.signature]) as Hex, }) - - if (response.status !== 200) { - const errorText = await response.text() - throw new Error(`Failed to delete piece: ${response.status} ${response.statusText} - ${errorText}`) - } - const data = await response.json() - return validatePieceDeleteResponse(data).txHash + return txHash } /** * Encode DataSetCreateData for extraData field * This matches the Solidity struct DataSetCreateData in Warm Storage contract */ - private _encodeDataSetCreateData(data: { payer: string; metadata: MetadataEntry[]; signature: string }): string { + private _encodeDataSetCreateData(data: { + payer: string + clientDataSetId: bigint + metadata: MetadataEntry[] + signature: string + }): string { // Ensure signature has 0x prefix const signature = data.signature.startsWith('0x') ? data.signature : `0x${data.signature}` // ABI encode the struct as a tuple // DataSetCreateData struct: // - address payer + // - uint256 clientDataSetId // - string[] metadataKeys // - string[] metadataValues // - bytes signature const keys = data.metadata.map((item) => item.key) const values = data.metadata.map((item) => item.value) const abiCoder = ethers.AbiCoder.defaultAbiCoder() - const encoded = abiCoder.encode(['address', 'string[]', 'string[]', 'bytes'], [data.payer, keys, values, signature]) + const encoded = abiCoder.encode( + ['address', 'uint256', 'string[]', 'string[]', 'bytes'], + [data.payer, data.clientDataSetId, keys, values, signature] + ) // Return hex string without 0x prefix (since we add it in the calling code) return encoded.slice(2) diff --git a/packages/synapse-sdk/src/pdp/validation.ts b/packages/synapse-sdk/src/pdp/validation.ts index b9356f58..7de7ba0e 100644 --- a/packages/synapse-sdk/src/pdp/validation.ts +++ b/packages/synapse-sdk/src/pdp/validation.ts @@ -201,7 +201,6 @@ export function validateFindPieceResponse(value: unknown): FindPieceResponse { // Return normalized response with PieceCID object return { pieceCid, - piece_cid: obj.piece_cid, // Keep legacy field if it exists } } diff --git a/packages/synapse-sdk/src/session/key.ts b/packages/synapse-sdk/src/session/key.ts index 06f56484..22efcb27 100644 --- a/packages/synapse-sdk/src/session/key.ts +++ b/packages/synapse-sdk/src/session/key.ts @@ -13,7 +13,7 @@ * const expiries = await sessionKey.fetchExpiries([ADD_PIECES_TYPEHASH]) * if (expiries[ADD_PIECES_TYPEHASH] * BigInt(1000) < BigInt(Date.now()) + HOUR_MILLIS) { * const DAY_MILLIS = BigInt(24) * HOUR_MILLIS - * const loginTx = await sessionKey.login(BigInt(Date.now()) / BigInt(1000 + 30 * DAY_MILLIS), PDP_PERMISSIONS) + * const loginTx = await sessionKey.login(BigInt(Date.now()) / BigInt(1000 + 30 * DAY_MILLIS), PDP_PERMISSIONS, "example.com") * const loginReceipt = await loginTx.wait() * } * synapse.setSession(sessionKey) @@ -46,6 +46,8 @@ export const PDP_PERMISSION_NAMES: Record = { [DELETE_DATA_SET_TYPEHASH]: 'DeleteDataSet', } +const DEFAULT_ORIGIN: string = (globalThis as any).location?.hostname || 'unknown' + export class SessionKey { private readonly _provider: ethers.Provider private readonly _registry: ethers.Contract @@ -122,10 +124,15 @@ export class SessionKey { * * @param expiry unix time (block.timestamp) that the permissions expire * @param permissions list of permissions granted to the signer, as a list of bytes32 hex strings + * @param origin the name of the application prompting this login * @return signed and broadcasted login transaction details */ - async login(expiry: bigint, permissions: string[] = PDP_PERMISSIONS): Promise { - return await this._registry.login(await this._signer.getAddress(), expiry, permissions) + async login( + expiry: bigint, + permissions: string[] = PDP_PERMISSIONS, + origin = DEFAULT_ORIGIN + ): Promise { + return await this._registry.login(await this._signer.getAddress(), expiry, permissions, origin) } /** diff --git a/packages/synapse-sdk/src/sp-registry/service.ts b/packages/synapse-sdk/src/sp-registry/service.ts index fe30144b..3854e6ae 100644 --- a/packages/synapse-sdk/src/sp-registry/service.ts +++ b/packages/synapse-sdk/src/sp-registry/service.ts @@ -179,14 +179,14 @@ export class SPRegistryService { const contract = this._getRegistryContract() const rawProvider = await contract.getProvider(providerId) - if (rawProvider.serviceProvider === ethers.ZeroAddress) { + if (rawProvider.info.serviceProvider === ethers.ZeroAddress) { return null } // Get products for this provider const products = await this._getProviderProducts(providerId) - return this._convertToProviderInfo(providerId, rawProvider, products) + return this._convertToProviderInfo(providerId, rawProvider.info, products) } catch (error) { if (error instanceof Error && error.message.includes('Provider not found')) { return null @@ -211,7 +211,7 @@ export class SPRegistryService { ]) // Check if provider exists (beneficiary address will be zero if not found) - if (rawProvider.serviceProvider === ethers.ZeroAddress) { + if (rawProvider.info.serviceProvider === ethers.ZeroAddress) { return null } @@ -219,7 +219,7 @@ export class SPRegistryService { const products = await this._getProviderProducts(Number(providerId)) // Convert to ProviderInfo - return this._convertToProviderInfo(Number(providerId), rawProvider, products) + return this._convertToProviderInfo(Number(providerId), rawProvider.info, products) } catch { return null } @@ -569,7 +569,7 @@ export class SPRegistryService { const products = this._extractProductsFromMulticallResult(results[pdpServiceResultIndex], iface) // Convert to ProviderInfo - const providerInfo = this._convertToProviderInfo(providerIds[i], rawProvider, products) + const providerInfo = this._convertToProviderInfo(providerIds[i], rawProvider.info, products) providers.push(providerInfo) } catch { // Skip failed decoding @@ -695,7 +695,7 @@ export class SPRegistryService { /** * Convert raw provider data to ProviderInfo */ - private _convertToProviderInfo(providerId: number, rawProvider: any, productsArray: ServiceProduct[]): ProviderInfo { + private _convertToProviderInfo(providerId: number, providerInfo: any, productsArray: ServiceProduct[]): ProviderInfo { // Convert products array to Record for direct access by type const products: Partial> = {} @@ -707,11 +707,11 @@ export class SPRegistryService { return { id: providerId, - serviceProvider: rawProvider.serviceProvider, - payee: rawProvider.payee, - name: rawProvider.name, - description: rawProvider.description, - active: rawProvider.isActive, + serviceProvider: providerInfo.serviceProvider, + payee: providerInfo.payee, + name: providerInfo.name, + description: providerInfo.description, + active: providerInfo.isActive, products, } } diff --git a/packages/synapse-sdk/src/storage/context.ts b/packages/synapse-sdk/src/storage/context.ts index 15f52945..ae24ebb5 100644 --- a/packages/synapse-sdk/src/storage/context.ts +++ b/packages/synapse-sdk/src/storage/context.ts @@ -55,6 +55,7 @@ import { } from '../utils/index.ts' import { combineMetadata, metadataMatches, objectToEntries, validatePieceMetadata } from '../utils/metadata.ts' import { ProviderResolver } from '../utils/provider-resolver.ts' +import { randIndex, randU256 } from '../utils/rand.ts' import type { WarmStorageService } from '../warm-storage/index.ts' export class StorageContext { @@ -258,7 +259,7 @@ export class StorageContext { // Create a new data set // Get next client dataset ID - const nextDatasetId = await warmStorageService.getNextClientDataSetId(clientAddress) + const nextDatasetId = randU256() // Create auth helper for signing const warmStorageAddress = synapse.getWarmStorageAddress() @@ -488,7 +489,7 @@ export class StorageContext { requestedMetadata, warmStorageService, providerResolver, - client, + options.excludeProviderIds, options.forceCreateDataSet, options.withIpni, options.dev @@ -705,7 +706,7 @@ export class StorageContext { requestedMetadata: Record, warmStorageService: WarmStorageService, providerResolver: ProviderResolver, - signer: ethers.Signer, + excludeProviderIds?: number[], forceCreateDataSet?: boolean, withIpni?: boolean, dev?: boolean @@ -732,7 +733,7 @@ export class StorageContext { // Create async generator that yields providers lazily async function* generateProviders(): AsyncGenerator { - const yieldedProviders = new Set() + const skipProviderIds = new Set(excludeProviderIds) // First, yield providers from existing data sets (in sorted order) for (const dataSet of sorted) { @@ -744,8 +745,8 @@ export class StorageContext { ) continue } - if (!yieldedProviders.has(provider.serviceProvider.toLowerCase())) { - yieldedProviders.add(provider.serviceProvider.toLowerCase()) + if (!skipProviderIds.has(provider.id)) { + skipProviderIds.add(provider.id) yield provider } } @@ -785,14 +786,16 @@ export class StorageContext { } // No existing data sets - select from all approved providers - const allProviders = await providerResolver.getApprovedProviders() + const allProviders = (await providerResolver.getApprovedProviders()).filter( + (provider: ProviderInfo) => excludeProviderIds?.includes(provider.id) !== true + ) if (allProviders.length === 0) { throw createError('StorageContext', 'smartSelectProvider', 'No approved service providers available') } // Random selection from all providers - const provider = await StorageContext.selectRandomProvider(allProviders, signer, withIpni, dev) + const provider = await StorageContext.selectRandomProvider(allProviders, withIpni, dev) return { provider, @@ -805,12 +808,12 @@ export class StorageContext { /** * Select a random provider from a list with ping validation * @param providers - Array of providers to select from - * @param signer - Signer for additional entropy + * @param withIpni - Filter for IPNI support + * @param dev - Include dev providers * @returns Selected provider */ private static async selectRandomProvider( providers: ProviderInfo[], - signer?: ethers.Signer, withIpni?: boolean, dev?: boolean ): Promise { @@ -823,34 +826,8 @@ export class StorageContext { const remaining = [...providers] while (remaining.length > 0) { - let randomIndex: number - - // Try crypto.getRandomValues if available (HTTPS contexts) - if (typeof globalThis.crypto !== 'undefined' && globalThis.crypto.getRandomValues != null) { - const randomBytes = new Uint8Array(1) - globalThis.crypto.getRandomValues(randomBytes) - randomIndex = randomBytes[0] % remaining.length - } else { - // Fallback for HTTP contexts - use multiple entropy sources - const timestamp = Date.now() - const random = Math.random() - - if (signer != null) { - // Use wallet address as additional entropy - const addressBytes = await signer.getAddress() - const addressSum = addressBytes.split('').reduce((a, c) => a + c.charCodeAt(0), 0) - - // Combine sources for better distribution - const combined = (timestamp * random * addressSum) % remaining.length - randomIndex = Math.floor(Math.abs(combined)) - } else { - // No signer available, use simpler fallback - randomIndex = Math.floor(Math.random() * remaining.length) - } - } - // Remove and yield the selected provider - const selected = remaining.splice(randomIndex, 1)[0] + const selected = remaining.splice(randIndex(remaining.length), 1)[0] yield selected } } @@ -1014,31 +991,11 @@ export class StorageContext { } // Poll for piece to be "parked" (ready) - const maxWaitTime = TIMING_CONSTANTS.PIECE_PARKING_TIMEOUT_MS - const pollInterval = TIMING_CONSTANTS.PIECE_PARKING_POLL_INTERVAL_MS - const startTime = Date.now() - let pieceReady = false - performance.mark('synapse:findPiece-start') - while (Date.now() - startTime < maxWaitTime) { - try { - await this._pdpServer.findPiece(uploadResult.pieceCid) - pieceReady = true - break - } catch { - // Piece not ready yet, wait and retry if we haven't exceeded timeout - if (Date.now() - startTime + pollInterval < maxWaitTime) { - await new Promise((resolve) => setTimeout(resolve, pollInterval)) - } - } - } + await this._pdpServer.findPiece(uploadResult.pieceCid) performance.mark('synapse:findPiece-end') performance.measure('synapse:findPiece', 'synapse:findPiece-start', 'synapse:findPiece-end') - if (!pieceReady) { - throw createError('StorageContext', 'findPiece', 'Timeout waiting for piece to be parked on service provider') - } - // Upload phase complete - remove from active tracking this._activeUploads.delete(uploadId) diff --git a/packages/synapse-sdk/src/storage/manager.ts b/packages/synapse-sdk/src/storage/manager.ts index d64d3ba0..bb4f8264 100644 --- a/packages/synapse-sdk/src/storage/manager.ts +++ b/packages/synapse-sdk/src/storage/manager.ts @@ -252,7 +252,10 @@ export class StorageManager { if (canUseDefault) { // Check if we have a default context with compatible metadata - if (this._defaultContext != null) { + if ( + this._defaultContext != null && + options?.excludeProviderIds?.includes(this._defaultContext.provider.id) !== true + ) { // Combine the current request metadata with effective withCDN setting const requestedMetadata = combineMetadata(options?.metadata, effectiveWithCDN) diff --git a/packages/synapse-sdk/src/synapse.ts b/packages/synapse-sdk/src/synapse.ts index 11b30213..27c73ae4 100644 --- a/packages/synapse-sdk/src/synapse.ts +++ b/packages/synapse-sdk/src/synapse.ts @@ -267,7 +267,7 @@ export class Synapse { * const HOUR_MILLIS = BigInt(1000 * 60 * 60) * if (expiries[ADD_PIECES_TYPEHASH] * BigInt(1000) < BigInt(Date.now()) + HOUR_MILLIS) { * const DAY_MILLIS = BigInt(24) * HOUR_MILLIS - * const loginTx = await sessionKey.login(BigInt(Date.now()) / BigInt(1000 + 30 * DAY_MILLIS), PDP_PERMISSIONS) + * const loginTx = await sessionKey.login(BigInt(Date.now()) / BigInt(1000 + 30 * DAY_MILLIS), PDP_PERMISSIONS, "example.com") * const loginReceipt = await loginTx.wait() * } * diff --git a/packages/synapse-sdk/src/test/metadata-selection.test.ts b/packages/synapse-sdk/src/test/metadata-selection.test.ts index 32ee304d..e1ebdc4c 100644 --- a/packages/synapse-sdk/src/test/metadata-selection.test.ts +++ b/packages/synapse-sdk/src/test/metadata-selection.test.ts @@ -148,6 +148,7 @@ describe('Metadata-based Data Set Selection', () => { pdpEndEpoch: 0n, providerId: 1n, cdnEndEpoch: 0n, + dataSetId, }, ] } @@ -165,6 +166,7 @@ describe('Metadata-based Data Set Selection', () => { pdpEndEpoch: 0n, providerId: 1n, cdnEndEpoch: 0n, + dataSetId, }, ] } @@ -182,6 +184,7 @@ describe('Metadata-based Data Set Selection', () => { pdpEndEpoch: 0n, providerId: 2n, cdnEndEpoch: 0n, + dataSetId, }, ] } @@ -199,6 +202,7 @@ describe('Metadata-based Data Set Selection', () => { pdpEndEpoch: 0n, providerId: 0n, cdnEndEpoch: 0n, + dataSetId, }, ] }, diff --git a/packages/synapse-sdk/src/test/metadata.test.ts b/packages/synapse-sdk/src/test/metadata.test.ts index eba2a39f..ec230014 100644 --- a/packages/synapse-sdk/src/test/metadata.test.ts +++ b/packages/synapse-sdk/src/test/metadata.test.ts @@ -64,7 +64,7 @@ describe('Metadata Support', () => { ) const result = await pdpServer.createDataSet( - 1, + 1n, '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payer dataSetMetadata, @@ -103,7 +103,7 @@ describe('Metadata Support', () => { ) // Test with matching metadata - const result = await pdpServer.addPieces(dataSetId, 1, 1, pieces, metadata) + const result = await pdpServer.addPieces(dataSetId, 1n, 1, pieces, metadata) assert.equal(result.txHash, mockTxHash) assert.exists(capturedPieceMetadata) assert.isNotNull(capturedPieceMetadata) @@ -117,7 +117,7 @@ describe('Metadata Support', () => { ] try { - await pdpServer.addPieces(dataSetId, 1, 1, pieces, mismatchedMetadata) + await pdpServer.addPieces(dataSetId, 1n, 1, pieces, mismatchedMetadata) assert.fail('Should have thrown an error') } catch (error: any) { assert.match(error.message, /Metadata length \(2\) must match pieces length \(1\)/) @@ -125,7 +125,7 @@ describe('Metadata Support', () => { // Test without metadata (should create empty arrays) capturedPieceMetadata = null - const resultNoMetadata = await pdpServer.addPieces(dataSetId, 1, 1, pieces) + const resultNoMetadata = await pdpServer.addPieces(dataSetId, 1n, 1, pieces) assert.equal(resultNoMetadata.txHash, mockTxHash) assert.exists(capturedPieceMetadata) assert.isNotNull(capturedPieceMetadata) @@ -156,7 +156,7 @@ describe('Metadata Support', () => { ] await pdpServer.createDataSet( - 1, + 1n, '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payer metadataWithCDN, @@ -171,7 +171,7 @@ describe('Metadata Support', () => { const metadataWithoutCDN: MetadataEntry[] = [{ key: 'project', value: 'test' }] await pdpServer.createDataSet( - 1, + 1n, '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payer metadataWithoutCDN, diff --git a/packages/synapse-sdk/src/test/mocks/jsonrpc/index.ts b/packages/synapse-sdk/src/test/mocks/jsonrpc/index.ts index 7ddc057f..9ca11533 100644 --- a/packages/synapse-sdk/src/test/mocks/jsonrpc/index.ts +++ b/packages/synapse-sdk/src/test/mocks/jsonrpc/index.ts @@ -245,7 +245,7 @@ export const presets = { pdpVerifierAddress: () => [ADDRESSES.calibration.pdpVerifier], paymentsContractAddress: () => [ADDRESSES.calibration.payments], usdfcTokenAddress: () => [ADDRESSES.calibration.usdfcToken], - filCDNBeneficiaryAddress: () => [ADDRESSES.calibration.filCDN], + filBeamBeneficiaryAddress: () => [ADDRESSES.calibration.filCDN], viewContractAddress: () => [ADDRESSES.calibration.viewContract], serviceProviderRegistry: () => [ADDRESSES.calibration.spRegistry], sessionKeyRegistry: () => [ADDRESSES.calibration.sessionKeyRegistry], @@ -275,6 +275,7 @@ export const presets = { pdpEndEpoch: 0n, providerId: 1n, cdnEndEpoch: 0n, + dataSetId: 1n, }, ], ], @@ -293,6 +294,7 @@ export const presets = { pdpEndEpoch: 0n, providerId: 1n, cdnEndEpoch: 0n, + dataSetId: 1n, }, ], getApprovedProviders: () => [[1n, 2n]], @@ -329,7 +331,7 @@ export const presets = { return [true, 'bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi'] return [false, ''] // key not found }, - clientDataSetIDs: () => { + clientDataSetIds: () => { return [BigInt(0)] }, }, @@ -341,12 +343,14 @@ export const presets = { serviceRegistry: { getProviderByAddress: (data) => [ { - serviceProvider: data[0], - payee: ADDRESSES.payee1, - isActive: true, - name: 'Test Provider', - description: 'Test Provider', providerId: 1n, + info: { + serviceProvider: data[0], + payee: ADDRESSES.payee1, + isActive: true, + name: 'Test Provider', + description: 'Test Provider', + }, }, ], getProviderIdByAddress: () => [1n], @@ -369,35 +373,41 @@ export const presets = { if (data[0] === 1n) { return [ { - serviceProvider: ADDRESSES.serviceProvider1, - payee: ADDRESSES.payee1, - isActive: true, - name: 'Test Provider', - description: 'Test Provider', providerId: 1n, + info: { + serviceProvider: ADDRESSES.serviceProvider1, + payee: ADDRESSES.payee1, + isActive: true, + name: 'Test Provider', + description: 'Test Provider', + }, }, ] } if (data[0] === 2n) { return [ { - serviceProvider: ADDRESSES.serviceProvider2, - payee: ADDRESSES.payee1, - isActive: true, - name: 'Test Provider', - description: 'Test Provider', providerId: 2n, + info: { + serviceProvider: ADDRESSES.serviceProvider2, + payee: ADDRESSES.payee1, + isActive: true, + name: 'Test Provider', + description: 'Test Provider', + }, }, ] } return [ { - serviceProvider: ADDRESSES.zero, - payee: ADDRESSES.zero, - isActive: false, - name: '', - description: '', providerId: 0n, + info: { + serviceProvider: ADDRESSES.zero, + payee: ADDRESSES.zero, + isActive: false, + name: '', + description: '', + }, }, ] }, diff --git a/packages/synapse-sdk/src/test/mocks/jsonrpc/warm-storage.ts b/packages/synapse-sdk/src/test/mocks/jsonrpc/warm-storage.ts index 4cf8b0ac..dc59e95f 100644 --- a/packages/synapse-sdk/src/test/mocks/jsonrpc/warm-storage.ts +++ b/packages/synapse-sdk/src/test/mocks/jsonrpc/warm-storage.ts @@ -28,7 +28,7 @@ export type getAllPieceMetadata = ExtractAbiFunction -export type clientDataSetIDs = ExtractAbiFunction +export type clientDataSetIds = ExtractAbiFunction export interface WarmStorageViewOptions { isProviderApproved?: (args: AbiToType) => AbiToType @@ -43,7 +43,7 @@ export interface WarmStorageViewOptions { getDataSetMetadata?: (args: AbiToType) => AbiToType getAllPieceMetadata?: (args: AbiToType) => AbiToType getPieceMetadata?: (args: AbiToType) => AbiToType - clientDataSetIDs?: (args: AbiToType) => AbiToType + clientDataSetIds?: (args: AbiToType) => AbiToType } /** @@ -56,7 +56,10 @@ export type paymentsContractAddress = ExtractAbiFunction -export type filCDNBeneficiaryAddress = ExtractAbiFunction +export type filBeamBeneficiaryAddress = ExtractAbiFunction< + typeof CONTRACT_ABIS.WARM_STORAGE, + 'filBeamBeneficiaryAddress' +> export type viewContractAddress = ExtractAbiFunction @@ -72,9 +75,9 @@ export interface WarmStorageOptions { args: AbiToType ) => AbiToType usdfcTokenAddress?: (args: AbiToType) => AbiToType - filCDNBeneficiaryAddress?: ( - args: AbiToType - ) => AbiToType + filBeamBeneficiaryAddress?: ( + args: AbiToType + ) => AbiToType viewContractAddress?: (args: AbiToType) => AbiToType serviceProviderRegistry?: ( args: AbiToType @@ -123,13 +126,13 @@ export function warmStorageCallHandler(data: Hex, options: JSONRPCOptions): Hex options.warmStorage.usdfcTokenAddress(args) ) } - case 'filCDNBeneficiaryAddress': { - if (!options.warmStorage?.filCDNBeneficiaryAddress) { - throw new Error('Warm Storage: filCDNBeneficiaryAddress is not defined') + case 'filBeamBeneficiaryAddress': { + if (!options.warmStorage?.filBeamBeneficiaryAddress) { + throw new Error('Warm Storage: filBeamBeneficiaryAddress is not defined') } return encodeAbiParameters( [{ name: '', internalType: 'address', type: 'address' }], - options.warmStorage.filCDNBeneficiaryAddress(args) + options.warmStorage.filBeamBeneficiaryAddress(args) ) } case 'viewContractAddress': { @@ -293,14 +296,14 @@ export function warmStorageViewCallHandler(data: Hex, options: JSONRPCOptions): options.warmStorageView.getPieceMetadata(args) ) } - case 'clientDataSetIDs': { - if (!options.warmStorageView?.clientDataSetIDs) { - throw new Error('Warm Storage View: clientDataSetIDs is not defined') + case 'clientDataSetIds': { + if (!options.warmStorageView?.clientDataSetIds) { + throw new Error('Warm Storage View: clientDataSetIds is not defined') } return encodeAbiParameters( - CONTRACT_ABIS.WARM_STORAGE_VIEW.find((abi) => abi.type === 'function' && abi.name === 'clientDataSetIDs')! + CONTRACT_ABIS.WARM_STORAGE_VIEW.find((abi) => abi.type === 'function' && abi.name === 'clientDataSetIds')! .outputs, - options.warmStorageView.clientDataSetIDs(args) + options.warmStorageView.clientDataSetIds(args) ) } diff --git a/packages/synapse-sdk/src/test/mocks/pdp/handlers.ts b/packages/synapse-sdk/src/test/mocks/pdp/handlers.ts index 797e4106..41f22353 100644 --- a/packages/synapse-sdk/src/test/mocks/pdp/handlers.ts +++ b/packages/synapse-sdk/src/test/mocks/pdp/handlers.ts @@ -181,12 +181,12 @@ export function findPieceHandler(pieceCid: string, found: boolean, options: PDPM /** * Helper to decode metadata from extraData */ -export function decodeMetadataFromExtraData(extraData: string): MetadataCapture { +export function decodeMetadataFromCreateDataSetExtraData(extraData: string): MetadataCapture { const abiCoder = ethers.AbiCoder.defaultAbiCoder() - const decoded = abiCoder.decode(['address', 'string[]', 'string[]', 'bytes'], extraData) + const decoded = abiCoder.decode(['address', 'uint256', 'string[]', 'string[]', 'bytes'], extraData) return { - keys: decoded[1] as string[], - values: decoded[2] as string[], + keys: decoded[2] as string[], + values: decoded[3] as string[], } } @@ -223,7 +223,7 @@ export function createDataSetWithMetadataCapture( } try { - const metadata = decodeMetadataFromExtraData(body.extraData) + const metadata = decodeMetadataFromCreateDataSetExtraData(body.extraData) captureCallback(metadata) if (options.debug) { diff --git a/packages/synapse-sdk/src/test/pdp-auth.test.ts b/packages/synapse-sdk/src/test/pdp-auth.test.ts index 3c17d39c..9f678745 100644 --- a/packages/synapse-sdk/src/test/pdp-auth.test.ts +++ b/packages/synapse-sdk/src/test/pdp-auth.test.ts @@ -36,7 +36,7 @@ const FIXTURES = { signature: '0xc77965e2b6efd594629c44eb61127bc3133b65d08c25f8aa33e3021e7f46435845ab67ffbac96afc4b4671ecbd32d4869ca7fe1c0eaa5affa942d0abbfd98d601b', digest: '0xd89be6a725302e66575d7a9c730191a84e2a624d0f0f3976194d0bd6f2927640', - clientDataSetId: 12345, + clientDataSetId: 12345n, payee: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', metadata: [{ key: 'title', value: 'TestDataSet' }], }, @@ -44,8 +44,8 @@ const FIXTURES = { signature: '0x215d2d6ea06c7daad46e3e636b305885c7d09aa34420e8dbace032af03cae06224cf678da808c7f1026b08ccf51f3d5d53351b935f5eee9750b80e78caffaaa91c', digest: '0xa690b5f3c6400833822aa3fd63ad1f0e4c1f70e5cc132cfd898c2993169d23bf', - clientDataSetId: 12345, - firstAdded: 1, + clientDataSetId: 12345n, + firstAdded: 1n, pieceCidBytes: [ '0x01559120220500de6815dcb348843215a94de532954b60be550a4bec6e74555665e9a5ec4e0f3c', '0x01559120227e03642a607ef886b004bf2c1978463ae1d4693ac0f410eb2d1b7a47fe205e5e750f', @@ -56,14 +56,14 @@ const FIXTURES = { signature: '0xcb8e645f2894fde89de54d4a54eb1e0d9871901c6fa1c2ee8a0390dc3a29e6cb2244d0561e3eca6452fa59efaab3d4b18a0b5b59ab52e233b3469422556ae9c61c', digest: '0xef55929f8dd724ef4b43c5759db26878608f7e1277d168e3e621d3cd4ba682dd', - clientDataSetId: 12345, - pieceIds: [1, 3, 5], + clientDataSetId: 12345n, + pieceIds: [1n, 3n, 5n], }, deleteDataSet: { signature: '0x94e366bd2f9bfc933a87575126715bccf128b77d9c6937e194023e13b54272eb7a74b7e6e26acf4341d9c56e141ff7ba154c37ea03e9c35b126fff1efe1a0c831c', digest: '0x79df79ba922d913eccb0f9a91564ba3a1a81a0ea81d99a7cecf23cc3f425cafb', - clientDataSetId: 12345, + clientDataSetId: 12345n, }, }, } diff --git a/packages/synapse-sdk/src/test/pdp-server.test.ts b/packages/synapse-sdk/src/test/pdp-server.test.ts index 4c9b8eaa..4828c6d5 100644 --- a/packages/synapse-sdk/src/test/pdp-server.test.ts +++ b/packages/synapse-sdk/src/test/pdp-server.test.ts @@ -6,6 +6,16 @@ * Tests the PDPServer class for creating data sets and adding pieces via HTTP API */ +import { + AddPiecesError, + CreateDataSetError, + DeletePieceError, + FindPieceError, + GetDataSetError, + LocationHeaderError, + PostPieceError, +} from '@filoz/synapse-core/errors' +import * as SP from '@filoz/synapse-core/sp' import { assert } from 'chai' import { ethers } from 'ethers' import { setup } from 'iso-web/msw' @@ -83,7 +93,7 @@ describe('PDPServer', () => { ) const result = await pdpServer.createDataSet( - 0, // clientDataSetId + 0n, // clientDataSetId '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee await signer.getAddress(), // payer [], // metadata (empty for no CDN) @@ -93,6 +103,162 @@ describe('PDPServer', () => { assert.strictEqual(result.txHash, mockTxHash) assert.include(result.statusUrl, mockTxHash) }) + + it('should fail for unexpected location header', async () => { + server.use( + http.post('http://pdp.local/pdp/data-sets', () => { + return new HttpResponse(null, { + status: 201, + headers: { Location: `/pdp/data-sets/created/invalid-hash` }, + }) + }) + ) + try { + await pdpServer.createDataSet( + 0n, // clientDataSetId + '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee + await signer.getAddress(), // payer + [], // metadata (empty for no CDN) + TEST_CONTRACT_ADDRESS // recordKeeper + ) + assert.fail('Should have thrown error for unexpected location header') + } catch (error) { + assert.instanceOf(error, LocationHeaderError) + assert.equal(error.message, 'Location header format is invalid: /pdp/data-sets/created/invalid-hash') + } + }) + it('should fail with no Location header', async () => { + server.use( + http.post('http://pdp.local/pdp/data-sets', () => { + return new HttpResponse(null, { + status: 201, + headers: {}, + }) + }) + ) + try { + await pdpServer.createDataSet( + 0n, // clientDataSetId + '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee + await signer.getAddress(), // payer + [], // metadata (empty for no CDN) + TEST_CONTRACT_ADDRESS // recordKeeper + ) + assert.fail('Should have thrown error for no Location header') + } catch (error) { + assert.instanceOf(error, LocationHeaderError) + assert.equal(error.message, 'Location header format is invalid: ') + } + }) + + it('should fail with CreateDataSetError string error', async () => { + server.use( + http.post('http://pdp.local/pdp/data-sets', () => { + return HttpResponse.text( + `Failed to send transaction: failed to estimate gas: message execution failed (exit=[33], revert reason=[message failed with backtrace: +00: f0169791 (method 3844450837) -- contract reverted at 75 (33) +01: f0169791 (method 6) -- contract reverted at 4535 (33) +02: f0169800 (method 3844450837) -- contract reverted at 75 (33) +03: f0169800 (method 6) -- contract reverted at 10988 (33) +04: f0169792 (method 3844450837) -- contract reverted at 1775 (33) + (RetCode=33)], vm error=[Error(invariant failure: insufficient funds to cover lockup after function execution)]) +`, + { + status: 500, + } + ) + }) + ) + try { + await pdpServer.createDataSet( + 0n, // clientDataSetId + '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee + await signer.getAddress(), // payer + [], // metadata (empty for no CDN) + TEST_CONTRACT_ADDRESS // recordKeeper + ) + assert.fail('Should have thrown error for no Location header') + } catch (error) { + assert.instanceOf(error, CreateDataSetError) + assert.equal(error.shortMessage, 'Failed to create data set.') + assert.equal( + error.message, + `Failed to create data set. + +Details: +invariant failure: insufficient funds to cover lockup after function execution` + ) + } + }) + + it('should fail with CreateDataSetError typed error', async () => { + server.use( + http.post('http://pdp.local/pdp/data-sets', () => { + return HttpResponse.text( + `Failed to send transaction: failed to estimate gas: message execution failed (exit=[33], revert reason=[message failed with backtrace: +00: f0169791 (method 3844450837) -- contract reverted at 75 (33) +01: f0169791 (method 6) -- contract reverted at 4535 (33) +02: f0169800 (method 3844450837) -- contract reverted at 75 (33) +03: f0169800 (method 6) -- contract reverted at 18957 (33) + (RetCode=33)], vm error=[0x42d750dc0000000000000000000000007e4abd63a7c8314cc28d388303472353d884f292000000000000000000000000b0ff6622d99a325151642386f65ab33a08c30213]) +`, + { + status: 500, + } + ) + }) + ) + try { + await pdpServer.createDataSet( + 0n, // clientDataSetId + '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', // payee + await signer.getAddress(), // payer + [], // metadata (empty for no CDN) + TEST_CONTRACT_ADDRESS // recordKeeper + ) + assert.fail('Should have thrown error for no Location header') + } catch (error) { + assert.instanceOf(error, CreateDataSetError) + assert.equal(error.shortMessage, 'Failed to create data set.') + assert.equal( + error.message, + `Failed to create data set. + +Details: Warm Storage +InvalidSignature(address expected, address actual) + (0x7e4ABd63A7C8314Cc28D388303472353D884f292, 0xb0fF6622D99A325151642386F65AB33a08c30213)` + ) + } + }) + }) + + describe('createAndAddPieces', () => { + it('should handle successful data set creation', async () => { + // Mock the createDataSet endpoint + const mockTxHash = '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' + const validPieceCid = ['bafkzcibcd4bdomn3tgwgrh3g532zopskstnbrd2n3sxfqbze7rxt7vqn7veigmy'] + + server.use( + http.post('http://pdp.local/pdp/data-sets/create-and-add', () => { + return new HttpResponse(null, { + status: 201, + headers: { Location: `/pdp/data-sets/created/${mockTxHash}` }, + }) + }) + ) + + const result = await pdpServer.createAndAddPieces( + 0n, + '0x70997970C51812dc3A010C7d01b50e0d17dc79C8', + await signer.getAddress(), + TEST_CONTRACT_ADDRESS, + validPieceCid, + {} + ) + + assert.strictEqual(result.txHash, mockTxHash) + assert.include(result.statusUrl, mockTxHash) + }) }) describe('getPieceAdditionStatus', () => { @@ -193,7 +359,7 @@ describe('PDPServer', () => { it('should validate input parameters', async () => { // Test empty piece entries try { - await pdpServer.addPieces(1, 0, 0, []) + await pdpServer.addPieces(1, 0n, 0, []) assert.fail('Should have thrown error for empty piece entries') } catch (error) { assert.include((error as Error).message, 'At least one piece must be provided') @@ -203,7 +369,7 @@ describe('PDPServer', () => { const invalidPieceCid = 'invalid-piece-link-string' try { - await pdpServer.addPieces(1, 0, 0, [invalidPieceCid]) + await pdpServer.addPieces(1, 0n, 0, [invalidPieceCid]) assert.fail('Should have thrown error for invalid PieceCID') } catch (error) { assert.include((error as Error).message, 'Invalid PieceCID') @@ -216,7 +382,7 @@ describe('PDPServer', () => { server.use( http.post<{ id: string }, PDPAddPiecesInput>( 'http://pdp.local/pdp/data-sets/:id/pieces', - async ({ request }) => { + async ({ request, params }) => { try { const body = await request.json() assert.isDefined(body.pieces) @@ -227,6 +393,9 @@ describe('PDPServer', () => { assert.strictEqual(body.pieces[0].subPieces[0].subPieceCid, validPieceCid[0]) // Piece is its own subPiece return HttpResponse.text('Pieces added successfully', { status: 201, + headers: { + Location: `/pdp/data-sets/${params.id}/pieces/added/0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef123456`, + }, }) } catch (error) { return HttpResponse.text((error as Error).message, { @@ -238,7 +407,7 @@ describe('PDPServer', () => { ) // Should not throw - const result = await pdpServer.addPieces(1, 0, 0, validPieceCid) + const result = await pdpServer.addPieces(1, 0n, 0, validPieceCid) assert.isDefined(result) assert.isDefined(result.message) }) @@ -256,12 +425,17 @@ describe('PDPServer', () => { ) try { - await pdpServer.addPieces(1, 0, 0, validPieceCid) + await pdpServer.addPieces(1, 0n, 0, validPieceCid) assert.fail('Should have thrown error for server error') } catch (error) { - assert.include( - (error as Error).message, - 'Failed to add pieces to data set: 400 Bad Request - Invalid piece CID' + assert.instanceOf(error, AddPiecesError) + assert.equal(error.shortMessage, 'Failed to add pieces.') + assert.equal( + error.message, + `Failed to add pieces. + +Details: Service Provider PDP +Invalid piece CID` ) } }) @@ -282,7 +456,7 @@ describe('PDPServer', () => { server.use( http.post<{ id: string }, PDPAddPiecesInput>( 'http://pdp.local/pdp/data-sets/:id/pieces', - async ({ request }) => { + async ({ request, params }) => { try { const body = await request.json() assert.strictEqual(body.pieces.length, 2) @@ -293,6 +467,9 @@ describe('PDPServer', () => { return HttpResponse.text('Multiple pieces added successfully', { status: 201, + headers: { + Location: `/pdp/data-sets/${params.id}/pieces/added/0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef123456`, + }, }) } catch (error) { return HttpResponse.text((error as Error).message, { @@ -302,7 +479,7 @@ describe('PDPServer', () => { } ) ) - const result = await pdpServer.addPieces(1, 0, 0, multiplePieceCid) + const result = await pdpServer.addPieces(1, 0n, 0, multiplePieceCid) assert.isDefined(result) assert.isDefined(result.message) }) @@ -322,55 +499,13 @@ describe('PDPServer', () => { }) ) - const result = await pdpServer.addPieces(1, 0, 0, validPieceCid) + const result = await pdpServer.addPieces(1, 0n, 0, validPieceCid) assert.isDefined(result) assert.isDefined(result.message) assert.strictEqual(result.txHash, mockTxHash) assert.include(result.statusUrl ?? '', mockTxHash) assert.include(result.statusUrl ?? '', '/pdp/data-sets/1/pieces/added/') }) - - it('should handle addPieces response with Location header missing 0x prefix', async () => { - const validPieceCid = ['bafkzcibcd4bdomn3tgwgrh3g532zopskstnbrd2n3sxfqbze7rxt7vqn7veigmy'] - const mockTxHashWithout0x = 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890' - const mockTxHashWith0x = `0x${mockTxHashWithout0x}` - - server.use( - http.post('http://pdp.local/pdp/data-sets/:id/pieces', async () => { - return HttpResponse.text('Pieces added successfully', { - status: 201, - headers: { - Location: `/pdp/data-sets/1/pieces/added/${mockTxHashWithout0x}`, - }, - }) - }) - ) - - const result = await pdpServer.addPieces(1, 0, 0, validPieceCid) - assert.isDefined(result) - assert.strictEqual(result.txHash, mockTxHashWith0x) // Should have 0x prefix added - }) - - it('should handle malformed Location header gracefully', async () => { - const validPieceCid = ['bafkzcibcd4bdomn3tgwgrh3g532zopskstnbrd2n3sxfqbze7rxt7vqn7veigmy'] - - server.use( - http.post('http://pdp.local/pdp/data-sets/:id/pieces', async () => { - return HttpResponse.text('Pieces added successfully', { - status: 201, - headers: { - Location: '/some/unexpected/path', - }, - }) - }) - ) - - const result = await pdpServer.addPieces(1, 0, 0, validPieceCid) - assert.isDefined(result) - assert.isDefined(result.message) - assert.isUndefined(result.txHash) // No txHash for malformed Location - assert.isUndefined(result.statusUrl) - }) }) describe('deletePiece', () => { @@ -389,7 +524,7 @@ describe('PDPServer', () => { }) }) ) - const result = await pdpServer.deletePiece(1, 0, 2) + const result = await pdpServer.deletePiece(1, 0n, 2) assert.strictEqual(result, mockTxHash) }) @@ -402,11 +537,18 @@ describe('PDPServer', () => { }) ) try { - await pdpServer.deletePiece(1, 0, 2) + await pdpServer.deletePiece(1, 0n, 2) assert.fail('Should have thrown error for server error') } catch (error: any) { - assert.include(error.message, 'Failed to delete piece') - assert.include(error.message, '500') + assert.instanceOf(error, DeletePieceError) + assert.equal(error.shortMessage, 'Failed to delete piece.') + assert.equal( + error.message, + `Failed to delete piece. + +Details: Service Provider PDP +Database error` + ) } }) }) @@ -475,6 +617,7 @@ describe('PDPServer', () => { }) it('should handle piece not found', async () => { + SP.setTimeout(100) const mockPieceCid = 'bafkzcibcd4bdomn3tgwgrh3g532zopskstnbrd2n3sxfqbze7rxt7vqn7veigmy' server.use( @@ -489,8 +632,15 @@ describe('PDPServer', () => { await pdpServer.findPiece(mockPieceCid) assert.fail('Should have thrown error for not found') } catch (error: any) { - assert.include(error.message, 'Piece not found') - assert.include(error.message, mockPieceCid) + assert.instanceOf(error, FindPieceError) + assert.equal(error.shortMessage, 'Failed to find piece.') + assert.equal( + error.message, + `Failed to find piece. + +Details: Service Provider PDP +Timeout waiting for piece to be found` + ) } }) @@ -519,9 +669,15 @@ describe('PDPServer', () => { await pdpServer.findPiece(mockPieceCid) assert.fail('Should have thrown error for server error') } catch (error: any) { - assert.include(error.message, 'Failed to find piece') - assert.include(error.message, '500') - assert.include(error.message, 'Database error') + assert.instanceOf(error, FindPieceError) + assert.equal(error.shortMessage, 'Failed to find piece.') + assert.equal( + error.message, + `Failed to find piece. + +Details: Service Provider PDP +Database error` + ) } }) }) @@ -795,9 +951,15 @@ describe('PDPServer', () => { await pdpServer.uploadPiece(testData) assert.fail('Should have thrown error') } catch (error: any) { - assert.include(error.message, 'Failed to create upload session') - assert.include(error.message, '500') - assert.include(error.message, 'Database error') + assert.instanceOf(error, PostPieceError) + assert.equal(error.shortMessage, 'Failed to create upload session.') + assert.equal( + error.message, + `Failed to create upload session. + +Details: Service Provider PDP +Database error` + ) } }) }) @@ -1054,14 +1216,12 @@ describe('PDPServer', () => { assert.equal(result.pieces.length, mockDataSetData.pieces.length) assert.equal(result.pieces[0].pieceId, mockDataSetData.pieces[0].pieceId) assert.equal(result.pieces[0].pieceCid.toString(), mockDataSetData.pieces[0].pieceCid) - assert.equal(result.pieces[0].subPieceCid.toString(), mockDataSetData.pieces[0].subPieceCid) - assert.equal(result.pieces[0].subPieceOffset, mockDataSetData.pieces[0].subPieceOffset) }) it('should handle data set not found', async () => { server.use( http.get('http://pdp.local/pdp/data-sets/999', async () => { - return HttpResponse.json(undefined, { + return new HttpResponse(null, { status: 404, }) }) @@ -1071,7 +1231,8 @@ describe('PDPServer', () => { await pdpServer.getDataSet(999) assert.fail('Should have thrown error for not found data set') } catch (error) { - assert.include((error as Error).message, 'Data set not found: 999') + assert.instanceOf(error, GetDataSetError) + assert.equal(error.shortMessage, 'Data set not found.') } }) @@ -1088,32 +1249,9 @@ describe('PDPServer', () => { await pdpServer.getDataSet(292) assert.fail('Should have thrown error for server error') } catch (error) { - assert.include((error as Error).message, 'Failed to fetch data set') - assert.include((error as Error).message, '500') - assert.include((error as Error).message, 'Database error') - } - }) - - it('should validate response data', async () => { - const invalidDataSetData = { - id: '292', // Should be number - pieces: 'not-array', // Should be array - nextChallengeEpoch: 'soon', // Should be number - } - - server.use( - http.get('http://pdp.local/pdp/data-sets/292', async () => { - return HttpResponse.json(invalidDataSetData, { - status: 200, - }) - }) - ) - - try { - await pdpServer.getDataSet(292) - assert.fail('Should have thrown error for invalid response data') - } catch (error) { - assert.include((error as Error).message, 'Invalid data set data response format') + assert.instanceOf(error, GetDataSetError) + assert.equal(error.shortMessage, 'Failed to get data set.') + assert.equal(error.details, 'Service Provider PDP\nDatabase error') } }) @@ -1164,7 +1302,7 @@ describe('PDPServer', () => { await pdpServer.getDataSet(292) assert.fail('Should have thrown error for invalid CID in response') } catch (error) { - assert.include((error as Error).message, 'Invalid data set data response format') + assert.include((error as Error).message, 'Invalid CID string: invalid-cid-format') } }) }) diff --git a/packages/synapse-sdk/src/test/rand.test.ts b/packages/synapse-sdk/src/test/rand.test.ts new file mode 100644 index 00000000..fcb44380 --- /dev/null +++ b/packages/synapse-sdk/src/test/rand.test.ts @@ -0,0 +1,78 @@ +/* globals describe it */ +import { assert } from 'chai' +import { fallbackRandIndex, fallbackRandU256, randIndex, randU256 } from '../utils/rand.ts' + +const randIndexMethods = [randIndex, fallbackRandIndex] +randIndexMethods.forEach((randIndexMethod) => { + describe(randIndexMethod.name, () => { + it('should return 0 for length 1', () => { + for (let i = 0; i < 32; i++) { + assert.equal(0, randIndexMethod(1)) + } + }) + it('returns both 0 and 1 for length 2', () => { + const counts = [0, 0] + for (let i = 0; i < 32; i++) { + counts[randIndexMethod(counts.length)]++ + } + // this test can fail probabilistically but the probability is low + // each bit should be independent with 50% likelihood + // the probability of getting the same index N times is 2**(1-N) + // so if this test fails, the 50% assumption is likely wrong + assert.isAtLeast(counts[0], 1) + assert.isAtLeast(counts[1], 1) + }) + it('has at least 10 random bits', () => { + const counts = [] + for (let i = 0; i < 10; i++) { + counts.push([0, 0]) + } + for (let i = 0; i < 32; i++) { + let index = randIndexMethod(1024) + assert.isAtLeast(index, 0) + assert.isAtMost(index, 1023) + for (let j = 0; j < 10; j++) { + counts[j][index & 1]++ + index >>= 1 + } + assert.equal(index, 0) + } + // this test can fail probabilistically but the probability is low + // each bit should be independent with 50% likelihood + // the probability of getting the same bitvalue N times is 2**(1-N) + // so if this test fails, the 50% assumption is likely wrong + for (let i = 0; i < 10; i++) { + assert.isAtLeast(counts[i][0], 1) + assert.isAtLeast(counts[i][1], 1) + } + }) + }) +}) + +const randU256Methods = [randU256, fallbackRandU256] +randU256Methods.forEach((randU256Method) => { + describe(randU256Method.name, () => { + it('has 256 random bits', () => { + const counts = [] + for (let i = 0; i < 256; i++) { + counts.push([0, 0]) + } + for (let j = 0; j < 32; j++) { + let rand = randU256Method() + for (let i = 0; i < 256; i++) { + counts[i][Number(rand & 1n)]++ + rand >>= 1n + } + assert.equal(rand, 0n) + } + // this test can fail probabilistically but the probability is low + // each bit should be independent with 50% likelihood + // the probability of getting the same bitvalue N times is 2**(1-N) + // so if this test fails, the 50% assumption is likely wrong + for (let i = 0; i < 256; i++) { + assert.isAtLeast(counts[i][0], 1) + assert.isAtLeast(counts[i][1], 1) + } + }) + }) +}) diff --git a/packages/synapse-sdk/src/test/retriever-chain.test.ts b/packages/synapse-sdk/src/test/retriever-chain.test.ts index 650e2c4b..cdfc90eb 100644 --- a/packages/synapse-sdk/src/test/retriever-chain.test.ts +++ b/packages/synapse-sdk/src/test/retriever-chain.test.ts @@ -84,10 +84,9 @@ const mockDataSet: EnhancedDataSetInfo = { payee: mockProvider1.serviceProvider, serviceProvider: mockProvider1.serviceProvider, commissionBps: 100, - clientDataSetId: 1, + clientDataSetId: 1n, pdpEndEpoch: 0, providerId: 1, - cdnEndEpoch: 0, paymentEndEpoch: 0, withCDN: false, pdpVerifierDataSetId: 123, @@ -95,6 +94,7 @@ const mockDataSet: EnhancedDataSetInfo = { currentPieceCount: 5, isLive: true, isManaged: true, + dataSetId: 1, metadata: {}, } @@ -202,7 +202,7 @@ describe('ChainRetriever', () => { payer: '0xClient', payee: '0xProvider1', commissionBps: 100, - clientDataSetId: 1, + clientDataSetId: 1n, paymentEndEpoch: 0, providerId: 1, isLive: true, @@ -215,7 +215,7 @@ describe('ChainRetriever', () => { payer: '0xClient', payee: '0xProvider2', commissionBps: 100, - clientDataSetId: 2, + clientDataSetId: 2n, paymentEndEpoch: 0, providerId: 2, isLive: true, diff --git a/packages/synapse-sdk/src/test/sp-registry-service.test.ts b/packages/synapse-sdk/src/test/sp-registry-service.test.ts index bf91f663..ab5624b5 100644 --- a/packages/synapse-sdk/src/test/sp-registry-service.test.ts +++ b/packages/synapse-sdk/src/test/sp-registry-service.test.ts @@ -26,31 +26,40 @@ describe('SPRegistryService', () => { getProviderByAddress: async (address: string) => { if (address.toLowerCase() === mockProviderAddress.toLowerCase()) { return { - serviceProvider: mockProviderAddress, - payee: mockProviderAddress, - name: 'Test Provider', - description: 'A test storage provider', - isActive: true, + providerId: 0n, + info: { + serviceProvider: mockProviderAddress, + payee: mockProviderAddress, + name: 'Test Provider', + description: 'A test storage provider', + isActive: true, + }, } } // Return zero address for non-existent provider return { - serviceProvider: ethers.ZeroAddress, - payee: ethers.ZeroAddress, - name: '', - description: '', - isActive: false, + providerId: 0n, + info: { + serviceProvider: ethers.ZeroAddress, + payee: ethers.ZeroAddress, + name: '', + description: '', + isActive: false, + }, } }, getProvider: async (id: number) => { if (id === 1) { return { - id: BigInt(1), - serviceProvider: mockProviderAddress, - payee: mockProviderAddress, - name: 'Test Provider', - description: 'A test storage provider', - isActive: true, + providerId: 1, + info: { + id: BigInt(1), + serviceProvider: mockProviderAddress, + payee: mockProviderAddress, + name: 'Test Provider', + description: 'A test storage provider', + isActive: true, + }, } } throw new Error('Provider not found') diff --git a/packages/synapse-sdk/src/test/synapse.test.ts b/packages/synapse-sdk/src/test/synapse.test.ts index 2d06cb43..31fec3e2 100644 --- a/packages/synapse-sdk/src/test/synapse.test.ts +++ b/packages/synapse-sdk/src/test/synapse.test.ts @@ -461,12 +461,14 @@ describe('Synapse', () => { ...presets.basic.serviceRegistry, getProviderByAddress: () => [ { - serviceProvider: ADDRESSES.zero, - payee: ADDRESSES.zero, - name: '', - description: '', - isActive: false, providerId: 0n, + info: { + serviceProvider: ADDRESSES.zero, + payee: ADDRESSES.zero, + name: '', + description: '', + isActive: false, + }, }, ], }, @@ -707,23 +709,28 @@ describe('Synapse', () => { if (data[0] === 1n) { return [ { - serviceProvider: ADDRESSES.serviceProvider1, - payee: ADDRESSES.payee1, - isActive: true, - name: 'Test Provider', - description: 'Test Provider', providerId: 1n, + info: { + serviceProvider: ADDRESSES.serviceProvider1, + payee: ADDRESSES.payee1, + isActive: true, + name: 'Test Provider', + description: 'Test Provider', + }, }, ] } return [ { - serviceProvider: ADDRESSES.zero, - payee: ADDRESSES.zero, - isActive: false, - name: '', - description: '', providerId: 0n, + info: { + serviceProvider: ADDRESSES.zero, + payee: ADDRESSES.zero, + isActive: false, + name: '', + description: '', + providerId: 0n, + }, }, ] }, diff --git a/packages/synapse-sdk/src/test/test-utils.ts b/packages/synapse-sdk/src/test/test-utils.ts index 9c79f9b9..5cf2a96f 100644 --- a/packages/synapse-sdk/src/test/test-utils.ts +++ b/packages/synapse-sdk/src/test/test-utils.ts @@ -141,8 +141,8 @@ export function createMockProvider(chainId: number = 314159): ethers.Provider { if (data?.startsWith('0xd39b33ab') === true) { return ethers.AbiCoder.defaultAbiCoder().encode(['address'], [CONTRACT_ADDRESSES.USDFC.calibration]) } - // filCDNBeneficiaryAddress() - function selector: 0xce4f8d8b - if (data?.startsWith('0xce4f8d8b') === true) { + // filBeamBeneficiaryAddress() - function selector: 0xdd6979bf + if (data?.startsWith('0xdd6979bf') === true) { return ethers.AbiCoder.defaultAbiCoder().encode(['address'], ['0x0000000000000000000000000000000000000000']) } // viewContractAddress() - function selector: 0x7a9ebc15 @@ -273,20 +273,20 @@ export function createMockProvider(chainId: number = 314159): ethers.Provider { TIME_CONSTANTS.EPOCHS_PER_MONTH, // maxLockupPeriod (30 days) ]) } - // Mock getRailsForPayerAndToken response - function selector: 0x9b85e253 - if (data.includes('9b85e253') === true) { + // Mock getRailsForPayerAndToken response - function selector: 0x007b5fd1 + if (data.includes('007b5fd1') === true) { const paymentsInterface = new ethers.Interface(CONTRACT_ABIS.PAYMENTS) const rails = [ { railId: 1n, isTerminated: false, endEpoch: 0n }, { railId: 2n, isTerminated: true, endEpoch: 999999n }, ] - return paymentsInterface.encodeFunctionResult('getRailsForPayerAndToken', [rails]) + return paymentsInterface.encodeFunctionResult('getRailsForPayerAndToken', [rails, 2, 2]) } - // Mock getRailsForPayeeAndToken response - function selector: 0x2ecfb2bf - if (data.includes('2ecfb2bf') === true) { + // Mock getRailsForPayeeAndToken response - function selector: 0x7f7562fa + if (data.includes('7f7562fa') === true) { const paymentsInterface = new ethers.Interface(CONTRACT_ABIS.PAYMENTS) const rails = [{ railId: 3n, isTerminated: false, endEpoch: 0n }] - return paymentsInterface.encodeFunctionResult('getRailsForPayeeAndToken', [rails]) + return paymentsInterface.encodeFunctionResult('getRailsForPayeeAndToken', [rails, 2, 2]) } // Mock settleRail response - function selector: 0xbcd40bf8 if (data.includes('bcd40bf8') === true) { @@ -295,6 +295,7 @@ export function createMockProvider(chainId: number = 314159): ethers.Provider { ethers.parseUnits('100', 18), // totalSettledAmount ethers.parseUnits('95', 18), // totalNetPayeeAmount ethers.parseUnits('5', 18), // totalOperatorCommission + ethers.parseUnits('1', 18), // totalNetworkFee 1000000n, // finalSettledEpoch 'Settlement successful', // note ]) @@ -627,13 +628,6 @@ export function setupProviderRegistryMocks( returnData: ethers.AbiCoder.defaultAbiCoder().encode(['address'], [CONTRACT_ADDRESSES.USDFC.calibration]), } } - // Mock filCDNAddress - if (callData.startsWith('0xf699dd7e')) { - return { - success: true, - returnData: ethers.AbiCoder.defaultAbiCoder().encode(['address'], [ethers.ZeroAddress]), - } - } // Mock viewContractAddress if (callData.startsWith('0x7a9ebc15')) { return { @@ -655,8 +649,8 @@ export function setupProviderRegistryMocks( // Handle calls to WarmStorageView contract for getApprovedProviders if (target === MOCK_ADDRESSES.WARM_STORAGE_VIEW.toLowerCase()) { - // Mock getApprovedProviders() - returns array of provider IDs - if (callData.startsWith('0x266afe1b')) { + // Mock getApprovedProviders(uint256,uint256) - returns array of provider IDs + if (callData.startsWith('0x7709a7f7')) { return { success: true, returnData: ethers.AbiCoder.defaultAbiCoder().encode(['uint256[]'], [approvedIds.map(BigInt)]), @@ -671,15 +665,30 @@ export function setupProviderRegistryMocks( const provider = providers.find((p) => p.id === providerId) if (provider) { const encoded = ethers.AbiCoder.defaultAbiCoder().encode( - ['tuple(address serviceProvider, address payee, string name, string description, bool isActive)'], - [[provider.serviceProvider, provider.payee, provider.name, provider.description || '', provider.active]] + [ + 'tuple(uint256 providerId, tuple(address serviceProvider, address payee, string name, string description, bool isActive) info)', + ], + [ + [ + providerId, + [ + provider.serviceProvider, + provider.payee, + provider.name, + provider.description || '', + provider.active, + ], + ], + ] ) return { success: true, returnData: encoded } } // Return empty provider const encoded = ethers.AbiCoder.defaultAbiCoder().encode( - ['tuple(address serviceProvider, address payee, string name, string description, bool isActive)'], - [[ethers.ZeroAddress, ethers.ZeroAddress, '', '', false]] + [ + 'tuple(uint256 providerId, tuple(address serviceProvider, address payee, string name, string description, bool isActive) info)', + ], + [[0n, [ethers.ZeroAddress, ethers.ZeroAddress, '', '', false]]] ) return { success: true, returnData: encoded } } @@ -732,7 +741,7 @@ export function setupProviderRegistryMocks( } // Mock getApprovedProviders() - returns array of provider IDs (WarmStorageView) - if (data?.startsWith('0x266afe1b')) { + if (data?.startsWith('0x7709a7f7')) { return ethers.AbiCoder.defaultAbiCoder().encode(['uint256[]'], [approvedIds.map(BigInt)]) } @@ -745,14 +754,23 @@ export function setupProviderRegistryMocks( const provider = providers.find((p) => p.id === providerId) if (provider) { return ethers.AbiCoder.defaultAbiCoder().encode( - ['tuple(address serviceProvider, address payee, string name, string description, bool isActive)'], - [[provider.serviceProvider, provider.payee, provider.name, provider.description || '', provider.active]] + [ + 'tuple(uint256 providerId, tuple(address serviceProvider, address payee, string name, string description, bool isActive) info)', + ], + [ + [ + providerId, + [provider.serviceProvider, provider.payee, provider.name, provider.description || '', provider.active], + ], + ] ) } // Return null provider (zero address indicates not found) return ethers.AbiCoder.defaultAbiCoder().encode( - ['tuple(address serviceProvider, address payee, string name, string description, bool isActive)'], - [[ethers.ZeroAddress, ethers.ZeroAddress, '', '', false]] + [ + 'tuple(uint256 providerId, tuple(address serviceProvider, address payee, string name, string description, bool isActive) info)', + ], + [[0n, [ethers.ZeroAddress, ethers.ZeroAddress, '', '', false]]] ) } @@ -849,14 +867,23 @@ export function setupProviderRegistryMocks( const provider = providers.find((p) => p.serviceProvider.toLowerCase() === addressParam.toLowerCase()) if (provider) { return ethers.AbiCoder.defaultAbiCoder().encode( - ['tuple(address serviceProvider, address payee, string name, string description, bool isActive)'], - [[provider.serviceProvider, provider.payee, provider.name, provider.description || '', provider.active]] + [ + 'tuple(uint256 providerId, tuple(address serviceProvider, address payee, string name, string description, bool isActive) info)', + ], + [ + [ + provider.id, + [provider.serviceProvider, provider.payee, provider.name, provider.description || '', provider.active], + ], + ] ) } // Return zero address struct for not found return ethers.AbiCoder.defaultAbiCoder().encode( - ['tuple(address serviceProvider, address payee, string name, string description, bool isActive)'], - [[ethers.ZeroAddress, ethers.ZeroAddress, '', '', false]] + [ + 'tuple(uint256 providerId, tuple(address serviceProvider, address payee, string name, string description, bool isActive) info)', + ], + [[0n, [ethers.ZeroAddress, ethers.ZeroAddress, '', '', false]]] ) } diff --git a/packages/synapse-sdk/src/test/warm-storage-service.test.ts b/packages/synapse-sdk/src/test/warm-storage-service.test.ts index 5dfaf63c..f94715c1 100644 --- a/packages/synapse-sdk/src/test/warm-storage-service.test.ts +++ b/packages/synapse-sdk/src/test/warm-storage-service.test.ts @@ -94,10 +94,10 @@ describe('WarmStorageService', () => { payee: '0x2345678901234567890123456789012345678901', serviceProvider: '0x3456789012345678901234567890123456789012', commissionBps: 100, - clientDataSetId: 5, + clientDataSetId: 5n, pdpEndEpoch: 0, providerId: 1, - cdnEndEpoch: 0, + dataSetId: BigInt(dataSetId), } // Use the Interface to encode the return data properly return viewInterface.encodeFunctionResult('getDataSet', [dataSetInfo]) @@ -111,7 +111,7 @@ describe('WarmStorageService', () => { assert.equal(result?.cacheMissRailId, 457) assert.equal(result?.cdnRailId, 458) assert.equal(result?.payer, '0x1234567890123456789012345678901234567890') - assert.equal(result?.clientDataSetId, 5) + assert.equal(result?.clientDataSetId, 5n) }) it('should throw for non-existent data set', async () => { @@ -130,10 +130,10 @@ describe('WarmStorageService', () => { payee: ethers.ZeroAddress, serviceProvider: ethers.ZeroAddress, commissionBps: 0, - clientDataSetId: 0, + clientDataSetId: 0n, pdpEndEpoch: 0, providerId: 0, - cdnEndEpoch: 0, + dataSetId: BigInt(dataSetId), } // Use the Interface to encode the return data properly return viewInterface.encodeFunctionResult('getDataSet', [emptyDataSet]) @@ -206,6 +206,7 @@ describe('WarmStorageService', () => { if (data?.startsWith('0x967c6f21') === true) { // Return two data sets const dataSet1 = { + id: 1n, pdpRailId: 123n, cacheMissRailId: 0n, cdnRailId: 0n, @@ -218,6 +219,7 @@ describe('WarmStorageService', () => { } const dataSet2 = { + id: 2n, pdpRailId: 456n, cacheMissRailId: 457n, cdnRailId: 458n, // Has CDN @@ -242,7 +244,7 @@ describe('WarmStorageService', () => { dataSet1.clientDataSetId, dataSet1.paymentEndEpoch, // pdpEndEpoch dataSet1.providerId, - 0, // cdnEndEpoch + dataSet1.id, ], [ dataSet2.pdpRailId, @@ -255,7 +257,7 @@ describe('WarmStorageService', () => { dataSet2.clientDataSetId, dataSet2.paymentEndEpoch, // pdpEndEpoch dataSet2.providerId, - 0, // cdnEndEpoch + dataSet2.id, ], ] @@ -274,7 +276,7 @@ describe('WarmStorageService', () => { assert.equal(dataSets[0].payer.toLowerCase(), '0x1234567890123456789012345678901234567890'.toLowerCase()) assert.equal(dataSets[0].payee.toLowerCase(), '0xabcdef1234567890123456789012345678901234'.toLowerCase()) assert.equal(dataSets[0].commissionBps, 100) - assert.equal(dataSets[0].clientDataSetId, 0) + assert.equal(dataSets[0].clientDataSetId, 0n) assert.equal(dataSets[0].cdnRailId, 0) // No CDN // Check second data set @@ -282,7 +284,7 @@ describe('WarmStorageService', () => { assert.equal(dataSets[1].payer.toLowerCase(), '0x1234567890123456789012345678901234567890'.toLowerCase()) assert.equal(dataSets[1].payee.toLowerCase(), '0x9876543210987654321098765432109876543210'.toLowerCase()) assert.equal(dataSets[1].commissionBps, 200) - assert.equal(dataSets[1].clientDataSetId, 1) + assert.equal(dataSets[1].clientDataSetId, 1n) assert.isAbove(dataSets[1].cdnRailId, 0) // Has CDN }) @@ -344,10 +346,10 @@ describe('WarmStorageService', () => { payee: '0xabcdef1234567890123456789012345678901234', serviceProvider: '0xabcdef1234567890123456789012345678901234', commissionBps: 100, - clientDataSetId: 0, + clientDataSetId: 0n, pdpEndEpoch: 0, providerId: 1, - cdnEndEpoch: 0, + dataSetId: 242n, } return viewInterface.encodeFunctionResult('getDataSet', [dataSetInfo]) } @@ -419,10 +421,10 @@ describe('WarmStorageService', () => { serviceProvider: id === 242 ? '0xabc1234567890123456789012345678901234567' : '0xdef1234567890123456789012345678901234567', commissionBps: 100, - clientDataSetId: id === 242 ? 0 : 1, + clientDataSetId: id === 242 ? 0n : 1n, pdpEndEpoch: 0, providerId: id === 242 ? 1 : 2, - cdnEndEpoch: 0, + dataSetId: BigInt(id), }) const id = dataSetIdHex === ethers.zeroPadValue('0xf2', 32).slice(2) ? 242 : 243 return viewInterface.encodeFunctionResult('getDataSet', [baseInfo(id)]) @@ -508,10 +510,10 @@ describe('WarmStorageService', () => { payee: '0xabc1234567890123456789012345678901234567', serviceProvider: '0xabc1234567890123456789012345678901234567', commissionBps: 100, - clientDataSetId: 0, + clientDataSetId: 0n, pdpEndEpoch: 0, providerId: 1, - cdnEndEpoch: 0, + dataSetId: 242n, } return viewInterface.encodeFunctionResult('getDataSet', [info]) } @@ -567,7 +569,7 @@ describe('WarmStorageService', () => { 3n, // clientDataSetId 0n, // pdpEndEpoch 1n, // providerId - 0n, // cdnEndEpoch + BigInt(dataSetId), ] return viewInterface.encodeFunctionResult('getClientDataSets', [[dataSet]]) } @@ -585,7 +587,7 @@ describe('WarmStorageService', () => { clientDataSetId: 0n, // expecting 0 pdpEndEpoch: 0n, providerId: 1n, - cdnEndEpoch: 0n, + dataSetId: BigInt(dataSetId), } return viewInterface.encodeFunctionResult('getDataSet', [info]) } @@ -597,7 +599,7 @@ describe('WarmStorageService', () => { const addPiecesInfo = await warmStorageService.getAddPiecesInfo(dataSetId) assert.equal(addPiecesInfo.nextPieceId, 5) - assert.equal(addPiecesInfo.clientDataSetId, 0) + assert.equal(addPiecesInfo.clientDataSetId, 0n) assert.equal(addPiecesInfo.currentPieceCount, 5) // Matches nextPieceId like master }) @@ -624,7 +626,7 @@ describe('WarmStorageService', () => { 3n, // clientDataSetId 0n, // pdpEndEpoch 1n, // providerId - 0n, // cdnEndEpoch + BigInt(dataSetId), ] return viewInterface.encodeFunctionResult('getClientDataSets', [[dataSet]]) } @@ -657,7 +659,6 @@ describe('WarmStorageService', () => { clientDataSetId: 3n, pdpEndEpoch: 0n, providerId: 1n, - cdnEndEpoch: 0n, } return viewInterface.encodeFunctionResult('getDataSet', [info]) } @@ -677,23 +678,6 @@ describe('WarmStorageService', () => { }) }) - describe('getNextClientDataSetId', () => { - it('should return the next client dataset ID', async () => { - const warmStorageService = await createWarmStorageService() - cleanup = mockProviderWithView((data) => { - // clientDataSetIDs mapping call - if (data?.startsWith('0x196ed89b') === true) { - return ethers.zeroPadValue('0x05', 32) // Return 5 - } - - return null - }) - - const nextId = await warmStorageService.getNextClientDataSetId(clientAddress) - assert.equal(nextId, 5) - }) - }) - describe('verifyDataSetCreation', () => { it('should verify successful data set creation', async () => { const warmStorageService = await createWarmStorageService() @@ -789,7 +773,7 @@ describe('WarmStorageService', () => { cleanup = mockProviderWithView((data) => { // getApprovedProviders selector - if (data?.startsWith('0x266afe1b') === true) { + if (data?.startsWith('0x7709a7f7') === true) { // Return array of provider IDs [1, 4, 7] return viewInterface.encodeFunctionResult('getApprovedProviders', [[1n, 4n, 7n]]) } @@ -808,7 +792,7 @@ describe('WarmStorageService', () => { cleanup = mockProviderWithView((data) => { // getApprovedProviders selector - if (data?.startsWith('0x266afe1b') === true) { + if (data?.startsWith('0x7709a7f7') === true) { // Return empty array return viewInterface.encodeFunctionResult('getApprovedProviders', [[]]) } @@ -979,7 +963,7 @@ describe('WarmStorageService', () => { cleanup = mockProviderWithView((data) => { // getApprovedProviders selector - return array with provider 4 at index 1 - if (data?.startsWith('0x266afe1b') === true) { + if (data?.startsWith('0x7709a7f7') === true) { return viewInterface.encodeFunctionResult('getApprovedProviders', [[1n, 4n, 7n]]) } return null @@ -1014,7 +998,7 @@ describe('WarmStorageService', () => { cleanup = mockProviderWithView((data) => { // getApprovedProviders selector - return array without provider 99 - if (data?.startsWith('0x266afe1b') === true) { + if (data?.startsWith('0x7709a7f7') === true) { return viewInterface.encodeFunctionResult('getApprovedProviders', [[1n, 4n, 7n]]) } return null @@ -1344,8 +1328,9 @@ describe('WarmStorageService', () => { assert.exists(check.depositAmountNeeded) assert.isTrue(check.depositAmountNeeded > 0n) - // depositAmountNeeded should equal 10 days of costs (default lockup) - const expectedDeposit = check.costs.perEpoch * BigInt(10) * BigInt(TIME_CONSTANTS.EPOCHS_PER_DAY) + // depositAmountNeeded should equal 30 days of costs (default lockup) + const expectedDeposit = + check.costs.perEpoch * TIME_CONSTANTS.DEFAULT_LOCKUP_DAYS * TIME_CONSTANTS.EPOCHS_PER_DAY assert.equal(check.depositAmountNeeded.toString(), expectedDeposit.toString()) }) @@ -1389,27 +1374,27 @@ describe('WarmStorageService', () => { return `0x${'0'.repeat(64)}` } - // Test with custom lockup period of 20 days - const customLockupDays = 20 + // Test with custom lockup period of 60 days + const customLockupDays = TIME_CONSTANTS.DEFAULT_LOCKUP_DAYS * 2n const check = await warmStorageService.checkAllowanceForStorage( Number(SIZE_CONSTANTS.GiB), // 1 GiB false, mockPaymentsService, - customLockupDays + Number(customLockupDays) ) // Verify depositAmountNeeded uses custom lockup period - const expectedDeposit = check.costs.perEpoch * BigInt(customLockupDays) * BigInt(TIME_CONSTANTS.EPOCHS_PER_DAY) + const expectedDeposit = check.costs.perEpoch * customLockupDays * TIME_CONSTANTS.EPOCHS_PER_DAY assert.equal(check.depositAmountNeeded.toString(), expectedDeposit.toString()) - // Compare with default (10 days) to ensure they're different + // Compare with default (30 days) to ensure they're different const defaultCheck = await warmStorageService.checkAllowanceForStorage( Number(SIZE_CONSTANTS.GiB), // 1 GiB false, mockPaymentsService ) - // Custom should be exactly 2x default (20 days vs 10 days) + // Custom should be exactly 2x default (60 days vs 30 days) assert.equal(check.depositAmountNeeded.toString(), (defaultCheck.depositAmountNeeded * 2n).toString()) }) }) @@ -2051,4 +2036,30 @@ describe('WarmStorageService', () => { mockProvider.call = originalCall }) }) + + describe('CDN Operations', () => { + it('should top up CDN payment rails (mock transaction)', async () => { + const dataSetId = 49 + const warmStorageService = await createWarmStorageService() + const mockSigner = { + getAddress: async () => '0x1234567890123456789012345678901234567890', + } as any + + // Mock the contract connection + const originalGetWarmStorageContract = (warmStorageService as any)._getWarmStorageContract + ;(warmStorageService as any)._getWarmStorageContract = () => ({ + connect: () => ({ + topUpCDNPaymentRails: async () => ({ + hash: '0xmocktxhash', + wait: async () => ({ status: 1 }), + }), + }), + }) + + const tx = await warmStorageService.topUpCDNPaymentRails(mockSigner, dataSetId, 1n, 1n) + assert.equal(tx.hash, '0xmocktxhash') + + ;(warmStorageService as any)._getWarmStorageContract = originalGetWarmStorageContract + }) + }) }) diff --git a/packages/synapse-sdk/src/types.ts b/packages/synapse-sdk/src/types.ts index 3ee48741..3c6125f5 100644 --- a/packages/synapse-sdk/src/types.ts +++ b/packages/synapse-sdk/src/types.ts @@ -209,15 +209,15 @@ export interface DataSetInfo { /** Commission rate in basis points (dynamic based on CDN usage) */ commissionBps: number /** Client's sequential dataset ID within this Warm Storage contract */ - clientDataSetId: number + clientDataSetId: bigint /** Epoch when PDP payments end (0 if not terminated) */ pdpEndEpoch: number /** Provider ID from the ServiceProviderRegistry */ providerId: number - /** Epoch when CDN payments end (0 if not terminated) */ - cdnEndEpoch: number // Legacy alias for backward compatibility paymentEndEpoch?: number + /** PDP Data Set ID */ + dataSetId: bigint | number } /** @@ -262,6 +262,8 @@ export interface SettlementResult { totalNetPayeeAmount: bigint /** Commission amount for operator */ totalOperatorCommission: bigint + /** Payments contract network fee */ + totalNetworkFee: bigint /** Final epoch that was settled */ finalSettledEpoch: bigint /** Note about the settlement */ @@ -331,6 +333,8 @@ export interface StorageCreationCallbacks { export interface StorageServiceOptions { /** Specific provider ID to use (optional) */ providerId?: number + /** Do not select any of these providers */ + excludeProviderIds?: number[] /** Specific provider address to use (optional) */ providerAddress?: string /** Specific data set ID to use (optional) */ diff --git a/packages/synapse-sdk/src/utils/constants.ts b/packages/synapse-sdk/src/utils/constants.ts index 70aa0ac1..4f6dc638 100644 --- a/packages/synapse-sdk/src/utils/constants.ts +++ b/packages/synapse-sdk/src/utils/constants.ts @@ -115,7 +115,7 @@ export const TIME_CONSTANTS = { /** * Default lockup period in days */ - DEFAULT_LOCKUP_DAYS: 10n, + DEFAULT_LOCKUP_DAYS: 30n, } as const /** @@ -319,7 +319,7 @@ export const CONTRACT_ADDRESSES = { */ WARM_STORAGE: { mainnet: '0x81DFD9813aDd354f03704F31419b0c6268d46232', - calibration: '0x80617b65FD2EEa1D7fDe2B4F85977670690ed348', + calibration: '0xD3De778C05f89e1240ef70100Fb0d9e5b2eFD258', } as const satisfies Record, /** diff --git a/packages/synapse-sdk/src/utils/index.ts b/packages/synapse-sdk/src/utils/index.ts index 82f151d1..b75b0c5d 100644 --- a/packages/synapse-sdk/src/utils/index.ts +++ b/packages/synapse-sdk/src/utils/index.ts @@ -5,3 +5,4 @@ export { createError } from './errors.ts' export { combineMetadata, metadataMatches } from './metadata.ts' export { getFilecoinNetworkType } from './network.ts' export { constructFindPieceUrl, constructPieceUrl } from './piece.ts' +export { randIndex, randU256 } from './rand.ts' diff --git a/packages/synapse-sdk/src/utils/rand.ts b/packages/synapse-sdk/src/utils/rand.ts new file mode 100644 index 00000000..e682615a --- /dev/null +++ b/packages/synapse-sdk/src/utils/rand.ts @@ -0,0 +1,47 @@ +const crypto = globalThis.crypto + +export function fallbackRandU256(): bigint { + let result = 0n + for (let i = 0; i < 32; i++) { + result <<= 8n + result |= BigInt(fallbackRandIndex(256)) + } + return result +} + +/** + * @returns a random unsigned big integer between `0` and `2**256-1` inclusive + */ +export function randU256(): bigint { + if (crypto?.getRandomValues != null) { + const randU64s = new BigUint64Array(4) + crypto.getRandomValues(randU64s) + let result = 0n + randU64s.forEach((randU64) => { + result <<= 64n + result |= randU64 + }) + return result + } else { + return fallbackRandU256() + } +} + +export function fallbackRandIndex(length: number): number { + return Math.floor(Math.random() * length) +} + +/** + * Provides a random index into an array of supplied length (0 <= index < length) + * @param length - exclusive upper boundary + * @returns a valid index + */ +export function randIndex(length: number): number { + if (crypto?.getRandomValues != null) { + const randomBytes = new Uint32Array(1) + crypto.getRandomValues(randomBytes) + return randomBytes[0] % length + } else { + return fallbackRandIndex(length) + } +} diff --git a/packages/synapse-sdk/src/warm-storage/service.ts b/packages/synapse-sdk/src/warm-storage/service.ts index e1544757..df95959d 100644 --- a/packages/synapse-sdk/src/warm-storage/service.ts +++ b/packages/synapse-sdk/src/warm-storage/service.ts @@ -6,6 +6,7 @@ * - Service provider registration and management * - Client dataset ID tracking * - Data set creation verification + * - CDN service management * * @example * ```typescript @@ -40,7 +41,7 @@ export interface AddPiecesInfo { /** The next piece ID to use when adding pieces */ nextPieceId: number /** The client dataset ID for this data set */ - clientDataSetId: number + clientDataSetId: bigint /** Current number of pieces in the data set */ currentPieceCount: number } @@ -114,7 +115,7 @@ export class WarmStorageService { pdpVerifier: string payments: string usdfcToken: string - filCDNBeneficiary: string + filBeamBeneficiary: string viewContract: string serviceProviderRegistry: string sessionKeyRegistry: string @@ -130,7 +131,7 @@ export class WarmStorageService { pdpVerifier: string payments: string usdfcToken: string - filCDNBeneficiary: string + filBeamBeneficiary: string viewContract: string serviceProviderRegistry: string sessionKeyRegistry: string @@ -176,7 +177,7 @@ export class WarmStorageService { { target: warmStorageAddress, allowFailure: false, - callData: iface.encodeFunctionData('filCDNBeneficiaryAddress'), + callData: iface.encodeFunctionData('filBeamBeneficiaryAddress'), }, { target: warmStorageAddress, @@ -201,7 +202,7 @@ export class WarmStorageService { pdpVerifier: iface.decodeFunctionResult('pdpVerifierAddress', results[0].returnData)[0], payments: iface.decodeFunctionResult('paymentsContractAddress', results[1].returnData)[0], usdfcToken: iface.decodeFunctionResult('usdfcTokenAddress', results[2].returnData)[0], - filCDNBeneficiary: iface.decodeFunctionResult('filCDNBeneficiaryAddress', results[3].returnData)[0], + filBeamBeneficiary: iface.decodeFunctionResult('filBeamBeneficiaryAddress', results[3].returnData)[0], viewContract: iface.decodeFunctionResult('viewContractAddress', results[4].returnData)[0], serviceProviderRegistry: iface.decodeFunctionResult('serviceProviderRegistry', results[5].returnData)[0], sessionKeyRegistry: iface.decodeFunctionResult('sessionKeyRegistry', results[6].returnData)[0], @@ -303,10 +304,10 @@ export class WarmStorageService { payee: ds.payee, serviceProvider: ds.serviceProvider, commissionBps: Number(ds.commissionBps), - clientDataSetId: Number(ds.clientDataSetId), + clientDataSetId: ds.clientDataSetId, pdpEndEpoch: Number(ds.pdpEndEpoch), providerId: Number(ds.providerId), - cdnEndEpoch: Number(ds.cdnEndEpoch), + dataSetId, } } @@ -329,10 +330,9 @@ export class WarmStorageService { payee: ds.payee, serviceProvider: ds.serviceProvider, commissionBps: Number(ds.commissionBps), - clientDataSetId: Number(ds.clientDataSetId), + clientDataSetId: ds.clientDataSetId, pdpEndEpoch: Number(ds.pdpEndEpoch), providerId: Number(ds.providerId), - cdnEndEpoch: Number(ds.cdnEndEpoch), })) } catch (error) { throw new Error(`Failed to get client data sets: ${error instanceof Error ? error.message : String(error)}`) @@ -435,11 +435,9 @@ export class WarmStorageService { ) } - const clientDataSetId = Number(dataSetInfo.clientDataSetId) - return { nextPieceId: Number(nextPieceId), - clientDataSetId, + clientDataSetId: dataSetInfo.clientDataSetId, currentPieceCount: Number(nextPieceId), } } catch (error) { @@ -447,27 +445,6 @@ export class WarmStorageService { } } - /** - * Get the next client dataset ID for a given client - * This reads the current counter from the WarmStorage contract - * @param clientAddress - The client's wallet address - * @returns next client dataset ID that will be assigned by this WarmStorage contract - */ - async getNextClientDataSetId(clientAddress: string): Promise { - try { - const viewContract = this._getWarmStorageViewContract() - - // Get the current clientDataSetIDs counter for this client in this WarmStorage contract - // This is the value that will be used for the next data set creation - const currentCounter = await viewContract.clientDataSetIDs(clientAddress) - - // Return the current counter value (it will be incremented during data set creation) - return Number(currentCounter) - } catch (error) { - throw new Error(`Failed to get next client dataset ID: ${error instanceof Error ? error.message : String(error)}`) - } - } - /** * Verify that a data set creation transaction was successful * This checks both the transaction status and on-chain data set state @@ -1032,7 +1009,7 @@ export class WarmStorageService { // First, we need to find the index of this provider in the array const viewContract = this._getWarmStorageViewContract() - const approvedIds = await viewContract.getApprovedProviders() + const approvedIds = await viewContract.getApprovedProviders(0n, 0n) const index = approvedIds.findIndex((id: bigint) => Number(id) === providerId) if (index === -1) { @@ -1048,7 +1025,7 @@ export class WarmStorageService { */ async getApprovedProviderIds(): Promise { const viewContract = this._getWarmStorageViewContract() - const providerIds = await viewContract.getApprovedProviders() + const providerIds = await viewContract.getApprovedProviders(0n, 0n) return providerIds.map((id: bigint) => Number(id)) } @@ -1103,4 +1080,32 @@ export class WarmStorageService { const window = await viewContract.challengeWindow() return Number(window) } + /** + * Increments the fixed locked-up amounts for CDN payment rails. + * + * This method tops up the prepaid balance for CDN services by adding to the existing + * lockup amounts. Both CDN and cache miss rails can be incremented independently. + * + * @param dataSetId - The ID of the data set + * @param cdnAmountToAdd - Amount to add to the CDN rail lockup + * @param cacheMissAmountToAdd - Amount to add to the cache miss rail lockup + * @returns Transaction response + */ + async topUpCDNPaymentRails( + signer: ethers.Signer, + dataSetId: number, + cdnAmountToAdd: bigint, + cacheMissAmountToAdd: bigint + ): Promise { + if (cdnAmountToAdd < 0n || cacheMissAmountToAdd < 0n) { + throw new Error('Top up amounts must be positive') + } + if (cdnAmountToAdd === 0n && cacheMissAmountToAdd === 0n) { + throw new Error('At least one top up amount must be >0') + } + + const contract = this._getWarmStorageContract() + const contractWithSigner = contract.connect(signer) as ethers.Contract + return await contractWithSigner.topUpCDNPaymentRails(dataSetId, cdnAmountToAdd, cacheMissAmountToAdd) + } } diff --git a/packages/synapse-sdk/tsconfig.json b/packages/synapse-sdk/tsconfig.json index 652d1e7f..caa2d4df 100644 --- a/packages/synapse-sdk/tsconfig.json +++ b/packages/synapse-sdk/tsconfig.json @@ -5,6 +5,11 @@ }, "include": ["src/**/*"], "exclude": ["node_modules", "dist"], + "references": [ + { + "path": "../synapse-core" + } + ], "typedocOptions": { "entryPointStrategy": "resolve", "entryPoints": [ diff --git a/packages/synapse-sdk/wagmi.config.ts b/packages/synapse-sdk/wagmi.config.ts index c2e15168..f5b02b82 100644 --- a/packages/synapse-sdk/wagmi.config.ts +++ b/packages/synapse-sdk/wagmi.config.ts @@ -2,8 +2,9 @@ import { defineConfig } from '@wagmi/cli' import { fetch } from '@wagmi/cli/plugins' import type { Address } from 'viem' -const GIT_REF = 'tags/alpha/calibnet/0x80617b65FD2EEa1D7fDe2B4F85977670690ed348-v2' -const BASE_URL = `https://raw.githubusercontent.com/FilOzone/filecoin-services/refs/${GIT_REF}/service_contracts/abi` +// GIT_REF can be one of: '', '' or 'tags/' +const GIT_REF = 'c77dfedebae55078102b45564a59914dea5338b3' +const BASE_URL = `https://raw.githubusercontent.com/FilOzone/filecoin-services/${GIT_REF.replace(/^(?![a-f0-9]{40}$)/, 'refs/')}/service_contracts/abi` const config = defineConfig(() => { const contracts = [ diff --git a/utils/README.md b/utils/README.md index e2ba31ea..c0e81b4d 100644 --- a/utils/README.md +++ b/utils/README.md @@ -192,7 +192,7 @@ Comprehensive demonstration of the enhanced payment APIs in the Synapse SDK. - **Balance**: USDFC deposited in the Payments contract for storage costs - **Rate Allowance**: Maximum per-epoch payment rate a service can set -- **Lockup Allowance**: Security deposit (10 days of storage) locked during rail creation +- **Lockup Allowance**: Security deposit (30 days of storage) locked during rail creation ## Development Notes