Public
Edited
Nov 17, 2023
3 forks
Insert cell
Insert cell
ucanto = await import('https://cdn.skypack.dev/@ucanto/core@5.0.0?min');

Insert cell
client = await import('https://cdn.skypack.dev/@ucanto/client@5.0.0?min');
Insert cell
transport = await import('https://cdn.skypack.dev/@ucanto/transport@5.0.0?min')
Insert cell
principal = await import('https://cdn.skypack.dev/@ucanto/principal@5.0.2?min')
Insert cell
params = Object.fromEntries(new URLSearchParams(html`<a href>`.search).entries())
Insert cell
Insert cell
web3storage = client.connect({
id: {
did: () => 'did:web:web3.storage'
},
encoder: transport.CAR,
decoder: transport.CBOR,
channel: transport.HTTP.open({
url: new URL('https://access.web3.storage/'),
})
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// https://github.com/web3-storage/specs/blob/main/w3-session.md#authorization-request-example
invokeAccessAuthorizeToAuthenticateAsAccount = await ucanto.invoke({
issuer: deviceA,
audience: web3storage.id,
capability: {
with: deviceA.did(),
can: 'access/authorize',
nb: {
iss: accountDID,
att: [
{can:"store/*"},
{can: "provider/add"},
],
}
}
})
Insert cell
authenticationResult = await invokeAccessAuthorizeToAuthenticateAsAccount.execute(web3storage)
Insert cell
authenticationResult.message
Insert cell
Insert cell
function assertNotError(result) {
if ('error' in result) {
throw new Error(`unexpected error result: ${result.message}`)
}
}
Insert cell
assertNotError(authenticationResult)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
claimAsDeviceA = clickedConfirmEmail, await ucanto.invoke({
issuer: deviceA,
audience: web3storage.id,
capability: {
with: deviceA.did(),
can: `access/claim`,
}
})
Insert cell
claimAsDeviceAResult = await claimAsDeviceA.execute(web3storage)
Insert cell
async function bytesToDelegation(bytes) {
const { roots, blocks } = await transport.CAR.codec.decode(bytes)
if (roots.length !== 1) throw new Error(`unexpected number of roots: ${roots.length}`)
return ucanto.Delegation.create({ root: roots[0], blocks })
}
Insert cell
claimAsDeviceADelegations = await Promise.all(Object.values(claimAsDeviceAResult.delegations).map(bytesToDelegation))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
spaceA = await principal.ed25519.generate()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof storageProvider = Inputs.radio([web3storageProvider, nftStorageProvider], {label: "Storage Provider"})
Insert cell
Insert cell
// add provider: https://github.com/web3-storage/specs/blob/main/w3-provider.md#add-paid-provider
addStorageProvider = claimAsDeviceADelegations, storageProvider && await ucanto.invoke({
issuer: deviceA,
audience: web3storage.id,
capability: {
can: 'provider/add',
with: accountDID,
nb: {
provider: storageProvider,
consumer: spaceA.did(),
}
},
proofs: claimAsDeviceADelegations
})
Insert cell
addStorageProviderResult = addStorageProvider && await addStorageProvider.execute(web3storage)
Insert cell
addStorageProviderResult
Insert cell
addStorageProviderResult && assertNotError(addStorageProviderResult)
Insert cell
* storage provider added
Insert cell
Insert cell
function authorizeAccessDelegateWithSpace (issuer, audience, space) {
return ucanto.delegate({
issuer,
audience,
capabilities: [
{
can: 'access/delegate',
with: spaceA.did(),
},
]
})
}
Insert cell
createSpaceASaysDeviceACanAccessDelegateWithSpaceA = () => authorizeAccessDelegateWithSpace(spaceA, deviceA, spaceA)
Insert cell
spaceASaysAccountACanAccessSpaceA = await ucanto.delegate({
issuer: spaceA,
audience: { did: () => accountDID },
capabilities: [
{
can: 'store/add',
with: spaceA.did(),
},
{
can: 'space/info',
with: spaceA.did(),
},
],
expiration: Infinity,
})
Insert cell
spaceASaysAccountACanAccessSpaceA.cid.toString()
Insert cell
Insert cell
delegateAccessSpaceAToAccount = addStorageProviderResult, await ucanto.invoke({
issuer: deviceA,
audience: web3storage.id,
capability: {
can: 'access/delegate',
with: spaceA.did(),
nb: {
delegations: {
[spaceASaysAccountACanAccessSpaceA.cid.toString()]: spaceASaysAccountACanAccessSpaceA.cid
}
}
},
proofs: [
await createSpaceASaysDeviceACanAccessDelegateWithSpaceA(),
// must be embedded here because it's referenced by cid in .nb.delegations
spaceASaysAccountACanAccessSpaceA,
]
})
Insert cell
delegateAccessSpaceAToAccountResult = await delegateAccessSpaceAToAccount.execute(web3storage)
Insert cell
delegateAccessSpaceAToAccountResult.message
Insert cell
Insert cell
Insert cell
deviceB = await principal.ed25519.generate()
Insert cell
deviceBDid = deviceB.did()
Insert cell
Insert cell
requestAuthorizeFromAccountToDeviceBRequest = await ucanto.invoke({
issuer: deviceB,
audience: web3storage.id,
capability: {
can: 'access/authorize',
with: deviceB.did(),
nb: {
iss: accountDID,
att: [
{can:"space/info"},
{can:"access/claim"},
{can: "provider/add"},
],
}
}
}).delegate()
Insert cell
requestAuthorizeFromAccountToDeviceBResult = {
if (!clickedConfirmEmail) {
return false
}
const [requestAuthorizeFromAccountToDeviceBResult] = await web3storage.execute(requestAuthorizeFromAccountToDeviceBRequest)
return requestAuthorizeFromAccountToDeviceBResult
}
Insert cell
Insert cell
Insert cell
claimAsDeviceBRequest = clickedConfirmEmailDeviceB, await ucanto.invoke({
issuer: deviceB,
audience: web3storage.id,
capability: {
can: 'access/claim',
with: deviceB.did(),
}
}).delegate()
Insert cell
claimAsDeviceBResponse = {
const [result] = await web3storage.execute(claimAsDeviceBRequest)
return result
}
Insert cell
{
if (claimAsDeviceBResponse.error) {
return claimAsDeviceBResponse.message
}
}
Insert cell
deviceBAccountProofs = await Promise.all(Object.values(claimAsDeviceBResponse.delegations).map(d => bytesToDelegation(d)))
Insert cell
Insert cell
claimWithAccountAsDeviceB = await ucanto.invoke({
issuer: deviceB,
audience: web3storage.id,
capability: {
can: 'access/claim',
with: accountDID,
},
proofs: [
...deviceBAccountProofs,
]
}).delegate()
Insert cell
Insert cell
claimWithAccountAsDeviceBResult = {
const [result] = await web3storage.execute(claimWithAccountAsDeviceB)
return result
}
Insert cell
Insert cell
accountDelegationsAsDeviceBAll = (!claimWithAccountAsDeviceBResult?.error) ? await decodeClaimResult(claimWithAccountAsDeviceBResult) : []
Insert cell
accountDelegationsAsDeviceB = accountDelegationsAsDeviceBAll?.filter(d => ! isDelegationExpired(d))
Insert cell
Insert cell
Insert cell
Insert cell
spaceInfoAsDeviceB = accountDelegationsAsDeviceB && await ucanto.invoke({
issuer: deviceB,
audience: web3storage.id,
capability: {
can: 'space/info',
with: spaceA.did(),
},
proofs: [
...accountDelegationsAsDeviceB,
...deviceBAccountProofs,
]
}).delegate()
Insert cell
spaceInfoAsDeviceBResult = {
const [result] = await web3storage.execute(spaceInfoAsDeviceB)
return result
}
Insert cell
resultErrorMessage(spaceInfoAsDeviceBResult)
Insert cell
Insert cell
Insert cell
Insert cell
function isDelegationExpired(d) {
return d.expiration < Date.now()
}
Insert cell
function resultErrorMessage(result) {
if (result.error) {
return result.message
}
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more