Skip to content

Commit

Permalink
feat!: add storefront filecoin api to upload api (storacha#1052)
Browse files Browse the repository at this point in the history
Adds `filecoin/*` to the `upload-api`, so that web3.storage implements
storefront capabilities

This will enable us to integrate the new API with w3infra, so that
clients can execute `filecoin/offer` to web3.storage.
  • Loading branch information
vasco-santos authored Nov 1, 2023
1 parent b232aa7 commit 39916c2
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/upload-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ jobs:
- name: Prepare
run: pnpm install

- name: Build
run: |
pnpm install
pnpm run --if-present build
- name: Check
uses: gozala/typescript-error-reporter-action@v1.0.8
with:
Expand Down
32 changes: 32 additions & 0 deletions packages/filecoin-api/test/context/queue-implementations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Queue } from './queue.js'

/**
* @param {Map<string, unknown[]>} queuedMessages
*/
export const getQueueImplementations = (
queuedMessages,
QueueImplementation = Queue
) => {
queuedMessages.set('filecoinSubmitQueue', [])
queuedMessages.set('pieceOfferQueue', [])
const filecoinSubmitQueue = new QueueImplementation({
onMessage: (message) => {
const messages = queuedMessages.get('filecoinSubmitQueue') || []
messages.push(message)
queuedMessages.set('filecoinSubmitQueue', messages)
},
})
const pieceOfferQueue = new QueueImplementation({
onMessage: (message) => {
const messages = queuedMessages.get('pieceOfferQueue') || []
messages.push(message)
queuedMessages.set('pieceOfferQueue', messages)
},
})
return {
storefront: {
filecoinSubmitQueue,
pieceOfferQueue
}
}
}
3 changes: 3 additions & 0 deletions packages/filecoin-api/test/context/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import * as API from '../../src/types.js'
import { validateAuthorization } from '../utils.js'
import { mockService } from './mocks.js'

export { getStoreImplementations } from './store-implementations.js'
export { getQueueImplementations } from './queue-implementations.js'

/**
* Mocked w3filecoin services
*/
Expand Down
23 changes: 4 additions & 19 deletions packages/filecoin-api/test/storefront.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import * as Signer from '@ucanto/principal/ed25519'
import * as StorefrontService from './services/storefront.js'
import * as StorefrontEvents from './events/storefront.js'

import { getStoreImplementations } from './context/store-implementations.js'
import { Queue } from './context/queue.js'
import { getMockService, getConnection } from './context/service.js'
import { getMockService, getConnection, getStoreImplementations, getQueueImplementations } from './context/service.js'
import { validateAuthorization } from './utils.js'

describe('storefront', () => {
Expand All @@ -26,22 +24,9 @@ describe('storefront', () => {
// resources
/** @type {Map<string, unknown[]>} */
const queuedMessages = new Map()
queuedMessages.set('filecoinSubmitQueue', [])
queuedMessages.set('pieceOfferQueue', [])
const filecoinSubmitQueue = new Queue({
onMessage: (message) => {
const messages = queuedMessages.get('filecoinSubmitQueue') || []
messages.push(message)
queuedMessages.set('filecoinSubmitQueue', messages)
},
})
const pieceOfferQueue = new Queue({
onMessage: (message) => {
const messages = queuedMessages.get('pieceOfferQueue') || []
messages.push(message)
queuedMessages.set('pieceOfferQueue', messages)
},
})
const {
storefront: { filecoinSubmitQueue, pieceOfferQueue }
} = getQueueImplementations(queuedMessages)
const {
storefront: { pieceStore, receiptStore, taskStore },
} = getStoreImplementations()
Expand Down
1 change: 1 addition & 0 deletions packages/upload-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"@web3-storage/access": "workspace:^",
"@web3-storage/capabilities": "workspace:^",
"@web3-storage/did-mailto": "workspace:^",
"@web3-storage/filecoin-api": "workspace:^",
"multiformats": "^12.1.2",
"p-retry": "^5.1.2"
},
Expand Down
7 changes: 6 additions & 1 deletion packages/upload-api/src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { createService as createAdminService } from './admin.js'
import { createService as createRateLimitService } from './rate-limit.js'
import { createService as createUcanService } from './ucan.js'
import { createService as createPlanService } from './plan.js'
import { createService as createFilecoinService } from '@web3-storage/filecoin-api/storefront/service'

export * from './types.js'

Expand All @@ -28,7 +29,10 @@ export const createServer = ({ id, codec = Legacy.inbound, ...context }) =>
...createRevocationChecker(context),
id,
codec,
service: createService(context),
service: createService({
...context,
id
}),
catch: (error) => context.errorReporter.catch(error),
})

Expand All @@ -50,6 +54,7 @@ export const createService = (context) => ({
upload: createUploadService(context),
ucan: createUcanService(context),
plan: createPlanService(context),
filecoin: createFilecoinService(context).filecoin,
})

/**
Expand Down
7 changes: 5 additions & 2 deletions packages/upload-api/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import type {
import type { ProviderInput, ConnectionView } from '@ucanto/server'

import { Signer as EdSigner } from '@ucanto/principal/ed25519'
import { StorefrontService } from '@web3-storage/filecoin-api/types'
import { ServiceContext as FilecoinServiceContext } from '@web3-storage/filecoin-api/storefront/api'
import { DelegationsStorage as Delegations } from './types/delegations.js'
import { ProvisionsStorage as Provisions } from './types/provisions.js'
import { RateLimitsStorage as RateLimits } from './types/rate-limits.js'
Expand Down Expand Up @@ -145,7 +147,7 @@ export type { RateLimitsStorage, RateLimit } from './types/rate-limits.js'
import { PlansStorage } from './types/plans.js'
export type { PlansStorage } from './types/plans.js'

export interface Service {
export interface Service extends StorefrontService {
store: {
add: ServiceMethod<StoreAdd, StoreAddSuccess, Failure>
get: ServiceMethod<StoreGet, StoreGetSuccess, StoreGetFailure>
Expand Down Expand Up @@ -328,7 +330,8 @@ export interface ServiceContext
RateLimitServiceContext,
RevocationServiceContext,
PlanServiceContext,
UploadServiceContext {}
UploadServiceContext,
FilecoinServiceContext {}

export interface UcantoServerContext extends ServiceContext, RevocationChecker {
id: Signer
Expand Down
17 changes: 17 additions & 0 deletions packages/upload-api/test/helpers/context.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as assert from 'assert'
import * as Signer from '@ucanto/principal/ed25519'
import { getStoreImplementations, getQueueImplementations } from '@web3-storage/filecoin-api/test/context/service'
import { CarStoreBucket } from '../storage/car-store-bucket.js'
import { StoreTable } from '../storage/store-table.js'
import { UploadTable } from '../storage/upload-table.js'
Expand Down Expand Up @@ -28,11 +29,22 @@ export const createContext = async (options = {}) => {
const revocationsStorage = new RevocationsStorage()
const plansStorage = new PlansStorage()
const signer = await Signer.generate()
const aggregatorSigner = await Signer.generate()
const id = signer.withDID('did:web:test.web3.storage')

/** @type {Map<string, unknown[]>} */
const queuedMessages = new Map()
const {
storefront: { filecoinSubmitQueue, pieceOfferQueue }
} = getQueueImplementations(queuedMessages)
const {
storefront: { pieceStore, receiptStore, taskStore },
} = getStoreImplementations()

/** @type { import('../../src/types.js').UcantoServerContext } */
const serviceContext = {
id,
aggregatorId: aggregatorSigner,
signer: id,
email: Email.debug(),
url: new URL('http://localhost:8787'),
Expand All @@ -51,6 +63,11 @@ export const createContext = async (options = {}) => {
uploadTable,
carStoreBucket,
dudewhereBucket,
filecoinSubmitQueue,
pieceOfferQueue,
pieceStore,
receiptStore,
taskStore,
...createRevocationChecker({ revocationsStorage }),
}

Expand Down
29 changes: 26 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 39916c2

Please sign in to comment.