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

w3name

v1.0.8

Published

The JavaScript API client w3name

Downloads

14,579

Readme

Getting started

Install the package using npm

npm install w3name

or yarn:

yarn add w3name

See the getting started docs for more information.

You can also find full API reference documentation for the client at https://web3-storage.github.io/w3name

Usage

The w3name package exposes several "top-level" or module-scoped functions like create, resolve, and publish, along with a few classes like Revision and Name that are returned from and accepted by the API functions.

In the examples below, the module is imported as Name using the ES module import syntax:

import * as Name from 'w3name'

If you happen to already have something called Name in scope, you can choose a different identifier when importing, or simply import the functions you need:

import { create, publish } from 'w3name'

Mutability

w3name is an implementation of IPNS (the InterPlanetary Name System), which was designed to work with IPFS (the InterPlanetary File System).

IPFS allows you to uniquely identify any piece of data using a cryptographic hash of the data itself. This is known as content addressing, and it's a very powerful and useful idea, especially when building distributed systems that span the planet (and ideally, beyond).

One of the major constraints of a content-addressed system is that all such addresses are immutable, meaning that they can't be changed to refer to something else after they've been created.

w3name and other IPNS implementations allow you to create mutable references that can be updated over time, while still providing cryptographic verification that nothing has been tampered with.

A "name" in the context of w3name is an identifier for a public key. The creator of the name can use their private key to publish records that will be returned when anyone fetches the latest value of the name. Because the name contains the verification key material, anyone can verify that the returned value was signed with the correct key and has not been tampered with since publication.

Below are some examples of the main use cases for the w3name library.

Create and Publish

The create function creates a new keypair, returing a WritableName object that can publish signed records to the w3name service.

Once you've created a WritableName, you can create the initial Revision, which contains the value that you want to publish, along with some internal data like a sequence number to keep track of revisions.

When creating the initial revision for a name, use the v0 function. Subsequent revisions will use the increment function, as described in the update section below.

With a name and a revision in hand, you're ready to call publish, which signs the revision with your key and submits it to the w3name service.

import * as Name from 'w3name'

const name = await Name.create()

console.log('Name:', name.toString())
// e.g. k51qzi5uqu5di9agapykyjh3tqrf7i14a7fjq46oo0f6dxiimj62knq13059lt

// The value to publish
const value = '/ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui'
const revision = await Name.v0(name, value)

await Name.publish(revision, name.key)

⚠️ Note: revisions live for 1 year after creation by default.

Resolve

The resolve function retrieves the latest value for a name by sending a request to the w3name service.

In the example below, we use the parse function to convert a string-encoded name into a Name object. Note that the Name returned by parse is not writable, unlike the WritableNames returned by create. As such, you can use parsed names to retrieve and verify values, but they are unable to create and update records.

import * as Name from 'w3name'

const name = Name.parse('k51qzi5uqu5di9agapykyjh3tqrf7i14a7fjq46oo0f6dxiimj62knq13059lt')

const revision = await Name.resolve(name)

console.log('Resolved value:', revision.value)
// e.g. /ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui

Update

Updating records involves creating a new revision from the previous one.

When creating the initial revision, we used the v0 function. All subsequent revisions must use the increment function, which accepts a Revision object describing the current state, and returns a new Revision with the new value and an incremented sequence number. Attempting to publish a new Revision with a sequence number thats less than or equal to the current value will result in an error.

import * as Name from 'w3name'

const name = await Name.create()

const value = '/ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui'
const revision = await Name.v0(name, value)

await Name.publish(revision, name.key)

// ...later

const nextValue = '/ipfs/bafybeiauyddeo2axgargy56kwxirquxaxso3nobtjtjvoqu552oqciudrm'
// Make a revision to the current record (increments sequence number and sets value)
const nextRevision = await Name.increment(revision, nextValue)

await Name.publish(nextRevision, name.key)

Signing Key Management

The private key used to sign IPNS records should be saved if a revision needs to be created in the future.

The WritableName object returned by the create function has a key property containing the private signing key. Using key.bytes, we can obtain a Uint8Array filled with a binary representation of the private key, which can be saved to a safe location.

Later, you can use the from function to convert from the binary representation to a WritableName object that can be used for signing and publication.

import * as Name from 'w3name'
import fs from 'fs'

// Creates a new "writable" name with a new signing key
const name = await Name.create()

// Store the signing key to a file for use later
await fs.promises.writeFile('priv.key', name.key.bytes)

// ...later

const bytes = await fs.promises.readFile('priv.key')
const name = await Name.from(bytes)

console.log('Name:', name.toString())
// e.g. k51qzi5uqu5di9agapykyjh3tqrf7i14a7fjq46oo0f6dxiimj62knq13059lt

Revision Serialization/Deserialization

The current revision for a name may need to be serialized to be stored on disk or transmitted and then deserialized later. Note that revisions are not IPNS records - they carry similar data, but are not signed.

import * as Name from 'w3name'
import fs from 'fs'

const { Revision } = Name
const name = await Name.create()
const value = '/ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui'
const revision = await Name.v0(name, value)

// Store the record to a file for use later
// Note: Revision.encode does NOT encode signing key data
await fs.promises.writeFile('ipns.revision', Revision.encode(rev))

// ...later

const bytes = await fs.promises.readFile('ipns.revision')
const revision = Revision.decode(bytes)