Skip to content

Commit

Permalink
feat!: upgrade to ucan 0.9 (#95)
Browse files Browse the repository at this point in the history
* feat: unifiy principals & signers

Co-authored-by: Hugo Dias <[email protected]>

* fix: tests on core

* fix: transport package

* chore: update client to 0.9

* feat(validator): update to ucan 0.9

* feat(server): upgrade to 0.9

* fix(principal): invalid test

* chore: update dag-ucan dep

* feat: rename caveats to nb

* fix(server): type checks

* fix(validator): increase coverage

* fix(docs): rename caveats to nb

* feat: improve decoders

* fix: types

* fix: types for .create / .invoke of capability

* fix: nb inference 98

Co-authored-by: Hugo Dias <[email protected]>
  • Loading branch information
Gozala and hugomrdias authored Sep 30, 2022
1 parent fda9c8e commit b752b39
Show file tree
Hide file tree
Showing 54 changed files with 1,495 additions and 935 deletions.
8 changes: 4 additions & 4 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { capability, URI, Link, Failure } from '@ucanto/server'
const Add = capability({
can: 'file/link',
with: URI.match({ protocol: 'file:' }),
caveats: { link: Link },
nb: { link: Link },
derives: (claimed, delegated) =>
// Can be derived if claimed capability path is contained in the delegated
// capability path.
Expand All @@ -47,7 +47,7 @@ const Add = capability({
const ensureTrailingDelimiter = uri => (uri.endsWith('/') ? uri : `${uri}/`)
```

> Please note that the library guarantees that both `claimed` and `delegated` capabilties will have `{can: "file/link", with: string, uri: URL, caveats: { link?: CID }}`
> Please note that the library guarantees that both `claimed` and `delegated` capabilties will have `{can: "file/link", with: string nb: { link?: CID }}`
> type inferred from the definition.
>
> We will explore more complicated cases later where a capability may be derived from a different capability or even a set.
Expand All @@ -61,10 +61,10 @@ import { provide, Failure, MalformedCapability } from '@ucanto/server'

const service = (context: { store: Map<string, string> }) => {
const add = provide(Add, ({ capability, invocation }) => {
store.set(capability.uri.href, capability.caveats.link)
store.set(capability.uri.href, capability.nb.link)
return {
with: capability.with,
link: capability.caveats.link,
link: capability.nb.link,
}
})

Expand Down
21 changes: 10 additions & 11 deletions packages/client/test/client.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import fetch from '@web-std/fetch'
test('encode inovocation', async () => {
/** @type {Client.ConnectionView<Service.Service>} */
const connection = Client.connect({
id: w3.principal,
id: w3,
channel: HTTP.open({ url: new URL('about:blank'), fetch }),
encoder: CAR,
decoder: CBOR,
Expand All @@ -26,7 +26,7 @@ test('encode inovocation', async () => {
capability: {
can: 'store/add',
with: alice.did(),
link: car.cid,
nb: { link: car.cid },
},
proofs: [],
})
Expand All @@ -49,8 +49,7 @@ test('encode inovocation', async () => {
{
can: 'store/add',
with: alice.did(),
// @ts-ignore
link: car.cid,
nb: { link: car.cid },
},
])
})
Expand All @@ -62,7 +61,7 @@ test('encode delegated invocation', async () => {

/** @type {Client.ConnectionView<Service.Service>} */
const connection = Client.connect({
id: w3.principal,
id: w3,
channel: HTTP.open({ url: new URL('about:blank'), fetch }),
encoder: CAR,
decoder: CBOR,
Expand All @@ -85,7 +84,7 @@ test('encode delegated invocation', async () => {
capability: {
can: 'store/add',
with: alice.did(),
link: car.cid,
nb: { link: car.cid },
},
proofs: [proof],
})
Expand All @@ -112,7 +111,7 @@ test('encode delegated invocation', async () => {
{
can: 'store/add',
with: alice.did(),
link: car.cid,
nb: { link: car.cid },
},
])

Expand Down Expand Up @@ -140,12 +139,12 @@ test('encode delegated invocation', async () => {
const service = Service.create()
/** @type {Client.ConnectionView<Service.Service>} */
const connection = Client.connect({
id: w3.principal,
id: w3,
channel: HTTP.open({
url: new URL('about:blank'),
fetch: async (url, input) => {
const invocations = await CAR.decode(input)
const promises = invocations.map((invocation) => {
const promises = invocations.map(invocation => {
const [capabality] = invocation.capabilities
switch (capabality.can) {
case 'store/add': {
Expand Down Expand Up @@ -187,7 +186,7 @@ test('execute', async () => {
capability: {
can: 'store/add',
with: alice.did(),
link: car.cid,
nb: { link: car.cid },
},
proofs: [],
})
Expand All @@ -198,7 +197,7 @@ test('execute', async () => {
capability: {
can: 'store/remove',
with: alice.did(),
link: car.cid,
nb: { link: car.cid },
},
})

Expand Down
10 changes: 5 additions & 5 deletions packages/client/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { SigningPrincipal } from '@ucanto/principal'
import * as ed25519 from '@ucanto/principal/ed25519'

/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */
export const alice = SigningPrincipal.parse(
export const alice = ed25519.parse(
'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM='
)
/** did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob */
export const bob = SigningPrincipal.parse(
export const bob = ed25519.parse(
'MgCYbj5AJfVvdrjkjNCxB3iAUwx7RQHVQ7H1sKyHy46Iose0BEevXgL1V73PD9snOCIoONgb+yQ9sycYchQC8kygR4qY='
)
/** did:key:z6MktafZTREjJkvV5mfJxcLpNBoVPwDLhTuMg9ng7dY4zMAL */
export const mallory = SigningPrincipal.parse(
export const mallory = ed25519.parse(
'MgCYtH0AvYxiQwBG6+ZXcwlXywq9tI50G2mCAUJbwrrahkO0B0elFYkl3Ulf3Q3A/EvcVY0utb4etiSE8e6pi4H0FEmU='
)

export const service = SigningPrincipal.parse(
export const service = ed25519.parse(
'MgCYKXoHVy7Vk4/QjcEGi+MCqjntUiasxXJ8uJKY0qh11e+0Bs8WsdqGK7xothgrDzzWD0ME7ynPjz2okXDh8537lId8='
)
14 changes: 7 additions & 7 deletions packages/client/test/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { the } from './services/util.js'
* @typedef {{
* can: "store/add"
* with: API.DID
* link: API.Link
* nb: { link: API.Link }
* }} Add
*
* @typedef {{
Expand All @@ -26,7 +26,7 @@ import { the } from './services/util.js'
* @typedef {{
* can: "store/remove"
* with: API.DID
* link: API.Link
* nb: { link: API.Link }
* }} Remove
*/

Expand Down Expand Up @@ -58,20 +58,20 @@ class StorageService {
// if (auth.ok) {
const result = await this.storage.add(
capability.with,
capability.link,
capability.nb.link,
/** @type {any} */ (ucan).cid
)
if (!result.error) {
if (result.status === 'in-s3') {
return {
with: capability.with,
link: capability.link,
link: capability.nb.link,
status: the('done'),
}
} else {
return {
with: capability.with,
link: capability.link,
link: capability.nb.link,
status: the('upload'),
url: 'http://localhost:9090/',
}
Expand All @@ -90,7 +90,7 @@ class StorageService {
// if (access.ok) {
const remove = await this.storage.remove(
capability.with,
capability.link,
capability.nb.link,
/** @type {any} */ (ucan).link
)
if (remove?.error) {
Expand Down Expand Up @@ -154,6 +154,6 @@ class Main {
* @param {Partial<Model>} [config]
* @returns {Service}
*/
export const create = (config) => new Main(config)
export const create = config => new Main(config)

export { Storage, Accounts }
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"dependencies": {
"@ipld/car": "^4.1.5",
"@ipld/dag-cbor": "^7.0.3",
"@ipld/dag-ucan": "3.0.0-beta",
"@ipld/dag-ucan": "^4.0.0-beta",
"@ucanto/interface": "^1.0.0",
"multiformats": "^9.8.1"
},
Expand Down
13 changes: 6 additions & 7 deletions packages/core/src/delegation.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const isLink =
* @param {API.Proof} proof
* @return {proof is API.Delegation}
*/
export const isDelegation = (proof) => !Link.isLink(proof)
export const isDelegation = proof => !Link.isLink(proof)

/**
* Represents UCAN chain view over the set of DAG UCAN nodes. You can think of
Expand Down Expand Up @@ -73,14 +73,14 @@ export class Delegation {
}

/**
* @type {API.UCAN.Principal}
* @type {API.Principal}
*/
get issuer() {
return this.data.issuer
}

/**
* @type {API.UCAN.Principal}
* @type {API.Principal}
*/
get audience() {
return this.data.audience
Expand Down Expand Up @@ -166,9 +166,8 @@ const decode = ({ bytes }) => {
* not set it defaults to 30 seconds from now. Returns UCAN in primary - IPLD
* representation.
*
* @template {number} A
* @template {API.Capabilities} C
* @param {API.DelegationOptions<C, A>} data
* @param {API.DelegationOptions<C>} data
* @param {API.EncodeOptions} [options]
* @returns {Promise<API.Delegation<C>>}
*/
Expand Down Expand Up @@ -230,7 +229,7 @@ const exportDAG = function* (root, blocks) {
* @param {Iterable<API.Block>} dag
* @returns {API.Delegation<C>}
*/
export const importDAG = (dag) => {
export const importDAG = dag => {
/** @type {Array<[string, API.Block]>} */
let entries = []
for (const block of dag) {
Expand Down Expand Up @@ -262,7 +261,7 @@ export const create = ({ root, blocks }) => new Delegation(root, blocks)
/**
* @param {API.Delegation} delegation
*/
const proofs = (delegation) => {
const proofs = delegation => {
/** @type {API.Proof[]} */
const proofs = []
const { root, blocks } = delegation
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/invocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { delegate } from './delegation.js'
* @param {API.InvocationOptions<Capability>} options
* @return {API.IssuedInvocationView<Capability>}
*/
export const invoke = (options) => new IssuedInvocation(options)
export const invoke = options => new IssuedInvocation(options)

/**
* @template {API.Capability} Capability
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export {
decode as decodeLink,
} from './link.js'
export * as UCAN from '@ipld/dag-ucan'
export * as DID from '@ipld/dag-ucan/did'
10 changes: 5 additions & 5 deletions packages/core/test/fixtures.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { SigningPrincipal } from '@ucanto/principal'
import * as ed25519 from '@ucanto/principal/ed25519'

/** did:key:z6Mkqa4oY9Z5Pf5tUcjLHLUsDjKwMC95HGXdE1j22jkbhz6r */
export const alice = SigningPrincipal.parse(
export const alice = ed25519.parse(
'MgCZT5vOnYZoVAeyjnzuJIVY9J4LNtJ+f8Js0cTPuKUpFne0BVEDJjEu6quFIU8yp91/TY/+MYK8GvlKoTDnqOCovCVM='
)
/** did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob */
export const bob = SigningPrincipal.parse(
export const bob = ed25519.parse(
'MgCYbj5AJfVvdrjkjNCxB3iAUwx7RQHVQ7H1sKyHy46Iose0BEevXgL1V73PD9snOCIoONgb+yQ9sycYchQC8kygR4qY='
)
/** did:key:z6MktafZTREjJkvV5mfJxcLpNBoVPwDLhTuMg9ng7dY4zMAL */
export const mallory = SigningPrincipal.parse(
export const mallory = ed25519.parse(
'MgCYtH0AvYxiQwBG6+ZXcwlXywq9tI50G2mCAUJbwrrahkO0B0elFYkl3Ulf3Q3A/EvcVY0utb4etiSE8e6pi4H0FEmU='
)

export const service = SigningPrincipal.parse(
export const service = ed25519.parse(
'MgCYKXoHVy7Vk4/QjcEGi+MCqjntUiasxXJ8uJKY0qh11e+0Bs8WsdqGK7xothgrDzzWD0ME7ynPjz2okXDh8537lId8='
)
8 changes: 4 additions & 4 deletions packages/core/test/invocation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test('expired invocation', async () => {
const expiration = UCAN.now() - 5
const invocation = invoke({
issuer: alice,
audience: w3.principal,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand All @@ -59,7 +59,7 @@ test('invocation with notBefore', async () => {
const notBefore = UCAN.now() + 500
const invocation = invoke({
issuer: alice,
audience: w3.principal,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand All @@ -81,7 +81,7 @@ test('invocation with notBefore', async () => {
test('invocation with nonce', async () => {
const invocation = invoke({
issuer: alice,
audience: w3.principal,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand All @@ -103,7 +103,7 @@ test('invocation with nonce', async () => {
test('invocation with facts', async () => {
const invocation = invoke({
issuer: alice,
audience: w3.principal,
audience: w3,
capability: {
can: 'store/add',
with: alice.did(),
Expand Down
10 changes: 5 additions & 5 deletions packages/core/test/lib.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ test('create delegation chain', async () => {
})
}

const data = await UCAN.issue({
const ucan = await UCAN.issue({
issuer: mallory,
audience: service,
capabilities: [
Expand All @@ -240,8 +240,8 @@ test('create delegation chain', async () => {
proofs: [delegation.cid],
})

const { cid, bytes } = await UCAN.write(data)
const root = { cid, data, bytes }
const { cid, bytes } = await UCAN.write(ucan)
const root = { cid, data: ucan.model, bytes }

{
const invocation = Delegation.create({
Expand Down Expand Up @@ -346,7 +346,7 @@ test('import delegation', async () => {
})

const replica = Delegation.import(original.export())
assert.deepEqual(original, replica)
assert.deepEqual(replica, original)

assert.equal(replica.issuer.did(), alice.did())
assert.equal(replica.audience.did(), bob.did())
Expand Down Expand Up @@ -404,7 +404,7 @@ test('issue chained delegation', async () => {
return assert.fail('must be a delegation')
}

assert.deepEqual(proof.bytes, delegation.bytes)
assert.deepEqual(delegation.bytes, proof.bytes)

assert.deepEqual([...proof.export()], [proof.root])
assert.deepEqual([...delegation.export()], [proof.root])
Expand Down
2 changes: 1 addition & 1 deletion packages/interface/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build": "tsc --build"
},
"dependencies": {
"@ipld/dag-ucan": "3.0.0-beta",
"@ipld/dag-ucan": "^4.0.0-beta",
"multiformats": "^9.8.1"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit b752b39

Please sign in to comment.