Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit 4264b16

Browse files
vmxrvaggachingbrain
authored
feat: upgrade to the new multiformats (#3556)
- Replaces the old [interface-ipld-format](https://github.com/ipld/interface-ipld-format) stack with the new [multiformats](https://github.com/multiformats/js-multiformats) stack. - The Block API takes/returns `Uint8Array`s instead of [ipld-block](https://github.com/ipld/js-ipld-block) objects BREAKING CHANGE: ipld-formats no longer supported, use multiformat BlockCodecs instead Co-authored-by: Rod Vagg <rod@vagg.org> Co-authored-by: achingbrain <alex@achingbrain.net>
1 parent 5cb87e7 commit 4264b16

File tree

43 files changed

+147
-528
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+147
-528
lines changed

browser-add-readable-stream/index.js

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ const main = async () => {
1414

1515
const directoryHash = await streamFiles(ipfs, directoryName, inputFiles)
1616

17-
const fileList = await ipfs.ls(directoryHash)
18-
1917
log(`\n--\n\nDirectory contents:\n\n${directoryName}/ ${directoryHash}`)
2018

21-
fileList.forEach((file, index) => {
22-
log(` ${index < fileList.length - 1 ? '\u251C' : '\u2514'}\u2500 ${file.name} ${file.path} ${file.hash}`)
23-
})
19+
let index = 0
20+
21+
for await (const file of ipfs.ls(directoryHash)) {
22+
log(` ${index < inputFiles.length - 1 ? '\u251C' : '\u2514'}\u2500 ${file.name} ${file.path} ${file.cid}`)
23+
index++
24+
}
2425
}
2526

2627
const createFiles = (directory) => {
@@ -54,7 +55,7 @@ const streamFiles = async (ipfs, directory, files) => {
5455

5556
const data = await ipfs.add(stream)
5657

57-
log(`Added ${data.path} hash: ${data.hash}`)
58+
log(`Added ${data.path} hash: ${data.cid}`)
5859

5960
// The last data event will contain the directory hash
6061
if (data.path === directory) {

browser-exchange-files/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
"execa": "^5.0.0",
1616
"http-server": "^0.12.3",
1717
"ipfs-http-client": "^50.1.2",
18-
"uint8arrays": "^2.1.3"
18+
"uint8arrays": "^2.1.6"
1919
},
2020
"dependencies": {
2121
"ipfs": "^0.55.4",
2222
"it-all": "^1.0.4",
23-
"libp2p-websockets": "^0.15.6",
23+
"libp2p-websockets": "^0.16.1",
2424
"rimraf": "^3.0.2",
2525
"test-ipfs-example": "^3.0.0"
2626
}

browser-ipns-publish/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const last = require("it-last");
88
const cryptoKeys = require("human-crypto-keys"); // { getKeyPairFromSeed }
99
const uint8ArrayToString = require('uint8arrays/to-string')
1010
const uint8ArrayFromString = require('uint8arrays/from-string')
11+
const { sha256 } = require('multiformats/hashes/sha2')
1112

1213
const { sleep, Logger, onEnterPress, catchAndLog } = require("./util");
1314

@@ -142,11 +143,10 @@ async function main() {
142143
return new Promise(async (resolve, reject) => {
143144
try {
144145
// quick and dirty key gen, don't do this in real life
145-
const key = await IPFS.multihashing.digest(
146+
const key = await sha256.digest(
146147
uint8ArrayFromString(keyName + Math.random().toString(36).substring(2)),
147-
"sha2-256"
148148
);
149-
const keyPair = await cryptoKeys.getKeyPairFromSeed(key, "rsa");
149+
const keyPair = await cryptoKeys.getKeyPairFromSeed(key.bytes, "rsa");
150150

151151
// put it on the browser IPNS keychain and name it
152152
await ipfsBrowser.key.import(keyName, keyPair.privateKey);

browser-ipns-publish/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@
1616
"human-crypto-keys": "^0.1.4",
1717
"ipfs": "^0.55.4",
1818
"ipfs-http-client": "^50.1.2",
19-
"ipfs-utils": "^8.1.2",
20-
"ipns": "^0.12.0",
19+
"ipfs-utils": "^8.1.4",
20+
"ipns": "^0.13.2",
2121
"it-last": "^1.0.4",
2222
"p-retry": "^4.2.0",
23-
"uint8arrays": "^2.1.3"
23+
"uint8arrays": "^2.1.6"
2424
},
2525
"browserslist": [
2626
"last 2 versions and not dead and > 2%"
2727
],
2828
"devDependencies": {
2929
"delay": "^5.0.0",
3030
"execa": "^5.0.0",
31-
"ipfsd-ctl": "^8.0.1",
31+
"ipfsd-ctl": "^9.0.0",
3232
"go-ipfs": "0.8.0",
3333
"parcel": "2.0.0-beta.2",
3434
"path": "^0.12.7",

circuit-relaying/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
"delay": "^5.0.0",
1818
"ipfs": "^0.55.4",
1919
"ipfs-pubsub-room": "^2.0.1",
20-
"libp2p-websockets": "^0.15.6",
21-
"uint8arrays": "^2.1.3"
20+
"libp2p-websockets": "^0.16.1",
21+
"uint8arrays": "^2.1.6"
2222
},
2323
"devDependencies": {
2424
"execa": "^5.0.0",

custom-ipfs-repo/index.js

Lines changed: 70 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,87 @@
11
'use strict'
22

33
const IPFS = require('ipfs')
4-
const Repo = require('ipfs-repo')
5-
const fsLock = require('ipfs-repo/src/lock')
4+
const {
5+
createRepo,
6+
locks: {
7+
fs: fsLock
8+
}
9+
} = require('ipfs-repo')
610
const all = require('it-all')
711
const uint8ArrayFromString = require('uint8arrays/from-string')
812
const uint8ArrayConcat = require('uint8arrays/concat')
13+
const DatastoreFS = require('datastore-fs')
14+
const BlockstoreDatastoreAdapter = require('blockstore-datastore-adapter')
915

10-
// Create our custom options
11-
const customRepositoryOptions = {
16+
// multiformat codecs to support
17+
const codecs = [
18+
require('@ipld/dag-pb'),
19+
require('@ipld/dag-cbor'),
20+
require('multiformats/codecs/raw')
21+
].reduce((acc, curr) => {
22+
acc[curr.name] = curr
23+
acc[curr.code] = curr
1224

13-
/**
14-
* IPFS nodes store different information in separate storageBackends, or datastores.
15-
* Each storage backend can use the same type of datastore or a different one — you
16-
* could store your keys in a levelDB database while everything else is in files,
17-
* for example. (See https://github.com/ipfs/interface-datastore for more about datastores.)
18-
*/
19-
storageBackends: {
20-
root: require('datastore-fs'), // version and config data will be saved here
21-
blocks: require('datastore-fs'),
22-
keys: require('datastore-fs'),
23-
datastore: require('datastore-fs')
24-
},
25+
return acc
26+
}, {})
2527

26-
/**
27-
* Storage Backend Options will get passed into the instantiation of their counterpart
28-
* in `storageBackends`. If you create a custom datastore, this is where you can pass in
29-
* custom constructor arguments. You can see an S3 datastore example at:
30-
* https://github.com/ipfs/js-datastore-s3/tree/master/examples/full-s3-repo
31-
*
32-
* NOTE: The following options are being overriden for demonstration purposes only.
33-
* In most instances you can simply use the default options, by not passing in any
34-
* overrides, which is recommended if you have no need to override.
35-
*/
36-
storageBackendOptions: {
37-
root: {
38-
extension: '.ipfsroot', // Defaults to ''. Used by datastore-fs; Appended to all files
39-
errorIfExists: false, // Used by datastore-fs; If the datastore exists, don't throw an error
40-
createIfMissing: true // Used by datastore-fs; If the datastore doesn't exist yet, create it
41-
},
42-
blocks: {
43-
sharding: false, // Used by IPFSRepo Blockstore to determine sharding; Ignored by datastore-fs
44-
extension: '.ipfsblock', // Defaults to '.data'.
45-
errorIfExists: false,
46-
createIfMissing: true
47-
},
48-
keys: {
49-
extension: '.ipfskey', // No extension by default
50-
errorIfExists: false,
51-
createIfMissing: true
52-
},
53-
datastore: {
54-
extension: '.ipfsds', // No extension by default
55-
errorIfExists: false,
56-
createIfMissing: true
28+
async function main () {
29+
const path = '/tmp/custom-repo/.ipfs'
30+
31+
// Support dag-pb and dag-cbor at a minimum
32+
const loadCodec = (nameOrCode) => {
33+
if (codecs[nameOrCode]) {
34+
return codecs[nameOrCode]
5735
}
58-
},
5936

60-
/**
61-
* A custom lock can be added here. Or the build in Repo `fs` or `memory` locks can be used.
62-
* See https://github.com/ipfs/js-ipfs-repo for more details on setting the lock.
63-
*/
64-
lock: fsLock
65-
}
37+
throw new Error(`Could not load codec for ${nameOrCode}`)
38+
}
6639

67-
async function main () {
6840
// Initialize our IPFS node with the custom repo options
6941
const node = await IPFS.create({
70-
repo: new Repo('/tmp/custom-repo/.ipfs', customRepositoryOptions),
42+
repo: createRepo(path, loadCodec, {
43+
/**
44+
* IPFS repos store different types of information in separate datastores.
45+
* Each storage backend can use the same type of datastore or a different one — for example
46+
* you could store your keys in a levelDB database while everything else is in files.
47+
* See https://www.npmjs.com/package/interface-datastore for more about datastores.
48+
*/
49+
root: new DatastoreFS(path, {
50+
extension: '.ipfsroot', // Defaults to '', appended to all files
51+
errorIfExists: false, // If the datastore exists, don't throw an error
52+
createIfMissing: true // If the datastore doesn't exist yet, create it
53+
}),
54+
// blocks is a blockstore, all other backends are datastores - but we can wrap a datastore
55+
// in an adapter to turn it into a blockstore
56+
blocks: new BlockstoreDatastoreAdapter(
57+
new DatastoreFS(`${path}/blocks`, {
58+
extension: '.ipfsblock',
59+
errorIfExists: false,
60+
createIfMissing: true
61+
})
62+
),
63+
keys: new DatastoreFS(`${path}/keys`, {
64+
extension: '.ipfskey',
65+
errorIfExists: false,
66+
createIfMissing: true
67+
}),
68+
datastore: new DatastoreFS(`${path}/datastore`, {
69+
extension: '.ipfsds',
70+
errorIfExists: false,
71+
createIfMissing: true
72+
}),
73+
pins: new DatastoreFS(`${path}/pins`, {
74+
extension: '.ipfspin',
75+
errorIfExists: false,
76+
createIfMissing: true
77+
})
78+
}, {
79+
/**
80+
* A custom lock can be added here. Or the build in Repo `fs` or `memory` locks can be used.
81+
* See https://github.com/ipfs/js-ipfs-repo for more details on setting the lock.
82+
*/
83+
lock: fsLock
84+
}),
7185

7286
// This just means we dont try to connect to the network which isn't necessary
7387
// to demonstrate custom repos

custom-ipfs-repo/package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@
1010
},
1111
"license": "MIT",
1212
"dependencies": {
13-
"datastore-fs": "4.0.0",
13+
"@ipld/dag-cbor": "^6.0.5",
14+
"@ipld/dag-pb": "^2.1.3",
15+
"blockstore-datastore-adapter": "^1.0.0",
16+
"datastore-fs": "^5.0.1",
1417
"ipfs": "^0.55.4",
15-
"ipfs-repo": "^9.1.6",
16-
"it-all": "^1.0.4"
18+
"ipfs-repo": "^11.0.0",
19+
"it-all": "^1.0.4",
20+
"multiformats": "^9.4.1"
1721
},
1822
"devDependencies": {
1923
"execa": "^5.0.0",

custom-ipld-formats/daemon-node.js

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,33 @@
1-
// ordinarily we'd open a PR against the multicodec module to get our
2-
// codec number added but since we're just testing we shim our new
3-
// codec into the base-table.json file - this has to be done
4-
// before requiring other modules as the int table will become read-only
5-
const codecName = 'dag-test'
6-
const codecNumber = 392091
7-
8-
const table = require('multicodec/src/base-table')
9-
// @ts-ignore
10-
table.baseTable = {
11-
...table.baseTable,
12-
[codecName]: codecNumber
13-
}
14-
15-
// now require modules as usual
161
const IPFSDaemon = require('ipfs-daemon')
17-
const multihashing = require('multihashing-async')
18-
const multihash = multihashing.multihash
19-
const multicodec = require('multicodec')
20-
const CID = require('cids')
212
const ipfsHttpClient = require('ipfs-http-client')
223
const uint8ArrayToString = require('uint8arrays/to-string')
4+
const uint8ArrayFromString = require('uint8arrays/from-string')
235

246
async function main () {
25-
// see https://github.com/ipld/interface-ipld-format for the interface definition
26-
const format = {
27-
codec: codecNumber,
28-
defaultHashAlg: multicodec.SHA2_256,
29-
util: {
30-
serialize (data) {
31-
return Buffer.from(JSON.stringify(data))
32-
},
33-
deserialize (buf) {
34-
return JSON.parse(uint8ArrayToString(buf))
35-
},
36-
async cid (buf) {
37-
const multihash = await multihashing(buf, format.defaultHashAlg)
38-
39-
return new CID(1, format.codec, multihash)
40-
}
41-
},
42-
resolver: {
43-
resolve: (buf, path) => {
44-
return {
45-
value: format.util.deserialize(buf),
46-
remainderPath: path
47-
}
48-
}
49-
}
7+
// see https://github.com/multiformats/js-multiformats#multicodec-encoders--decoders--codecs for the interface definition
8+
const codec = {
9+
name: 'dag-test',
10+
code: 392091,
11+
encode: (data) => uint8ArrayFromString(JSON.stringify(data)),
12+
decode: (buf) => JSON.parse(uint8ArrayToString(buf))
5013
}
5114

5215
// start an IPFS Daemon
5316
const daemon = new IPFSDaemon({
5417
ipld: {
55-
formats: [
56-
format
18+
codecs: [
19+
codec
5720
]
5821
}
5922
})
6023
await daemon.start()
6124

6225
// in another process:
63-
const client = ipfsHttpClient({
26+
const client = ipfsHttpClient.create({
6427
url: `http://localhost:${daemon._httpApi._apiServers[0].info.port}`,
6528
ipld: {
66-
formats: [
67-
format
29+
codecs: [
30+
codec
6831
]
6932
}
7033
})
@@ -74,8 +37,8 @@ async function main () {
7437
}
7538

7639
const cid = await client.dag.put(data, {
77-
format: codecName,
78-
hashAlg: multihash.codes[format.defaultHashAlg]
40+
format: 'dag-test',
41+
hashAlg: 'sha2-256'
7942
})
8043

8144
console.info(`Put ${JSON.stringify(data)} = CID(${cid})`)

0 commit comments

Comments
 (0)