web3.storage
Advanced tools
@@ -14,3 +14,3 @@ import type { UnixFSEntry } from 'ipfs-car/unpack'; | ||
| export interface Service { | ||
| endpoint: URL; | ||
| endpoint?: URL; | ||
| token: string; | ||
@@ -20,6 +20,2 @@ rateLimiter?: RateLimiter; | ||
| } | ||
| export interface PublicService { | ||
| endpoint: URL; | ||
| rateLimiter?: RateLimiter; | ||
| } | ||
| /** | ||
@@ -26,0 +22,0 @@ * CID in string representation. |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AACvC,YAAY,EAAE,GAAG,EAAE,WAAW,EAAE,CAAA;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,EACL,KAAK,IAAI,MAAM,EAChB,MAAM,aAAa,CAAA;AAEpB;;GAEG;AACH,oBAAY,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,GAAG,CAAA;CAAE,CAAA;AAE9C,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,GAAG,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,KAAK,CAAC,EAAE,OAAO,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,GAAG,CAAA;IACb,WAAW,CAAC,EAAE,WAAW,CAAA;CAC1B;AAED;;GAEG;AACH,oBAAY,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAE3C,MAAM,WAAW,GAAG;IAClB;;OAEG;IACH,GAAG,CACD,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,EACzB,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,SAAS,CAAC,CAAA;IAErB;;OAEG;IACH,MAAM,CACJ,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,SAAS,CAAC,CAAA;IAErB;;OAEG;IACH,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAA;IAEnE;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IAEtF;;OAEG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAE/F;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,WAAW,GAAI,aAAa,CAAC,MAAM,CAAC,CAAA;CACtE;AAED,MAAM,WAAW,QAAQ;IACvB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAA;IACZ;;;OAGG;IACH,MAAM,EAAE,MAAM,cAAc,CAAA;CAC7B;AAED,oBAAY,cAAc,GAAG;IAC3B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAA;CACrB,CAAA;AAED,oBAAY,UAAU,GAAG,cAAc,GAAG;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAA;IACzC;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACtC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,oBAAY,aAAa,GAAG,cAAc,GAAG;IAC3C;;OAEG;IACF,IAAI,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACF,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;OAEG;IACF,UAAU,CAAC,EAAE,MAAM,CAAA;IACpB;;OAEG;IACF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAA;CACrC,CAAA;AAED,oBAAY,WAAW,GAAG,cAAc,GAAG;IACzC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,WAAW,QAAS,SAAQ,IAAI;IACpC;;OAEG;IACH,GAAG,EAAE,SAAS,CAAA;CACf;AAED,MAAM,WAAW,YAAa,SAAQ,QAAQ;IAC5C,cAAc,EAAE,MAAM,aAAa,CAAC,WAAW,CAAC,CAAA;IAChD,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,GAAG;IAClB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;IAC1C;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,IAAI;IACnB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAA;IACd;;OAEG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;OAEG;IACH,MAAM,EAAE,QAAQ,GAAG,WAAW,GAAG,QAAQ,CAAA;IACzC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAA;IACzB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,MAAM;IACrB;;OAEG;IACH,GAAG,EAAE,SAAS,CAAA;IACd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,OAAO,EAAE,MAAM,CAAA;IACf;;OAEG;IACH,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;IAChB;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;CACnB;AAED,MAAM,WAAW,MAAO,SAAQ,MAAM;IACpC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CAClB"} | ||
| {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/lib/interface.ts"],"names":[],"mappings":"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"} |
+34
-306
@@ -5,18 +5,4 @@ 'use strict'; | ||
| var fromString = require('uint8arrays/from-string'); | ||
| var toString = require('uint8arrays/to-string'); | ||
| var ipns = require('ipns'); | ||
| var Digest = require('multiformats/hashes/digest'); | ||
| var identity = require('multiformats/hashes/identity'); | ||
| var base36 = require('multiformats/bases/base36'); | ||
| var cid = require('multiformats/cid'); | ||
| var libp2pCrypto = require('libp2p-crypto'); | ||
| var cbor = require('cborg'); | ||
| var _fetch = require('@web-std/fetch'); | ||
| require('@web-std/blob'); | ||
| require('@web-std/file'); | ||
| require('ipfs-car/blockstore/fs'); | ||
| var w3name = require('w3name'); | ||
| function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
| function _interopNamespace(e) { | ||
@@ -40,48 +26,24 @@ if (e && e.__esModule) return e; | ||
| var ipns__namespace = /*#__PURE__*/_interopNamespace(ipns); | ||
| var Digest__namespace = /*#__PURE__*/_interopNamespace(Digest); | ||
| var cbor__namespace = /*#__PURE__*/_interopNamespace(cbor); | ||
| var _fetch__default = /*#__PURE__*/_interopDefaultLegacy(_fetch); | ||
| var w3name__namespace = /*#__PURE__*/_interopNamespace(w3name); | ||
| /** | ||
| * A client library for the w3name - IPNS over HTTP API. It provides a | ||
| * convenient interface for creating names, making revisions to name records, | ||
| * and publishing and resolving them via the HTTP API. | ||
| * | ||
| * @example | ||
| * ```js | ||
| * import { Web3Storage } from 'web3.storage' | ||
| * import * as Name from 'web3.storage/name' | ||
| * | ||
| * const client = new Web3Storage({ token: API_TOKEN }) | ||
| * 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) | ||
| * | ||
| * // Publish the revision | ||
| * await Name.publish(client, revision, name.key) | ||
| * | ||
| * // Resolve the latest value | ||
| * await Name.resolve(name) | ||
| * ``` | ||
| * @module | ||
| * This module exists only to provide maintain the existing functionality to allow a | ||
| * smooth transition to the new 'w3name' package. This module will be later removed. | ||
| */ | ||
| const libp2pKeyCode = 0x72; | ||
| const ONE_YEAR = 1000 * 60 * 60 * 24 * 365; | ||
| console.warn('The name.js module is deprecated. You should use the new \'w3name\' npm package instead.'); | ||
| const defaultValidity = () => new Date(Date.now() + ONE_YEAR).toISOString(); | ||
| const { | ||
| Name, | ||
| WritableName, | ||
| create, | ||
| parse, | ||
| from, | ||
| v0, | ||
| increment, | ||
| Revision | ||
| } = w3name__namespace; | ||
| /** | ||
| * @typedef {{ | ||
| * bytes: Uint8Array, | ||
| * verify (data: Uint8Array, signature: Uint8Array): Promise<boolean> | ||
| * }} PublicKey | ||
| * | ||
| * @typedef {{ | ||
| * sign (data: Uint8Array): Promise<Uint8Array> | ||
@@ -91,271 +53,37 @@ * }} SigningKey | ||
| * @typedef {{ | ||
| * public: PublicKey, | ||
| * bytes: Uint8Array | ||
| * } & SigningKey} PrivateKey | ||
| * endpoint: URL | ||
| * rateLimiter?: function | ||
| * }} PublicService | ||
| */ | ||
| /** | ||
| * Name is an IPNS key ID. | ||
| */ | ||
| class Name { | ||
| /** | ||
| * @param {PublicKey} pubKey Public key. | ||
| */ | ||
| constructor (pubKey) { | ||
| /** | ||
| * @private | ||
| */ | ||
| this._pubKey = pubKey; | ||
| } | ||
| /* eslint-disable no-unused-vars */ | ||
| get bytes () { | ||
| const digest = Digest__namespace.create(identity.identity.code, this._pubKey.bytes); | ||
| return cid.CID.createV1(libp2pKeyCode, digest).bytes | ||
| } | ||
| toString () { | ||
| const digest = Digest__namespace.create(identity.identity.code, this._pubKey.bytes); | ||
| return cid.CID.createV1(libp2pKeyCode, digest).toString(base36.base36) | ||
| } | ||
| } | ||
| /** | ||
| * WritableName is a Name that has a signing key associated with it such that | ||
| * new IPNS record revisions can be created and signed for it. | ||
| */ | ||
| class WritableName extends Name { | ||
| /** | ||
| * @param {PrivateKey} privKey | ||
| */ | ||
| constructor (privKey) { | ||
| super(privKey.public); | ||
| /** | ||
| * @private | ||
| */ | ||
| this._privKey = privKey; | ||
| } | ||
| get key () { | ||
| return this._privKey | ||
| } | ||
| } | ||
| /** | ||
| * Create a new name with associated signing key that can be used to create and | ||
| * publish IPNS record revisions. | ||
| * Proxy the old `publish` function arguments through to the new version. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| */ | ||
| async function create () { | ||
| const privKey = await libp2pCrypto.keys.generateKeyPair('Ed25519', 2048); | ||
| return new WritableName(privKey) | ||
| } | ||
| /** | ||
| * Parses string name to readable name. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {string} name The name to parse. | ||
| */ | ||
| function parse (name) { | ||
| const keyCid = cid.CID.parse(name, base36.base36); | ||
| if (keyCid.code !== libp2pKeyCode) { | ||
| throw new Error(`invalid key, expected ${libp2pKeyCode} codec code but got ${keyCid.code}`) | ||
| } | ||
| const pubKey = libp2pCrypto.keys.unmarshalPublicKey(Digest__namespace.decode(keyCid.multihash.bytes).bytes); | ||
| return new Name(pubKey) | ||
| } | ||
| /** | ||
| * Create a name from an existing signing key (private key). | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Uint8Array} key Binary representation of the signing key for the name. | ||
| */ | ||
| async function from (key) { | ||
| const privKey = await libp2pCrypto.keys.unmarshalPrivateKey(key); | ||
| return new WritableName(privKey) | ||
| } | ||
| /** | ||
| * Create an initial version of the IPNS record for the passed name, set to the | ||
| * passed value. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Name} name | ||
| * @param {string} value | ||
| */ | ||
| async function v0 (name, value) { | ||
| return new Revision(name, value, 0n, defaultValidity()) | ||
| } | ||
| /** | ||
| * Create a revision of the passed IPNS record by incrementing the sequence | ||
| * number and changing the value. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Revision} revision | ||
| * @param {string} value | ||
| */ | ||
| async function increment (revision, value) { | ||
| const seqno = revision.sequence + 1n; | ||
| return new Revision(revision.name, value, seqno, defaultValidity()) | ||
| } | ||
| /** | ||
| * A represetation of a IPNS record that may be initial or revised. | ||
| */ | ||
| class Revision { | ||
| /** | ||
| * @param {Name} name | ||
| * @param {string} value | ||
| * @param {bigint} sequence | ||
| * @param {string} validity | ||
| */ | ||
| constructor (name, value, sequence, validity) { | ||
| this._name = name; | ||
| if (typeof value !== 'string') { | ||
| throw new Error('invalid value') | ||
| } | ||
| this._value = value; | ||
| if (typeof sequence !== 'bigint') { | ||
| throw new Error('invalid sequence number') | ||
| } | ||
| this._sequence = sequence; | ||
| if (typeof validity !== 'string') { | ||
| throw new Error('invalid validity') | ||
| } | ||
| // TODO: validate format | ||
| this._validity = validity; | ||
| } | ||
| get name () { | ||
| return this._name | ||
| } | ||
| get value () { | ||
| return this._value | ||
| } | ||
| get sequence () { | ||
| return this._sequence | ||
| } | ||
| /** | ||
| * RFC3339 date string. | ||
| */ | ||
| get validity () { | ||
| return this._validity | ||
| } | ||
| /** | ||
| * Note: if `revision.name` is a `WritableName` then signing key data will be | ||
| * lost. i.e. the private key is not encoded. | ||
| * | ||
| * @param {Revision} revision Revision to encode. | ||
| */ | ||
| static encode (revision) { | ||
| return cbor__namespace.encode({ | ||
| name: revision._name.toString(), | ||
| value: revision._value, | ||
| sequence: revision._sequence, | ||
| validity: revision._validity | ||
| }) | ||
| } | ||
| /** | ||
| * @param {Uint8Array} bytes | ||
| */ | ||
| static decode (bytes) { | ||
| const raw = cbor__namespace.decode(bytes); | ||
| const name = parse(raw.name); | ||
| return new Revision(name, raw.value, BigInt(raw.sequence), raw.validity) | ||
| } | ||
| } | ||
| /** | ||
| * Publish a name revision to Web3.Storage. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * ⚠️ Name records are not _yet_ published to or updated from the IPFS network. | ||
| * Working with name records simply updates the Web3.Storage cache of data. | ||
| * | ||
| * @param {import('./lib/interface.js').Service} service | ||
| * @param {Revision} revision Revision of record to publish. | ||
| * @param {w3name.Revision} revision Revision of record to publish. | ||
| * @param {SigningKey} key Private key to sign the record with. | ||
| */ | ||
| // @ts-expect-error | ||
| async function publish (service, revision, key) { | ||
| const url = new URL(`name/${revision.name}`, service.endpoint); | ||
| const entry = await ipns__namespace.create( | ||
| // @ts-expect-error API expects a libp2p-crypto.PrivateKey but only uses SigningKey.sign(). | ||
| key, | ||
| fromString.fromString(revision.value), | ||
| revision.sequence, | ||
| new Date(revision.validity).getTime() - Date.now() | ||
| ); | ||
| const res = await maybeHandleError(_fetch__default["default"](url.toString(), { | ||
| method: 'POST', | ||
| headers: headers(service.token), | ||
| body: toString.toString(ipns__namespace.marshal(entry), 'base64pad') | ||
| })); | ||
| await res.json(); | ||
| // The user _might_ have overridden the endpoint in the service, but it's unlikely and | ||
| // this library is only really intended for use with the w3name endpoint anyway. The | ||
| // most likely use case for overriding it is for tests, which no longer exist for this | ||
| // module because it's now just a proxy. | ||
| // @ts-ignore key type is libp2p-crypto PrivateKey instead of SigningKey | ||
| return await w3name__namespace.publish(revision, key) | ||
| } | ||
| /** | ||
| * Resolve the current IPNS record revision for the passed name. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {import('./lib/interface.js').PublicService} service | ||
| * @param {Name} name The name to resolve. | ||
| * Proxy the old function arguments to the new version. | ||
| * @param {PublicService} service | ||
| * @param {w3name.Name} name The name to resolve. | ||
| */ | ||
| // @ts-expect-error | ||
| async function resolve (service, name) { | ||
| const url = new URL(`name/${name}`, service.endpoint); | ||
| const res = await maybeHandleError(_fetch__default["default"](url.toString())); | ||
| const { record } = await res.json(); | ||
| const entry = ipns__namespace.unmarshal(fromString.fromString(record, 'base64pad')); | ||
| const keyCid = cid.CID.decode(name.bytes); | ||
| const pubKey = libp2pCrypto.keys.unmarshalPublicKey(Digest__namespace.decode(keyCid.multihash.bytes).bytes); | ||
| await ipns__namespace.validate(pubKey, entry); | ||
| return new Revision( | ||
| name, | ||
| toString.toString(entry.value), | ||
| entry.sequence, | ||
| toString.toString(entry.validity) | ||
| ) | ||
| // Same reasoning as in `publish`, we ignore the `service` arg. | ||
| return await w3name__namespace.resolve(name) | ||
| } | ||
| /** | ||
| * @param {string} token | ||
| * @returns {Record<string, string>} | ||
| */ | ||
| function headers (token) { | ||
| if (!token) throw new Error('missing token') | ||
| return { | ||
| Authorization: `Bearer ${token}`, | ||
| 'X-Client': 'web3.storage' | ||
| } | ||
| } | ||
| /** | ||
| * @param {Promise<Response>} resPromise | ||
| * @returns {Promise<Response>} | ||
| */ | ||
| async function maybeHandleError (resPromise) { | ||
| const res = await resPromise; | ||
| if (res.ok) return res | ||
| const err = new Error(`unexpected status: ${res.status}`); | ||
| try { | ||
| Object.assign(err, await res.json()); | ||
| } catch {} | ||
| throw err | ||
| } | ||
| exports.Name = Name; | ||
@@ -362,0 +90,0 @@ exports.Revision = Revision; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"name.cjs","sources":["../../src/name.js"],"sourcesContent":["/**\n * A client library for the w3name - IPNS over HTTP API. It provides a\n * convenient interface for creating names, making revisions to name records,\n * and publishing and resolving them via the HTTP API.\n *\n * @example\n * ```js\n * import { Web3Storage } from 'web3.storage'\n * import * as Name from 'web3.storage/name'\n *\n * const client = new Web3Storage({ token: API_TOKEN })\n * const name = await Name.create()\n *\n * console.log('Name:', name.toString())\n * // e.g. k51qzi5uqu5di9agapykyjh3tqrf7i14a7fjq46oo0f6dxiimj62knq13059lt\n *\n * // The value to publish\n * const value = '/ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui'\n * const revision = await Name.v0(name, value)\n *\n * // Publish the revision\n * await Name.publish(client, revision, name.key)\n *\n * // Resolve the latest value\n * await Name.resolve(name)\n * ```\n * @module\n */\nimport { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'\nimport { toString as uint8ArrayToString } from 'uint8arrays/to-string'\nimport * as ipns from 'ipns'\nimport * as Digest from 'multiformats/hashes/digest'\nimport { identity } from 'multiformats/hashes/identity'\nimport { base36 } from 'multiformats/bases/base36'\nimport { CID } from 'multiformats/cid'\nimport { keys } from 'libp2p-crypto'\nimport * as cbor from 'cborg'\nimport { fetch } from './platform.js'\n\nconst libp2pKeyCode = 0x72\nconst ONE_YEAR = 1000 * 60 * 60 * 24 * 365\n\nconst defaultValidity = () => new Date(Date.now() + ONE_YEAR).toISOString()\n\n/**\n * @typedef {{\n * bytes: Uint8Array,\n * verify (data: Uint8Array, signature: Uint8Array): Promise<boolean>\n * }} PublicKey\n *\n * @typedef {{\n * sign (data: Uint8Array): Promise<Uint8Array>\n * }} SigningKey\n *\n * @typedef {{\n * public: PublicKey,\n * bytes: Uint8Array\n * } & SigningKey} PrivateKey\n */\n\n/**\n * Name is an IPNS key ID.\n */\nexport class Name {\n /**\n * @param {PublicKey} pubKey Public key.\n */\n constructor (pubKey) {\n /**\n * @private\n */\n this._pubKey = pubKey\n }\n\n get bytes () {\n const digest = Digest.create(identity.code, this._pubKey.bytes)\n return CID.createV1(libp2pKeyCode, digest).bytes\n }\n\n toString () {\n const digest = Digest.create(identity.code, this._pubKey.bytes)\n return CID.createV1(libp2pKeyCode, digest).toString(base36)\n }\n}\n\n/**\n * WritableName is a Name that has a signing key associated with it such that\n * new IPNS record revisions can be created and signed for it.\n */\nexport class WritableName extends Name {\n /**\n * @param {PrivateKey} privKey\n */\n constructor (privKey) {\n super(privKey.public)\n /**\n * @private\n */\n this._privKey = privKey\n }\n\n get key () {\n return this._privKey\n }\n}\n\n/**\n * Create a new name with associated signing key that can be used to create and\n * publish IPNS record revisions.\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n */\nexport async function create () {\n const privKey = await keys.generateKeyPair('Ed25519', 2048)\n return new WritableName(privKey)\n}\n\n/**\n * Parses string name to readable name.\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n *\n * @param {string} name The name to parse.\n */\nexport function parse (name) {\n const keyCid = CID.parse(name, base36)\n if (keyCid.code !== libp2pKeyCode) {\n throw new Error(`invalid key, expected ${libp2pKeyCode} codec code but got ${keyCid.code}`)\n }\n const pubKey = keys.unmarshalPublicKey(Digest.decode(keyCid.multihash.bytes).bytes)\n return new Name(pubKey)\n}\n\n/**\n * Create a name from an existing signing key (private key).\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n *\n * @param {Uint8Array} key Binary representation of the signing key for the name.\n */\nexport async function from (key) {\n const privKey = await keys.unmarshalPrivateKey(key)\n return new WritableName(privKey)\n}\n\n/**\n * Create an initial version of the IPNS record for the passed name, set to the\n * passed value.\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n *\n * @param {Name} name\n * @param {string} value\n */\nexport async function v0 (name, value) {\n return new Revision(name, value, 0n, defaultValidity())\n}\n\n/**\n * Create a revision of the passed IPNS record by incrementing the sequence\n * number and changing the value.\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n *\n * @param {Revision} revision\n * @param {string} value\n */\nexport async function increment (revision, value) {\n const seqno = revision.sequence + 1n\n return new Revision(revision.name, value, seqno, defaultValidity())\n}\n\n/**\n * A represetation of a IPNS record that may be initial or revised.\n */\nexport class Revision {\n /**\n * @param {Name} name\n * @param {string} value\n * @param {bigint} sequence\n * @param {string} validity\n */\n constructor (name, value, sequence, validity) {\n this._name = name\n if (typeof value !== 'string') {\n throw new Error('invalid value')\n }\n this._value = value\n if (typeof sequence !== 'bigint') {\n throw new Error('invalid sequence number')\n }\n this._sequence = sequence\n if (typeof validity !== 'string') {\n throw new Error('invalid validity')\n }\n // TODO: validate format\n this._validity = validity\n }\n\n get name () {\n return this._name\n }\n\n get value () {\n return this._value\n }\n\n get sequence () {\n return this._sequence\n }\n\n /**\n * RFC3339 date string.\n */\n get validity () {\n return this._validity\n }\n\n /**\n * Note: if `revision.name` is a `WritableName` then signing key data will be\n * lost. i.e. the private key is not encoded.\n *\n * @param {Revision} revision Revision to encode.\n */\n static encode (revision) {\n return cbor.encode({\n name: revision._name.toString(),\n value: revision._value,\n sequence: revision._sequence,\n validity: revision._validity\n })\n }\n\n /**\n * @param {Uint8Array} bytes\n */\n static decode (bytes) {\n const raw = cbor.decode(bytes)\n const name = parse(raw.name)\n return new Revision(name, raw.value, BigInt(raw.sequence), raw.validity)\n }\n}\n\n/**\n * Publish a name revision to Web3.Storage.\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n *\n * ⚠️ Name records are not _yet_ published to or updated from the IPFS network.\n * Working with name records simply updates the Web3.Storage cache of data.\n *\n * @param {import('./lib/interface.js').Service} service\n * @param {Revision} revision Revision of record to publish.\n * @param {SigningKey} key Private key to sign the record with.\n */\nexport async function publish (service, revision, key) {\n const url = new URL(`name/${revision.name}`, service.endpoint)\n const entry = await ipns.create(\n // @ts-expect-error API expects a libp2p-crypto.PrivateKey but only uses SigningKey.sign().\n key,\n uint8ArrayFromString(revision.value),\n revision.sequence,\n new Date(revision.validity).getTime() - Date.now()\n )\n const res = await maybeHandleError(fetch(url.toString(), {\n method: 'POST',\n headers: headers(service.token),\n body: uint8ArrayToString(ipns.marshal(entry), 'base64pad')\n }))\n await res.json()\n}\n\n/**\n * Resolve the current IPNS record revision for the passed name.\n *\n * **❗️Experimental** this API may not work, may change, and may be removed.\n *\n * @param {import('./lib/interface.js').PublicService} service\n * @param {Name} name The name to resolve.\n */\nexport async function resolve (service, name) {\n const url = new URL(`name/${name}`, service.endpoint)\n const res = await maybeHandleError(fetch(url.toString()))\n const { record } = await res.json()\n const entry = ipns.unmarshal(uint8ArrayFromString(record, 'base64pad'))\n const keyCid = CID.decode(name.bytes)\n const pubKey = keys.unmarshalPublicKey(Digest.decode(keyCid.multihash.bytes).bytes)\n\n await ipns.validate(pubKey, entry)\n\n return new Revision(\n name,\n uint8ArrayToString(entry.value),\n entry.sequence,\n uint8ArrayToString(entry.validity)\n )\n}\n\n/**\n * @param {string} token\n * @returns {Record<string, string>}\n */\nfunction headers (token) {\n if (!token) throw new Error('missing token')\n return {\n Authorization: `Bearer ${token}`,\n 'X-Client': 'web3.storage'\n }\n}\n\n/**\n * @param {Promise<Response>} resPromise\n * @returns {Promise<Response>}\n */\nasync function maybeHandleError (resPromise) {\n const res = await resPromise\n if (res.ok) return res\n const err = new Error(`unexpected status: ${res.status}`)\n try {\n Object.assign(err, await res.json())\n } catch {}\n throw err\n}\n"],"names":["Digest","identity","CID","base36","keys","cbor","ipns","uint8ArrayFromString","fetch","uint8ArrayToString"],"mappings":"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"} | ||
| {"version":3,"file":"name.cjs","sources":["../../src/name.js"],"sourcesContent":["/**\n * This module exists only to provide maintain the existing functionality to allow a\n * smooth transition to the new 'w3name' package. This module will be later removed.\n */\nimport * as w3name from 'w3name'\n\nconsole.warn('The name.js module is deprecated. You should use the new \\'w3name\\' npm package instead.')\n\nexport const {\n Name,\n WritableName,\n create,\n parse,\n from,\n v0,\n increment,\n Revision\n} = w3name\n\n/**\n * @typedef {{\n * sign (data: Uint8Array): Promise<Uint8Array>\n * }} SigningKey\n *\n * @typedef {{\n * endpoint: URL\n * rateLimiter?: function\n * }} PublicService\n */\n\n/* eslint-disable no-unused-vars */\n\n/**\n * Proxy the old `publish` function arguments through to the new version.\n *\n * @param {import('./lib/interface.js').Service} service\n * @param {w3name.Revision} revision Revision of record to publish.\n * @param {SigningKey} key Private key to sign the record with.\n */\n// @ts-expect-error\nexport async function publish (service, revision, key) {\n // The user _might_ have overridden the endpoint in the service, but it's unlikely and\n // this library is only really intended for use with the w3name endpoint anyway. The\n // most likely use case for overriding it is for tests, which no longer exist for this\n // module because it's now just a proxy.\n // @ts-ignore key type is libp2p-crypto PrivateKey instead of SigningKey\n return await w3name.publish(revision, key)\n}\n\n/**\n * Proxy the old function arguments to the new version.\n * @param {PublicService} service\n * @param {w3name.Name} name The name to resolve.\n */\n// @ts-expect-error\nexport async function resolve (service, name) {\n // Same reasoning as in `publish`, we ignore the `service` arg.\n return await w3name.resolve(name)\n}\n"],"names":["w3name"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AAEA;AACA,OAAO,CAAC,IAAI,CAAC,0FAA0F,EAAC;AACxG;AACY,MAAC;AACb,EAAE,IAAI;AACN,EAAE,YAAY;AACd,EAAE,MAAM;AACR,EAAE,KAAK;AACP,EAAE,IAAI;AACN,EAAE,EAAE;AACJ,EAAE,SAAS;AACX,EAAE,QAAQ;AACV,CAAC,GAAGA,kBAAM;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE;AACvD;AACA;AACA;AACA;AACA;AACA,EAAE,OAAO,MAAMA,iBAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;AAC5C,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;AAC9C;AACA,EAAE,OAAO,MAAMA,iBAAM,CAAC,OAAO,CAAC,IAAI,CAAC;AACnC;;;;;;;;;;;;;"} |
+26
-141
| /** | ||
| * Create a new name with associated signing key that can be used to create and | ||
| * publish IPNS record revisions. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| */ | ||
| export function create(): Promise<WritableName>; | ||
| /** | ||
| * Parses string name to readable name. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {string} name The name to parse. | ||
| */ | ||
| export function parse(name: string): Name; | ||
| /** | ||
| * Create a name from an existing signing key (private key). | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Uint8Array} key Binary representation of the signing key for the name. | ||
| */ | ||
| export function from(key: Uint8Array): Promise<WritableName>; | ||
| /** | ||
| * Create an initial version of the IPNS record for the passed name, set to the | ||
| * passed value. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Name} name | ||
| * @param {string} value | ||
| */ | ||
| export function v0(name: Name, value: string): Promise<Revision>; | ||
| /** | ||
| * Create a revision of the passed IPNS record by incrementing the sequence | ||
| * number and changing the value. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Revision} revision | ||
| * @param {string} value | ||
| */ | ||
| export function increment(revision: Revision, value: string): Promise<Revision>; | ||
| /** | ||
| * Publish a name revision to Web3.Storage. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * ⚠️ Name records are not _yet_ published to or updated from the IPFS network. | ||
| * Working with name records simply updates the Web3.Storage cache of data. | ||
| * | ||
| * @param {import('./lib/interface.js').Service} service | ||
| * @param {Revision} revision Revision of record to publish. | ||
| * @param {SigningKey} key Private key to sign the record with. | ||
| */ | ||
| export function publish(service: import('./lib/interface.js').Service, revision: Revision, key: SigningKey): Promise<void>; | ||
| /** | ||
| * Resolve the current IPNS record revision for the passed name. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {import('./lib/interface.js').PublicService} service | ||
| * @param {Name} name The name to resolve. | ||
| */ | ||
| export function resolve(service: import('./lib/interface.js').PublicService, name: Name): Promise<Revision>; | ||
| /** | ||
| * @typedef {{ | ||
| * bytes: Uint8Array, | ||
| * verify (data: Uint8Array, signature: Uint8Array): Promise<boolean> | ||
| * }} PublicKey | ||
| * | ||
| * @typedef {{ | ||
| * sign (data: Uint8Array): Promise<Uint8Array> | ||
@@ -77,81 +7,36 @@ * }} SigningKey | ||
| * @typedef {{ | ||
| * public: PublicKey, | ||
| * bytes: Uint8Array | ||
| * } & SigningKey} PrivateKey | ||
| * endpoint: URL | ||
| * rateLimiter?: function | ||
| * }} PublicService | ||
| */ | ||
| /** | ||
| * Name is an IPNS key ID. | ||
| * Proxy the old `publish` function arguments through to the new version. | ||
| * | ||
| * @param {import('./lib/interface.js').Service} service | ||
| * @param {w3name.Revision} revision Revision of record to publish. | ||
| * @param {SigningKey} key Private key to sign the record with. | ||
| */ | ||
| export class Name { | ||
| /** | ||
| * @param {PublicKey} pubKey Public key. | ||
| */ | ||
| constructor(pubKey: PublicKey); | ||
| /** | ||
| * @private | ||
| */ | ||
| private _pubKey; | ||
| get bytes(): Uint8Array; | ||
| toString(): string; | ||
| } | ||
| export function publish(service: import('./lib/interface.js').Service, revision: w3name.Revision, key: SigningKey): Promise<void>; | ||
| /** | ||
| * WritableName is a Name that has a signing key associated with it such that | ||
| * new IPNS record revisions can be created and signed for it. | ||
| * Proxy the old function arguments to the new version. | ||
| * @param {PublicService} service | ||
| * @param {w3name.Name} name The name to resolve. | ||
| */ | ||
| export class WritableName extends Name { | ||
| /** | ||
| * @param {PrivateKey} privKey | ||
| */ | ||
| constructor(privKey: PrivateKey); | ||
| /** | ||
| * @private | ||
| */ | ||
| private _privKey; | ||
| get key(): PrivateKey; | ||
| } | ||
| /** | ||
| * A represetation of a IPNS record that may be initial or revised. | ||
| */ | ||
| export class Revision { | ||
| /** | ||
| * Note: if `revision.name` is a `WritableName` then signing key data will be | ||
| * lost. i.e. the private key is not encoded. | ||
| * | ||
| * @param {Revision} revision Revision to encode. | ||
| */ | ||
| static encode(revision: Revision): Uint8Array; | ||
| /** | ||
| * @param {Uint8Array} bytes | ||
| */ | ||
| static decode(bytes: Uint8Array): Revision; | ||
| /** | ||
| * @param {Name} name | ||
| * @param {string} value | ||
| * @param {bigint} sequence | ||
| * @param {string} validity | ||
| */ | ||
| constructor(name: Name, value: string, sequence: bigint, validity: string); | ||
| _name: Name; | ||
| _value: string; | ||
| _sequence: bigint; | ||
| _validity: string; | ||
| get name(): Name; | ||
| get value(): string; | ||
| get sequence(): bigint; | ||
| /** | ||
| * RFC3339 date string. | ||
| */ | ||
| get validity(): string; | ||
| } | ||
| export type PublicKey = { | ||
| bytes: Uint8Array; | ||
| verify(data: Uint8Array, signature: Uint8Array): Promise<boolean>; | ||
| }; | ||
| export function resolve(service: PublicService, name: w3name.Name): Promise<w3name.Revision>; | ||
| export const Name: typeof w3name.Name; | ||
| export const WritableName: typeof w3name.WritableName; | ||
| export const create: typeof w3name.create; | ||
| export const parse: typeof w3name.parse; | ||
| export const from: typeof w3name.from; | ||
| export const v0: typeof w3name.v0; | ||
| export const increment: typeof w3name.increment; | ||
| export const Revision: typeof w3name.Revision; | ||
| export type SigningKey = { | ||
| sign(data: Uint8Array): Promise<Uint8Array>; | ||
| }; | ||
| export type PrivateKey = { | ||
| public: PublicKey; | ||
| bytes: Uint8Array; | ||
| } & SigningKey; | ||
| export type PublicService = { | ||
| endpoint: URL; | ||
| rateLimiter?: Function; | ||
| }; | ||
| import * as w3name from "w3name"; | ||
| //# sourceMappingURL=name.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"name.d.ts","sourceRoot":"","sources":["../../src/name.js"],"names":[],"mappings":"AA0GA;;;;;GAKG;AACH,gDAGC;AAED;;;;;;GAMG;AACH,4BAFW,MAAM,QAShB;AAED;;;;;;GAMG;AACH,0BAFW,UAAU,yBAKpB;AAED;;;;;;;;GAQG;AACH,yBAHW,IAAI,SACJ,MAAM,qBAIhB;AAED;;;;;;;;GAQG;AACH,oCAHW,QAAQ,SACR,MAAM,qBAKhB;AAyED;;;;;;;;;;;GAWG;AACH,iCAJW,OAAO,oBAAoB,EAAE,OAAO,YACpC,QAAQ,OACR,UAAU,iBAiBpB;AAED;;;;;;;GAOG;AACH,iCAHW,OAAO,oBAAoB,EAAE,aAAa,QAC1C,IAAI,qBAkBd;AA5PD;;;;;;;;;;;;;;GAcG;AAEH;;GAEG;AACH;IACE;;OAEG;IACH,oBAFW,SAAS,EAOnB;IAJC;;OAEG;IACH,gBAAqB;IAGvB,wBAGC;IAED,mBAGC;CACF;AAED;;;GAGG;AACH;IACE;;OAEG;IACH,qBAFW,UAAU,EAQpB;IAJC;;OAEG;IACH,iBAAuB;IAGzB,sBAEC;CACF;AAoED;;GAEG;AACH;IA2CE;;;;;OAKG;IACH,wBAFW,QAAQ,cASlB;IAED;;OAEG;IACH,qBAFW,UAAU,YAMpB;IAhED;;;;;OAKG;IACH,kBALW,IAAI,SACJ,MAAM,YACN,MAAM,YACN,MAAM,EAiBhB;IAdC,YAAiB;IAIjB,eAAmB;IAInB,kBAAyB;IAKzB,kBAAyB;IAG3B,iBAEC;IAED,oBAEC;IAED,uBAEC;IAED;;OAEG;IACH,uBAEC;CAyBF;;WAnMW,UAAU;iBACH,UAAU,aAAa,UAAU,GAAG,QAAQ,OAAO,CAAC;;;eAItD,UAAU,GAAG,QAAQ,UAAU,CAAC;;yBAGpC;IACZ,MAAU,EAAE,SAAS,CAAC;IACtB,KAAS,EAAE,UAAU,CAAA;CAClB,GAAG,UAAU"} | ||
| {"version":3,"file":"name.d.ts","sourceRoot":"","sources":["../../src/name.js"],"names":[],"mappings":"AAmBA;;;;;;;;;GASG;AAIH;;;;;;GAMG;AAEH,iCALW,OAAO,oBAAoB,EAAE,OAAO,YACpC,eAAe,OACf,UAAU,iBAUpB;AAED;;;;GAIG;AAEH,iCAJW,aAAa,QACb,WAAW,4BAMrB;;;;;;;;;;eArCgB,UAAU,GAAG,QAAQ,UAAU,CAAC;;4BAGpC;IACZ,QAAY,EAAE,GAAG,CAAA;IACjB,WAAe,CAAC,WAAU;CACvB"} |
+3
-3
| { | ||
| "name": "web3.storage", | ||
| "version": "4.3.0", | ||
| "version": "4.4.0", | ||
| "description": "API client for web3.storage", | ||
@@ -43,3 +43,2 @@ "type": "module", | ||
| "ipfs-car": "^0.7.0", | ||
| "ipns": "^0.16.0", | ||
| "libp2p-crypto": "^0.21.0", | ||
@@ -49,3 +48,4 @@ "p-retry": "^4.5.0", | ||
| "throttled-queue": "^2.1.2", | ||
| "uint8arrays": "^3.0.0" | ||
| "uint8arrays": "^3.0.0", | ||
| "w3name": "^1.0.4" | ||
| }, | ||
@@ -52,0 +52,0 @@ "devDependencies": { |
+1
-112
@@ -42,115 +42,4 @@ <h1 align="center">⁂<br/>web3.storage</h1> | ||
| **❗️Experimental** this API may not work, may change, and may be removed in a future version. | ||
| Management of mutable name records with IPNS has now moved to the [w3name client](https://github.com/web3-storage/w3name/blob/main/packages/client). | ||
| Mutability in Web3.Storage is maintained through IPNS records. | ||
| ⚠️ Name records are not _yet_ published to or updated from the IPFS network. Working with name records simply updates the Web3.Storage cache of data. | ||
| #### Create and Publish | ||
| ```js | ||
| import { Web3Storage } from 'web3.storage' | ||
| import * as Name from 'web3.storage/name' | ||
| const client = new Web3Storage({ token: API_TOKEN }) | ||
| 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(client, revision, name.key) | ||
| ``` | ||
| ⚠️ Note: revisions live for 1 year after creation by default. | ||
| #### Resolve | ||
| ```js | ||
| import { Web3Storage } from 'web3.storage' | ||
| import * as Name from 'web3.storage/name' | ||
| const client = new Web3Storage({ token: API_TOKEN }) | ||
| const name = Name.parse('k51qzi5uqu5di9agapykyjh3tqrf7i14a7fjq46oo0f6dxiimj62knq13059lt') | ||
| const revision = await Name.resolve(client, name) | ||
| console.log('Resolved value:', revision.value) | ||
| // e.g. /ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui | ||
| ``` | ||
| #### Update | ||
| Updating records involves creating a new _revision_ from the previous one. | ||
| ```js | ||
| import { Web3Storage } from 'web3.storage' | ||
| import * as Name from 'web3.storage/name' | ||
| const client = new Web3Storage({ token: API_TOKEN }) | ||
| const name = await Name.create() | ||
| const value = '/ipfs/bafkreiem4twkqzsq2aj4shbycd4yvoj2cx72vezicletlhi7dijjciqpui' | ||
| const revision = await Name.v0(name, value) | ||
| await Name.publish(client, 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(client, 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. | ||
| ```js | ||
| import * as Name from 'web3.storage/name' | ||
| 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. | ||
| ```js | ||
| import * as Name from 'web3.storage/name' | ||
| 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) | ||
| ``` | ||
| ## Testing | ||
@@ -157,0 +46,0 @@ Run `npm test` to test the ESM code, CJS, and in the browser via `playwright-test`. 100% test coverage is required by the `hundreds` module. |
@@ -16,3 +16,3 @@ import type { UnixFSEntry } from 'ipfs-car/unpack' | ||
| export interface Service { | ||
| endpoint: URL | ||
| endpoint?: URL | ||
| token: string | ||
@@ -23,7 +23,2 @@ rateLimiter?: RateLimiter | ||
| export interface PublicService { | ||
| endpoint: URL | ||
| rateLimiter?: RateLimiter | ||
| } | ||
| /** | ||
@@ -30,0 +25,0 @@ * CID in string representation. |
+33
-297
| /** | ||
| * A client library for the w3name - IPNS over HTTP API. It provides a | ||
| * convenient interface for creating names, making revisions to name records, | ||
| * and publishing and resolving them via the HTTP API. | ||
| * | ||
| * @example | ||
| * ```js | ||
| * import { Web3Storage } from 'web3.storage' | ||
| * import * as Name from 'web3.storage/name' | ||
| * | ||
| * const client = new Web3Storage({ token: API_TOKEN }) | ||
| * 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) | ||
| * | ||
| * // Publish the revision | ||
| * await Name.publish(client, revision, name.key) | ||
| * | ||
| * // Resolve the latest value | ||
| * await Name.resolve(name) | ||
| * ``` | ||
| * @module | ||
| * This module exists only to provide maintain the existing functionality to allow a | ||
| * smooth transition to the new 'w3name' package. This module will be later removed. | ||
| */ | ||
| import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string' | ||
| import { toString as uint8ArrayToString } from 'uint8arrays/to-string' | ||
| import * as ipns from 'ipns' | ||
| import * as Digest from 'multiformats/hashes/digest' | ||
| import { identity } from 'multiformats/hashes/identity' | ||
| import { base36 } from 'multiformats/bases/base36' | ||
| import { CID } from 'multiformats/cid' | ||
| import { keys } from 'libp2p-crypto' | ||
| import * as cbor from 'cborg' | ||
| import { fetch } from './platform.js' | ||
| import * as w3name from 'w3name' | ||
| const libp2pKeyCode = 0x72 | ||
| const ONE_YEAR = 1000 * 60 * 60 * 24 * 365 | ||
| console.warn('The name.js module is deprecated. You should use the new \'w3name\' npm package instead.') | ||
| const defaultValidity = () => new Date(Date.now() + ONE_YEAR).toISOString() | ||
| export const { | ||
| Name, | ||
| WritableName, | ||
| create, | ||
| parse, | ||
| from, | ||
| v0, | ||
| increment, | ||
| Revision | ||
| } = w3name | ||
| /** | ||
| * @typedef {{ | ||
| * bytes: Uint8Array, | ||
| * verify (data: Uint8Array, signature: Uint8Array): Promise<boolean> | ||
| * }} PublicKey | ||
| * | ||
| * @typedef {{ | ||
| * sign (data: Uint8Array): Promise<Uint8Array> | ||
@@ -56,269 +26,35 @@ * }} SigningKey | ||
| * @typedef {{ | ||
| * public: PublicKey, | ||
| * bytes: Uint8Array | ||
| * } & SigningKey} PrivateKey | ||
| * endpoint: URL | ||
| * rateLimiter?: function | ||
| * }} PublicService | ||
| */ | ||
| /** | ||
| * Name is an IPNS key ID. | ||
| */ | ||
| export class Name { | ||
| /** | ||
| * @param {PublicKey} pubKey Public key. | ||
| */ | ||
| constructor (pubKey) { | ||
| /** | ||
| * @private | ||
| */ | ||
| this._pubKey = pubKey | ||
| } | ||
| /* eslint-disable no-unused-vars */ | ||
| get bytes () { | ||
| const digest = Digest.create(identity.code, this._pubKey.bytes) | ||
| return CID.createV1(libp2pKeyCode, digest).bytes | ||
| } | ||
| toString () { | ||
| const digest = Digest.create(identity.code, this._pubKey.bytes) | ||
| return CID.createV1(libp2pKeyCode, digest).toString(base36) | ||
| } | ||
| } | ||
| /** | ||
| * WritableName is a Name that has a signing key associated with it such that | ||
| * new IPNS record revisions can be created and signed for it. | ||
| */ | ||
| export class WritableName extends Name { | ||
| /** | ||
| * @param {PrivateKey} privKey | ||
| */ | ||
| constructor (privKey) { | ||
| super(privKey.public) | ||
| /** | ||
| * @private | ||
| */ | ||
| this._privKey = privKey | ||
| } | ||
| get key () { | ||
| return this._privKey | ||
| } | ||
| } | ||
| /** | ||
| * Create a new name with associated signing key that can be used to create and | ||
| * publish IPNS record revisions. | ||
| * Proxy the old `publish` function arguments through to the new version. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| */ | ||
| export async function create () { | ||
| const privKey = await keys.generateKeyPair('Ed25519', 2048) | ||
| return new WritableName(privKey) | ||
| } | ||
| /** | ||
| * Parses string name to readable name. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {string} name The name to parse. | ||
| */ | ||
| export function parse (name) { | ||
| const keyCid = CID.parse(name, base36) | ||
| if (keyCid.code !== libp2pKeyCode) { | ||
| throw new Error(`invalid key, expected ${libp2pKeyCode} codec code but got ${keyCid.code}`) | ||
| } | ||
| const pubKey = keys.unmarshalPublicKey(Digest.decode(keyCid.multihash.bytes).bytes) | ||
| return new Name(pubKey) | ||
| } | ||
| /** | ||
| * Create a name from an existing signing key (private key). | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Uint8Array} key Binary representation of the signing key for the name. | ||
| */ | ||
| export async function from (key) { | ||
| const privKey = await keys.unmarshalPrivateKey(key) | ||
| return new WritableName(privKey) | ||
| } | ||
| /** | ||
| * Create an initial version of the IPNS record for the passed name, set to the | ||
| * passed value. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Name} name | ||
| * @param {string} value | ||
| */ | ||
| export async function v0 (name, value) { | ||
| return new Revision(name, value, 0n, defaultValidity()) | ||
| } | ||
| /** | ||
| * Create a revision of the passed IPNS record by incrementing the sequence | ||
| * number and changing the value. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {Revision} revision | ||
| * @param {string} value | ||
| */ | ||
| export async function increment (revision, value) { | ||
| const seqno = revision.sequence + 1n | ||
| return new Revision(revision.name, value, seqno, defaultValidity()) | ||
| } | ||
| /** | ||
| * A represetation of a IPNS record that may be initial or revised. | ||
| */ | ||
| export class Revision { | ||
| /** | ||
| * @param {Name} name | ||
| * @param {string} value | ||
| * @param {bigint} sequence | ||
| * @param {string} validity | ||
| */ | ||
| constructor (name, value, sequence, validity) { | ||
| this._name = name | ||
| if (typeof value !== 'string') { | ||
| throw new Error('invalid value') | ||
| } | ||
| this._value = value | ||
| if (typeof sequence !== 'bigint') { | ||
| throw new Error('invalid sequence number') | ||
| } | ||
| this._sequence = sequence | ||
| if (typeof validity !== 'string') { | ||
| throw new Error('invalid validity') | ||
| } | ||
| // TODO: validate format | ||
| this._validity = validity | ||
| } | ||
| get name () { | ||
| return this._name | ||
| } | ||
| get value () { | ||
| return this._value | ||
| } | ||
| get sequence () { | ||
| return this._sequence | ||
| } | ||
| /** | ||
| * RFC3339 date string. | ||
| */ | ||
| get validity () { | ||
| return this._validity | ||
| } | ||
| /** | ||
| * Note: if `revision.name` is a `WritableName` then signing key data will be | ||
| * lost. i.e. the private key is not encoded. | ||
| * | ||
| * @param {Revision} revision Revision to encode. | ||
| */ | ||
| static encode (revision) { | ||
| return cbor.encode({ | ||
| name: revision._name.toString(), | ||
| value: revision._value, | ||
| sequence: revision._sequence, | ||
| validity: revision._validity | ||
| }) | ||
| } | ||
| /** | ||
| * @param {Uint8Array} bytes | ||
| */ | ||
| static decode (bytes) { | ||
| const raw = cbor.decode(bytes) | ||
| const name = parse(raw.name) | ||
| return new Revision(name, raw.value, BigInt(raw.sequence), raw.validity) | ||
| } | ||
| } | ||
| /** | ||
| * Publish a name revision to Web3.Storage. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * ⚠️ Name records are not _yet_ published to or updated from the IPFS network. | ||
| * Working with name records simply updates the Web3.Storage cache of data. | ||
| * | ||
| * @param {import('./lib/interface.js').Service} service | ||
| * @param {Revision} revision Revision of record to publish. | ||
| * @param {w3name.Revision} revision Revision of record to publish. | ||
| * @param {SigningKey} key Private key to sign the record with. | ||
| */ | ||
| // @ts-expect-error | ||
| export async function publish (service, revision, key) { | ||
| const url = new URL(`name/${revision.name}`, service.endpoint) | ||
| const entry = await ipns.create( | ||
| // @ts-expect-error API expects a libp2p-crypto.PrivateKey but only uses SigningKey.sign(). | ||
| key, | ||
| uint8ArrayFromString(revision.value), | ||
| revision.sequence, | ||
| new Date(revision.validity).getTime() - Date.now() | ||
| ) | ||
| const res = await maybeHandleError(fetch(url.toString(), { | ||
| method: 'POST', | ||
| headers: headers(service.token), | ||
| body: uint8ArrayToString(ipns.marshal(entry), 'base64pad') | ||
| })) | ||
| await res.json() | ||
| // The user _might_ have overridden the endpoint in the service, but it's unlikely and | ||
| // this library is only really intended for use with the w3name endpoint anyway. The | ||
| // most likely use case for overriding it is for tests, which no longer exist for this | ||
| // module because it's now just a proxy. | ||
| // @ts-ignore key type is libp2p-crypto PrivateKey instead of SigningKey | ||
| return await w3name.publish(revision, key) | ||
| } | ||
| /** | ||
| * Resolve the current IPNS record revision for the passed name. | ||
| * | ||
| * **❗️Experimental** this API may not work, may change, and may be removed. | ||
| * | ||
| * @param {import('./lib/interface.js').PublicService} service | ||
| * @param {Name} name The name to resolve. | ||
| * Proxy the old function arguments to the new version. | ||
| * @param {PublicService} service | ||
| * @param {w3name.Name} name The name to resolve. | ||
| */ | ||
| // @ts-expect-error | ||
| export async function resolve (service, name) { | ||
| const url = new URL(`name/${name}`, service.endpoint) | ||
| const res = await maybeHandleError(fetch(url.toString())) | ||
| const { record } = await res.json() | ||
| const entry = ipns.unmarshal(uint8ArrayFromString(record, 'base64pad')) | ||
| const keyCid = CID.decode(name.bytes) | ||
| const pubKey = keys.unmarshalPublicKey(Digest.decode(keyCid.multihash.bytes).bytes) | ||
| await ipns.validate(pubKey, entry) | ||
| return new Revision( | ||
| name, | ||
| uint8ArrayToString(entry.value), | ||
| entry.sequence, | ||
| uint8ArrayToString(entry.validity) | ||
| ) | ||
| // Same reasoning as in `publish`, we ignore the `service` arg. | ||
| return await w3name.resolve(name) | ||
| } | ||
| /** | ||
| * @param {string} token | ||
| * @returns {Record<string, string>} | ||
| */ | ||
| function headers (token) { | ||
| if (!token) throw new Error('missing token') | ||
| return { | ||
| Authorization: `Bearer ${token}`, | ||
| 'X-Client': 'web3.storage' | ||
| } | ||
| } | ||
| /** | ||
| * @param {Promise<Response>} resPromise | ||
| * @returns {Promise<Response>} | ||
| */ | ||
| async function maybeHandleError (resPromise) { | ||
| const res = await resPromise | ||
| if (res.ok) return res | ||
| const err = new Error(`unexpected status: ${res.status}`) | ||
| try { | ||
| Object.assign(err, await res.json()) | ||
| } catch {} | ||
| throw err | ||
| } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
69
-4.17%1193421
-2.95%2996
-17.08%57
-66.07%2
100%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed