@storacha/client
Version:
Client for the storacha.network w3up api
156 lines • 4.72 kB
JavaScript
import { conclude } from '@storacha/capabilities/ucan';
import { Receipt } from '@ucanto/core';
import * as Server from '@ucanto/server';
import { UCAN } from '@storacha/capabilities';
import * as HTTP from '@storacha/capabilities/http';
import * as W3sBlobCapabilities from '@storacha/capabilities/web3.storage/blob';
import { W3sBlob } from '@storacha/capabilities';
import * as Types from '../../src/types.js';
export const validateAuthorization = () => ({ ok: {} });
export const receiptsEndpoint = 'http://localhost:9201';
/**
* Utility function that creates a delegation from account to agent and an
* attestation from service to proof it. Proofs can be used to invoke any
* capability on behalf of the account.
*
* @param {object} input
* @param {Types.UCAN.Signer<Types.AccountDID>} input.account
* @param {Types.Signer<Types.DID>} input.service
* @param {Types.Signer} input.agent
*/
export const createAuthorization = async ({ account, agent, service }) => {
// Issue authorization from account DID to agent DID
const authorization = await Server.delegate({
issuer: account,
audience: agent,
capabilities: [
{
with: 'ucan:*',
can: '*',
},
],
expiration: Infinity,
});
const attest = await UCAN.attest
.invoke({
issuer: service,
audience: agent,
with: service.did(),
nb: {
proof: authorization.cid,
},
expiration: Infinity,
})
.delegate();
return [authorization, attest];
};
// FIXME this code has been copied over from upload-api
/**
* @param {import('@ucanto/interface').Signer} id
* @param {import('@ucanto/interface').Verifier} serviceDid
* @param {import('@ucanto/interface').Receipt} receipt
*/
function createConcludeInvocation(id, serviceDid, receipt) {
const receiptBlocks = [];
const receiptCids = [];
for (const block of receipt.iterateIPLDBlocks()) {
receiptBlocks.push(block);
receiptCids.push(block.cid);
}
const concludeAllocatefx = conclude.invoke({
issuer: id,
audience: serviceDid,
with: id.toDIDKey(),
nb: {
receipt: receipt.link(),
},
expiration: Infinity,
facts: [
{
...receiptCids,
},
],
});
for (const block of receiptBlocks) {
concludeAllocatefx.attach(block);
}
return concludeAllocatefx;
}
export const setupBlobAddResponse = async function (
// @ts-ignore
{ issuer, with: space, proofs, audience },
// @ts-ignore
invocation) {
const blob = invocation.capabilities[0].nb.blob;
const blobAllocateTask = await W3sBlob.allocate
.invoke({
issuer,
audience,
with: space.did(),
nb: {
blob,
cause: invocation.link(),
space: space.did(),
},
expiration: Infinity,
})
.delegate();
const blobAllocateReceipt = await Receipt.issue({
issuer,
ran: blobAllocateTask.cid,
result: { ok: {} },
});
const blobConcludeAllocate = await createConcludeInvocation(issuer, audience, blobAllocateReceipt).delegate();
const blobPutTask = await HTTP.put
.invoke({
issuer,
audience,
with: space.toDIDKey(),
nb: {
body: blob,
url: {
'ucan/await': ['.out.ok.address.url', blobAllocateTask.link()],
},
headers: {
'ucan/await': ['.out.ok.address.headers', blobAllocateTask.link()],
},
},
facts: [
{
keys: audience.toArchive(),
},
],
expiration: Infinity,
})
.delegate();
const blobAcceptTask = await W3sBlobCapabilities.accept
.invoke({
issuer,
audience,
with: space.did(),
nb: {
blob,
space: space.did(),
_put: { 'ucan/await': ['.out.ok', blobPutTask.link()] },
},
proofs,
})
.delegate();
const blobAcceptReceipt = await Receipt.issue({
issuer,
ran: blobAcceptTask.cid,
result: { ok: {} },
});
const blobConcludeAccept = await createConcludeInvocation(issuer, audience, blobAcceptReceipt).delegate();
return Server.ok({
site: {
'ucan/await': ['.out.ok.site', blobAcceptTask.link()],
},
})
.fork(blobAllocateTask)
.fork(blobConcludeAllocate)
.fork(blobPutTask)
.join(blobAcceptTask)
.fork(blobConcludeAccept);
};
//# sourceMappingURL=utils.js.map