Skip to content

Commit

Permalink
feat: wip publish index claim
Browse files Browse the repository at this point in the history
  • Loading branch information
alanshaw committed Jun 6, 2024
1 parent 91cb335 commit 07bcf7e
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/capabilities/src/index/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const add = capability({
with: SpaceDID,
nb: Schema.struct({
/** Content Archive (CAR) containing the `Index`. */
index: Schema.link({ code: CAR.code }),
index: Schema.link({ code: CAR.code, version: 1 }),
}),
derives: (claimed, delegated) =>
and(equalWith(claimed, delegated)) ||
Expand Down
2 changes: 1 addition & 1 deletion packages/upload-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@
"@web3-storage/access": "workspace:^",
"@web3-storage/blob-index": "workspace:^",
"@web3-storage/capabilities": "workspace:^",
"@web3-storage/content-claims": "^5.0.0",
"@web3-storage/content-claims": "^5.1.0",
"@web3-storage/did-mailto": "workspace:^",
"@web3-storage/filecoin-api": "workspace:^",
"multiformats": "^12.1.2",
Expand Down
29 changes: 26 additions & 3 deletions packages/upload-api/src/index/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as Server from '@ucanto/server'
import { ok, error } from '@ucanto/server'
import * as Index from '@web3-storage/capabilities/index'
import { ShardedDAGIndex } from '@web3-storage/blob-index'
import { Assert } from '@web3-storage/content-claims/capability'
import { concat } from 'uint8arrays'
import * as API from '../types.js'

Expand Down Expand Up @@ -61,13 +62,21 @@ const add = async ({ capability }, context) => {
shardDigests.map((s) => assertAllocated(context, space, s, 'ShardNotFound'))
)
for (const res of shardAllocRes) {
if (!res.ok) return res
if (res.error) return res
}

// TODO: randomly validate slices in the index correspond to slices in the blob

// publish the index data to IPNI
return context.ipniService.publish(idxRes.ok)
const publishRes = await Promise.all([
// publish the index data to IPNI
context.ipniService.publish(idxRes.ok),
// publish a content claim for the index
publishIndexClaim(context, { content: idxRes.ok.content, index: idxLink })
])
for (const res of publishRes) {
if (res.error) return res
}
return ok({})
}

/**
Expand All @@ -87,3 +96,17 @@ const assertAllocated = async (context, space, digest, errorName) => {
)
return ok({})
}

/**
* @param {API.ClaimsClientContext} ctx
* @param {{ content: API.UnknownLink, index: API.CARLink }} params
*/
const publishIndexClaim = async (ctx, { content, index }) => {
const { invocationConfig, connection } = ctx.claimsService
const { issuer, audience, with: resource, proofs } = invocationConfig
const expiration = Infinity
const nb = { content, index }
const conf = { issuer, audience, with: resource, nb, expiration, proofs }
const res = await Assert.index.invoke(conf).execute(connection)
return res.out
}
5 changes: 5 additions & 0 deletions packages/upload-api/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ export type {
BlobNotFound,
ShardedDAGIndex,
} from './types/index.js'
export type {
ClaimsInvocationConfig,
ClaimsClientContext,
Service as ClaimsService
} from './types/content-claims.js'

export interface Service extends StorefrontService, W3sService {
store: {
Expand Down
23 changes: 23 additions & 0 deletions packages/upload-api/src/types/content-claims.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ConnectionView, DID, Principal, Proof, Signer } from '@ucanto/interface'
import { Service } from '@web3-storage/content-claims/server/service/api'

export type { ConnectionView, DID, Principal, Proof, Signer }
export type { Service }

export interface ClaimsInvocationConfig {
/** Signing authority issuing the UCAN invocation(s). */
issuer: Signer
/** The principal delegated to in the current UCAN. */
audience: Principal
/** The resource the invocation applies to. */
with: DID
/** Proof(s) the issuer has the capability to perform the action. */
proofs?: Proof[]
}

export interface ClaimsClientContext {
claimsService: {
invocationConfig: ClaimsInvocationConfig
connection: ConnectionView<Service>
}
}
5 changes: 3 additions & 2 deletions packages/upload-api/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { MultihashDigest } from 'multiformats'
import { Failure, Result, Unit } from '@ucanto/interface'
import { ShardedDAGIndex } from '@web3-storage/blob-index/types'
import { AllocationsStorage } from './blob.js'
import { ClaimsClientContext } from './content-claims.js'

export type { ShardedDAGIndex }
export type { ShardedDAGIndex, ClaimsClientContext }

/**
* Service that allows publishing a set of multihashes to IPNI for a
Expand All @@ -26,7 +27,7 @@ export interface BlobRetriever {
): Promise<Result<ReadableStream<Uint8Array>, BlobNotFound>>
}

export interface IndexServiceContext {
export interface IndexServiceContext extends ClaimsClientContext {
allocationsStorage: AllocationsStorage
blobRetriever: BlobRetriever
ipniService: IPNIService
Expand Down
15 changes: 13 additions & 2 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 07bcf7e

Please sign in to comment.