Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use w3up client final version #190

Merged
merged 3 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions can.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,11 @@ export async function blobAdd(blobPath) {
}

spinner.start('Storing')
const digest = await client.capability.blob.add(blob)
const cid = Link.create(raw.code, digest)
spinner.stopAndPersist({ symbol: '⁂', text: `Stored ${base58btc.encode(digest.bytes)} (${cid})` })
const { multihash } = await client.capability.blob.add(blob, {
receiptsEndpoint: client._receiptsEndpoint.toString()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

})
const cid = Link.create(raw.code, multihash)
spinner.stopAndPersist({ symbol: '⁂', text: `Stored ${base58btc.encode(multihash.bytes)} (${cid})` })
}

/**
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ export async function upload(firstPath, opts) {
concurrentRequests:
opts?.['concurrent-requests'] &&
parseInt(String(opts?.['concurrent-requests'])),
receiptsEndpoint: client._receiptsEndpoint.toString()
})
spinner.stopAndPersist({
symbol: '⁂',
Expand Down
8 changes: 7 additions & 1 deletion lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ export function getClient() {
process.env.W3UP_SERVICE_DID || process.env.W3_UPLOAD_SERVICE_DID
const uploadServiceURL =
process.env.W3UP_SERVICE_URL || process.env.W3_UPLOAD_SERVICE_URL
const receiptsEndpointString = (process.env.W3UP_RECEIPTS_ENDPOINT || process.env.W3_UPLOAD_RECEIPTS_URL)
let receiptsEndpoint
if (receiptsEndpointString) {
receiptsEndpoint = new URL(receiptsEndpointString)
}

let serviceConf
if (
accessServiceDID &&
Expand Down Expand Up @@ -134,7 +140,7 @@ export function getClient() {
}

/** @type {import('@web3-storage/w3up-client/types').ClientFactoryOptions} */
const createConfig = { store, serviceConf }
const createConfig = { store, serviceConf, receiptsEndpoint }

const principal = process.env.W3_PRINCIPAL
if (principal) {
Expand Down
30 changes: 15 additions & 15 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"@web3-storage/access": "^20.0.0",
"@web3-storage/data-segment": "^5.0.0",
"@web3-storage/did-mailto": "^2.1.0",
"@web3-storage/w3up-client": "^14.0.0-rc.2",
"@web3-storage/w3up-client": "^14.0.0",
"ansi-escapes": "^6.2.0",
"chalk": "^5.3.0",
"files-from-path": "^1.0.4",
Expand Down
7 changes: 7 additions & 0 deletions test/helpers/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { createEnv } from './env.js'
import { Signer } from '@ucanto/principal/ed25519'
import { createServer as createHTTPServer } from './http-server.js'
import { createReceiptsServer } from './receipt-http-server.js'
import http from 'node:http'
import { StoreConf } from '@web3-storage/w3up-client/stores/conf'
import * as FS from 'node:fs/promises'
Expand Down Expand Up @@ -49,6 +50,7 @@ export const provisionSpace = async (context, { space, account, provider }) => {
* @typedef {import('@web3-storage/w3up-client/types').StoreAddSuccess} StoreAddSuccess
* @typedef {UcantoServerTestContext & {
* server: import('./http-server').TestingServer['server']
* receiptsServer: import('./receipt-http-server.js').TestingServer['server']
* router: import('./http-server').Router
* env: { alice: Record<string, string>, bob: Record<string, string> }
* serverURL: URL
Expand All @@ -61,22 +63,26 @@ export const setup = async () => {
const { server, serverURL, router } = await createHTTPServer({
'/': context.connection.channel.request.bind(context.connection.channel),
})
const { server: receiptsServer, serverURL: receiptsServerUrl } = await createReceiptsServer()

return Object.assign(context, {
server,
serverURL,
receiptsServer,
router,
serverRouter: router,
env: {
alice: createEnv({
storeName: `w3cli-test-alice-${context.service.did()}`,
servicePrincipal: context.service,
serviceURL: serverURL,
receiptsEndpoint: new URL('receipt', receiptsServerUrl),
}),
bob: createEnv({
storeName: `w3cli-test-bob-${context.service.did()}`,
servicePrincipal: context.service,
serviceURL: serverURL,
receiptsEndpoint: new URL('receipt', receiptsServerUrl),
}),
},
})
Expand All @@ -88,6 +94,7 @@ export const setup = async () => {
export const teardown = async (context) => {
await cleanupContext(context)
context.server.close()
context.receiptsServer.close()

const stores = [
context.env.alice.W3_STORE_NAME,
Expand Down
4 changes: 3 additions & 1 deletion test/helpers/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
* @param {import('@ucanto/interface').Principal} [options.servicePrincipal]
* @param {URL} [options.serviceURL]
* @param {string} [options.storeName]
* @param {URL} [options.receiptsEndpoint]
*/
export function createEnv(options = {}) {
const { servicePrincipal, serviceURL, storeName } = options
const { servicePrincipal, serviceURL, storeName, receiptsEndpoint } = options
const env = { W3_STORE_NAME: storeName ?? 'w3cli-test' }
if (servicePrincipal && serviceURL) {
Object.assign(env, {
W3UP_SERVICE_DID: servicePrincipal.did(),
W3UP_SERVICE_URL: serviceURL.toString(),
W3UP_RECEIPTS_ENDPOINT: receiptsEndpoint?.toString()
})
}
return env
Expand Down
61 changes: 61 additions & 0 deletions test/helpers/random.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { CarWriter } from '@ipld/car'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import * as CAR from '@ucanto/transport/car'
import { CID } from 'multiformats/cid'
import * as raw from 'multiformats/codecs/raw'
import { sha256 } from 'multiformats/hashes/sha2'

/** @param {number} size */
export async function randomBytes(size) {
const bytes = new Uint8Array(size)
while (size) {
const chunk = new Uint8Array(Math.min(size, 65_536))
if (!globalThis.crypto) {
try {
const { webcrypto } = await import('node:crypto')
webcrypto.getRandomValues(chunk)
} catch (err) {
throw new Error(
'unknown environment - no global crypto and not Node.js',
{ cause: err }
)
}
} else {
crypto.getRandomValues(chunk)
}
size -= chunk.length
bytes.set(chunk, size)
}
return bytes
}

/** @param {number} size */
export async function randomCAR(size) {
const bytes = await randomBytes(size)
return toCAR(bytes)
}

/** @param {Uint8Array} bytes */
export async function toBlock(bytes) {
const hash = await sha256.digest(bytes)
const cid = CID.createV1(raw.code, hash)
return { cid, bytes }
}

/**
* @param {Uint8Array} bytes
*/
export async function toCAR(bytes) {
const block = await toBlock(bytes)
const { writer, out } = CarWriter.create(block.cid)
writer.put(block)
writer.close()

const chunks = []
for await (const chunk of out) {
chunks.push(chunk)
}
const blob = new Blob(chunks)
const cid = await CAR.codec.link(new Uint8Array(await blob.arrayBuffer()))

return Object.assign(blob, { cid, roots: [block.cid] })
}
79 changes: 79 additions & 0 deletions test/helpers/receipt-http-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import http from 'http'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { once } from 'events'

import { parseLink } from '@ucanto/server'
import * as Signer from '@ucanto/principal/ed25519'
import { Receipt, Message } from '@ucanto/core'
import * as CAR from '@ucanto/transport/car'
import { Assert } from '@web3-storage/content-claims/capability'
import { randomCAR } from './random.js'

/**
* @typedef {{
* server: http.Server
* serverURL: URL
* }} TestingServer
*/

/**
* @returns {Promise<TestingServer>}
*/
export async function createReceiptsServer() {
/**
* @param {http.IncomingMessage} request
* @param {http.ServerResponse} response
*/
const listener = async (request, response) => {
const taskCid = request.url?.split('/')[1] ?? ''
const body = await generateReceipt(taskCid)
response.writeHead(200)
response.end(body)
return undefined
}

const server = http.createServer(listener).listen()

await once(server, 'listening')

return {
server,
// @ts-expect-error
serverURL: new URL(`http://127.0.0.1:${server.address().port}`),
}
}

/**
* @param {string} taskCid
*/
const generateReceipt = async (taskCid) => {
const issuer = await Signer.generate()
const content = (await randomCAR(128)).cid
const locationClaim = await Assert.location.delegate({
issuer,
audience: issuer,
with: issuer.toDIDKey(),
nb: {
content,
location: ['http://localhost'],
},
expiration: Infinity,
})

const receipt = await Receipt.issue({
issuer,
fx: {
fork: [locationClaim],
},
ran: parseLink(taskCid),
result: {
ok: {
site: locationClaim.link(),
},
},
})

const message = await Message.build({
receipts: [receipt],
})
return CAR.request.encode(message).body
}