npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@storacha/capabilities

v1.2.0

Published

UCAN Capabilities provided by storacha.network

Downloads

462

Readme

@storacha/capabilities

Capabilities for interacting with storacha.network

About

The w3up platform by storacha.network is implemented as a set of capabilities that can be invoked using the ucanto RPC framework.

The @storacha/capabilities package contains capability definitions, which are used by clients to create invocations and by services to validate and parse invocations and route requests to the correct capability handler.

See the capabilities spec for more information about each capability included in this package.

Install

Install the package:

npm install @storacha/capabilities

Usage

import * as Space from '@storacha/capabilities/space'
import * as Store from '@storacha/capabilities/store'
import * as Top from '@storacha/capabilities/top'
import * as Types from '@storacha/capabilities/types'
import * as Upload from '@storacha/capabilities/upload'
import * as Utils from '@storacha/capabilities/utils'
import * as Plan from '@storacha/capabilities/plan'
import * as Filecoin from '@storacha/capabilities/filecoin'
import * as Aggregator from '@storacha/capabilities/filecoin/aggregator'
import * as DealTracker from '@storacha/capabilities/filecoin/deal-tracker'
import * as Dealer from '@storacha/capabilities/filecoin/dealer'
import * as Index from '@storacha/capabilities/space/index'

// This package has a "main" entrypoint but we recommend the usage of the specific imports above

Capability types

The capability objects exported by this package are defined using ucanto's type-inference based capability parser. This results in concrete types that capture the details of each capability, allowing type-safe invocation and validation.

When inspecting the concrete types of a capability object (e.g. in your IDE), you may see something similar to the following:

const add: TheCapabilityParser<DerivedMatch<{
    can: "store/add";
    with: URI<"did:">;
    nb: InferCaveats<{
        link: typeof Store.Schema.Link;
        size: Store.Schema.NumberSchema<number & Phantom<{
            typeof: "integer";
        }>, unknown>;
        origin: Store.Schema.Schema<...>;
    }>;
}, CapabilityMatch<...> | DerivedMatch<...>>>

While this is a fairly complex type signature, most of the types exist to support the mechanics of the capability parser and can generally be ignored when using the capabilities. The most interesting part as a user is the definition in the DerivedMatch type constraint, which shows the inferred ability and the constraints upon the resource URI and the caveats. In the example above, the can field shows that this capability's ability is "store/add", its resource URI (the with field) must have the "did:" scheme, and there are three caveats defined in the nb field: link, size, and origin, each of which have constraints on their allowed values.

Using the exported capabilities

The capability object exposes three methods via the TheCapabilityParser interface: create, invoke, and delegate.

create

The create method returns a "materialized" capability object, which is to say, a JS object containing the can, with, and nb fields needed to fully specify a UCAN capability.

You must provide an input object containing a with resource URI that matches the constraints in the capability definition, as well as an nb object containing any caveats you want to include. If a capability has no caveats defined, or if all the caveats are optional, you may omit the nb field from the input.

const cap = Store.add.create({
  with: 'did:key:z6MkwFPNubhwM66HNKeJYtBu1Rv9n1LZdJhbyhLFg97Qr6FG',
  nb: {
    link: 'bagbaieraspawtgooy5lptr7loyd3fxjsrgkamre3y6au3ga4df5bkhrxdkmq',
    size: 20,
  }
})

The above would result in an object similar to the following:

{
  can: 'store/add',
  with: 'did:key:z6MkwFPNubhwM66HNKeJYtBu1Rv9n1LZdJhbyhLFg97Qr6FG',
  nb: {
    link: 'bagbaieraspawtgooy5lptr7loyd3fxjsrgkamre3y6au3ga4df5bkhrxdkmq',
    size: 20,
  }
}

invoke

The invoke method returns an invocation of the capability, which can be executed against a ucanto service.

Like create, invoke accepts with and nb fields, and the inputs must match the constraints in the capability definition.

Because invocations are a type of UCAN, you also need to supply some UCAN-related options. At minimum, you need to include the issuer, which is a Signer capable of signing a UCAN, and audience, which identifies the recipient by DID. You can also include any of the optional fields in the interface definition below:

interface UCANOptions {
  audience: Principal
  lifetimeInSeconds?: number
  expiration?: UCAN.UTCUnixTimestamp
  notBefore?: UCAN.UTCUnixTimestamp

  nonce?: UCAN.Nonce

  facts?: Fact[]
  proofs?: Proof[]
}

In the example below, we're generating a new Signer to act as the issuer of the invocation using the @ucanto/principal/ed25519 package. Note that in a real application, the service would likely reject an invocation from this signer, as it does not have any delegated permissions. See the access client package for more about key management and delegation in practice.

import * as DID from '@ipld/dag-ucan/did'
import * as ed25519 from '@ucanto/principal/ed25519'

const issuer = await ed25519.generate()
const audience = DID.parse('did:web:storacha.network')

const invocation = Store.add.invoke({
  issuer,
  audience,
  with: 'did:key:z6MkwFPNubhwM66HNKeJYtBu1Rv9n1LZdJhbyhLFg97Qr6FG',
  nb: {
    link: 'bagbaieraspawtgooy5lptr7loyd3fxjsrgkamre3y6au3ga4df5bkhrxdkmq',
    size: 20,
  }
})

Note that creating an invocation does not automatically execute it. To send the invocation to a service, you need a ucanto ConnectionView configured to access the service, which you can pass into the execute method on the invocation object.

const result = await invocation.execute(serviceConnection)

delegate

The delegate method allows you to create a ucanto Delegation, which allows another principal to invoke the capability.

delegate accepts the same input as invoke, however the nb field is optional. If nb is present, the values provided will act as constraints on the invocations that can be made using the delegation. For example, creating a store/add delegation with the size caveat set to 1048576 would limit invocations made using the delegation to uploads of no more than 1MiB.

import * as DID from '@ipld/dag-ucan/did'
import * as ed25519 from '@ucanto/principal/ed25519'

const issuer = await ed25519.generate()
const audience = DID.parse('did:web:storacha.network')

const delegation = await Store.add.delegate({
  issuer,
  audience,
  with: 'did:key:z6MkwFPNubhwM66HNKeJYtBu1Rv9n1LZdJhbyhLFg97Qr6FG',
})