mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-consumer.git
synced 2026-09-21 16:52:03 -07:00
feat(helia v5): Generating and saving new private key
This commit is contained in:
Generated
+13
-102
@@ -16,7 +16,7 @@
|
||||
"@libp2p/bootstrap": "11.0.21",
|
||||
"@libp2p/circuit-relay-v2": "3.1.11",
|
||||
"@libp2p/identify": "3.0.18",
|
||||
"@libp2p/keychain": "4.1.5",
|
||||
"@libp2p/keychain": "5.0.14",
|
||||
"@libp2p/logger": "5.1.8",
|
||||
"@libp2p/tcp": "10.0.18",
|
||||
"@libp2p/webrtc": "5.0.27",
|
||||
@@ -3457,23 +3457,6 @@
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/auto-tls/node_modules/@libp2p/keychain": {
|
||||
"version": "5.0.14",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fkeychain/-/keychain-5.0.14.tgz",
|
||||
"integrity": "sha512-WTxHrLu8Dx8DNmVTOvlYtODQVsFNPgjL/tmyp61HwhBqKLqeEefH5BeU7W/W3YDlnwcL0JaUi5tIdMeu2qwRLw==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.11",
|
||||
"@libp2p/interface": "^2.5.0",
|
||||
"@noble/hashes": "^1.6.1",
|
||||
"asn1js": "^3.0.5",
|
||||
"interface-datastore": "^8.3.1",
|
||||
"merge-options": "^3.0.4",
|
||||
"multiformats": "^13.3.1",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/autonat": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fautonat/-/autonat-2.0.19.tgz",
|
||||
@@ -3546,23 +3529,6 @@
|
||||
"interface-datastore": "^8.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/config/node_modules/@libp2p/keychain": {
|
||||
"version": "5.0.14",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fkeychain/-/keychain-5.0.14.tgz",
|
||||
"integrity": "sha512-WTxHrLu8Dx8DNmVTOvlYtODQVsFNPgjL/tmyp61HwhBqKLqeEefH5BeU7W/W3YDlnwcL0JaUi5tIdMeu2qwRLw==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.11",
|
||||
"@libp2p/interface": "^2.5.0",
|
||||
"@noble/hashes": "^1.6.1",
|
||||
"asn1js": "^3.0.5",
|
||||
"interface-datastore": "^8.3.1",
|
||||
"merge-options": "^3.0.4",
|
||||
"multiformats": "^13.3.1",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/crypto": {
|
||||
"version": "5.0.11",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fcrypto/-/crypto-5.0.11.tgz",
|
||||
@@ -3702,59 +3668,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/keychain": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fkeychain/-/keychain-4.1.5.tgz",
|
||||
"integrity": "sha512-teDH0WbQ4mMSBCtOxV5ZoPltTj13xQiuOV27rzarRNYf4jRopPn2BU7k2c5qOFZ0VaCIvMAd1DT2Q8kfjcT4cw==",
|
||||
"version": "5.0.14",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fkeychain/-/keychain-5.0.14.tgz",
|
||||
"integrity": "sha512-WTxHrLu8Dx8DNmVTOvlYtODQVsFNPgjL/tmyp61HwhBqKLqeEefH5BeU7W/W3YDlnwcL0JaUi5tIdMeu2qwRLw==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^4.1.9",
|
||||
"@libp2p/interface": "^1.7.0",
|
||||
"@libp2p/peer-id": "^4.2.4",
|
||||
"interface-datastore": "^8.2.11",
|
||||
"merge-options": "^3.0.4",
|
||||
"multiformats": "^13.1.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/keychain/node_modules/@libp2p/crypto": {
|
||||
"version": "4.1.9",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fcrypto/-/crypto-4.1.9.tgz",
|
||||
"integrity": "sha512-8Cf2VKh0uC/rQLvTLSloIOMqUvf4jsSTHXgjWQRf47lDNJlNNI0wSv2S6gakT72GZsRV/jCjYwKPqRlsa5S0iA==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@libp2p/interface": "^1.7.0",
|
||||
"@noble/curves": "^1.4.0",
|
||||
"@noble/hashes": "^1.4.0",
|
||||
"@libp2p/crypto": "^5.0.11",
|
||||
"@libp2p/interface": "^2.5.0",
|
||||
"@noble/hashes": "^1.6.1",
|
||||
"asn1js": "^3.0.5",
|
||||
"multiformats": "^13.1.0",
|
||||
"protons-runtime": "^5.4.0",
|
||||
"uint8arraylist": "^2.4.8",
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/keychain/node_modules/@libp2p/interface": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2finterface/-/interface-1.7.0.tgz",
|
||||
"integrity": "sha512-/zFyaIaIGW0aihhsH7/93vQdpWInUzFocxF11RO/029Y6h0SVjs24HHbils+DqaFDTqN+L7oNlBx2rM2MnmTjA==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@multiformats/multiaddr": "^12.2.3",
|
||||
"it-pushable": "^3.2.3",
|
||||
"it-stream-types": "^2.0.1",
|
||||
"multiformats": "^13.1.0",
|
||||
"progress-events": "^1.0.0",
|
||||
"uint8arraylist": "^2.4.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@libp2p/keychain/node_modules/@libp2p/peer-id": {
|
||||
"version": "4.2.4",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fpeer-id/-/peer-id-4.2.4.tgz",
|
||||
"integrity": "sha512-mvvsVxt4HkF14BrTNKbqr14VObW+KBJBWu1Oe6BFCoDttGMQLaI+PdduE1r6Tquntv5IONBqoITgD7ow5dQ+vQ==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@libp2p/interface": "^1.7.0",
|
||||
"multiformats": "^13.1.0",
|
||||
"interface-datastore": "^8.3.1",
|
||||
"merge-options": "^3.0.4",
|
||||
"multiformats": "^13.3.1",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
@@ -11647,23 +11573,6 @@
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/helia/node_modules/@libp2p/keychain": {
|
||||
"version": "5.0.14",
|
||||
"resolved": "http://94.130.170.209:4873/@libp2p%2fkeychain/-/keychain-5.0.14.tgz",
|
||||
"integrity": "sha512-WTxHrLu8Dx8DNmVTOvlYtODQVsFNPgjL/tmyp61HwhBqKLqeEefH5BeU7W/W3YDlnwcL0JaUi5tIdMeu2qwRLw==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.11",
|
||||
"@libp2p/interface": "^2.5.0",
|
||||
"@noble/hashes": "^1.6.1",
|
||||
"asn1js": "^3.0.5",
|
||||
"interface-datastore": "^8.3.1",
|
||||
"merge-options": "^3.0.4",
|
||||
"multiformats": "^13.3.1",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"uint8arrays": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/hermes-estree": {
|
||||
"version": "0.25.1",
|
||||
"resolved": "http://94.130.170.209:4873/hermes-estree/-/hermes-estree-0.25.1.tgz",
|
||||
@@ -15554,6 +15463,7 @@
|
||||
"resolved": "http://94.130.170.209:4873/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
@@ -24483,6 +24393,7 @@
|
||||
"resolved": "http://94.130.170.209:4873/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
|
||||
"integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4",
|
||||
"signal-exit": "^3.0.7"
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
"@libp2p/bootstrap": "11.0.21",
|
||||
"@libp2p/circuit-relay-v2": "3.1.11",
|
||||
"@libp2p/identify": "3.0.18",
|
||||
"@libp2p/keychain": "4.1.5",
|
||||
"@libp2p/keychain": "5.0.14",
|
||||
"@libp2p/logger": "5.1.8",
|
||||
"@libp2p/tcp": "10.0.18",
|
||||
"@libp2p/webrtc": "5.0.27",
|
||||
|
||||
+37
-49
@@ -28,8 +28,9 @@ import { publicIpv4 } from 'public-ip'
|
||||
import { multiaddr } from '@multiformats/multiaddr'
|
||||
// import { webRTC } from '@libp2p/webrtc'
|
||||
import { keychain } from '@libp2p/keychain'
|
||||
import { defaultLogger } from '@libp2p/logger'
|
||||
import { unixfs } from '@helia/unixfs'
|
||||
import { generateKeyPairFromSeed } from '@libp2p/crypto/keys'
|
||||
import crypto from 'crypto'
|
||||
|
||||
// Local libraries
|
||||
import config from '../../../config/index.js'
|
||||
@@ -64,8 +65,7 @@ class IpfsAdapter {
|
||||
this.createNode = this.createNode.bind(this)
|
||||
this.stop = this.stop.bind(this)
|
||||
this.ensureBlocksDir = this.ensureBlocksDir.bind(this)
|
||||
this.getSeed = this.getSeed.bind(this)
|
||||
this.getKeychain = this.getKeychain.bind(this)
|
||||
this.getPrivateKey = this.getPrivateKey.bind(this)
|
||||
}
|
||||
|
||||
// Start an IPFS node.
|
||||
@@ -111,19 +111,6 @@ class IpfsAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
async getKeychain (datastore) {
|
||||
const keychainInit = {
|
||||
pass: await this.getSeed()
|
||||
}
|
||||
|
||||
const chain = this.keychain(keychainInit)({
|
||||
datastore,
|
||||
logger: defaultLogger()
|
||||
})
|
||||
|
||||
return chain
|
||||
}
|
||||
|
||||
// This function creates an IPFS node using Helia.
|
||||
// It returns the node as an object.
|
||||
async createNode () {
|
||||
@@ -132,25 +119,9 @@ class IpfsAdapter {
|
||||
const blockstore = new FsBlockstore(`${IPFS_DIR}/blockstore`)
|
||||
const datastore = new FsDatastore(`${IPFS_DIR}/datastore`)
|
||||
|
||||
// const keychainInit = {
|
||||
// pass: await this.getSeed()
|
||||
// }
|
||||
|
||||
// Create an identity
|
||||
let peerId
|
||||
// console.log('this.keychain: ', this.keychain)
|
||||
// const chain = this.keychain(keychainInit)({
|
||||
// datastore,
|
||||
// logger: defaultLogger()
|
||||
// })
|
||||
const chain = await this.getKeychain(datastore)
|
||||
try {
|
||||
peerId = await chain.exportPeerId('myKey')
|
||||
} catch (err) {
|
||||
await chain.createKey('myKey', 'Ed25519', 4096)
|
||||
peerId = await chain.exportPeerId('myKey')
|
||||
}
|
||||
console.log('peerId: ', peerId)
|
||||
// Get the private key.
|
||||
const privateKey = await this.getPrivateKey()
|
||||
// console.log('privateKey: ', privateKey)
|
||||
|
||||
// Configure services
|
||||
const services = {
|
||||
@@ -188,7 +159,8 @@ class IpfsAdapter {
|
||||
|
||||
// libp2p is the networking layer that underpins Helia
|
||||
const libp2p = await this.createLibp2p({
|
||||
peerId,
|
||||
// peerId,
|
||||
privateKey,
|
||||
datastore,
|
||||
addresses: {
|
||||
listen: [
|
||||
@@ -245,6 +217,8 @@ class IpfsAdapter {
|
||||
|
||||
!this.fs.existsSync(`${IPFS_DIR}/datastore`) && this.fs.mkdirSync(`${IPFS_DIR}/datastore`)
|
||||
|
||||
!this.fs.existsSync(`${IPFS_DIR}/datastore/pkcs8`) && this.fs.mkdirSync(`${IPFS_DIR}/datastore/pkcs8`)
|
||||
|
||||
// !fs.existsSync(`${IPFS_DIR}/datastore/peers`) && fs.mkdirSync(`${IPFS_DIR}/datastore/peers`)
|
||||
|
||||
return true
|
||||
@@ -254,30 +228,44 @@ class IpfsAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
// This function opens the seed used to generate the key for this IPFS peer.
|
||||
// The seed is stored in a JSON file. If it doesn't exist, a new one is created.
|
||||
async getSeed () {
|
||||
// Get the private key from disk, or generate a new one and save it,
|
||||
// if it doesn't exist.
|
||||
async getPrivateKey () {
|
||||
try {
|
||||
let seed
|
||||
|
||||
const filename = `${IPFS_DIR}/seed.json`
|
||||
const filename = `${IPFS_DIR}/privkey.json`
|
||||
|
||||
let privKeyHex
|
||||
try {
|
||||
// Try to read the JSON file containing the seed.
|
||||
seed = await this.jsonFiles.readJSON(filename)
|
||||
privKeyHex = await this.jsonFiles.readJSON(filename)
|
||||
// console.log('saved privKeyHex: ', privKeyHex)
|
||||
} catch (err) {
|
||||
const seedNum = Math.floor(Math.random() * 1000000000000000000000)
|
||||
seed = seedNum.toString()
|
||||
// Generate a new private key and save it to disk.
|
||||
|
||||
// Generate a new private key and save it to disk.
|
||||
const randomBuffer = crypto.randomBytes(32)
|
||||
// console.log('randomBuffer: ', randomBuffer)
|
||||
|
||||
privKeyHex = randomBuffer.toString('hex')
|
||||
// console.log('new privKeyHex: ', privKeyHex)
|
||||
|
||||
// Save the newly generated seed
|
||||
await this.jsonFiles.writeJSON(seed, filename)
|
||||
await this.jsonFiles.writeJSON(privKeyHex, filename)
|
||||
}
|
||||
|
||||
// console.log('getSeed() seed: ', seed)
|
||||
// Convert the saved hex string to a buffer.
|
||||
const privKeyBuf = Buffer.from(privKeyHex, 'hex')
|
||||
|
||||
return seed
|
||||
// Convert the buffer to a Uint8Array 'seed'
|
||||
const seed = new Uint8Array(privKeyBuf.buffer, privKeyBuf.byteOffset, privKeyBuf.byteLength)
|
||||
// console.log('seed: ', seed)
|
||||
|
||||
// Generate a ED25519 key pair.
|
||||
const privKey = await generateKeyPairFromSeed('Ed25519', seed)
|
||||
|
||||
return privKey
|
||||
} catch (err) {
|
||||
console.error('Error in adapters/ipfs/ipfs.js/getSeed()')
|
||||
console.error('Error in adapters/ipfs/ipfs.js/getPrivateKey(): ', err)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { assert } from 'chai'
|
||||
import sinon from 'sinon'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
import { peerIdFromString } from '@libp2p/peer-id'
|
||||
// import { peerIdFromString } from '@libp2p/peer-id'
|
||||
|
||||
// Local libraries
|
||||
import IPFSLib from '../../../src/adapters/ipfs/ipfs.js'
|
||||
@@ -165,17 +165,17 @@ describe('#IPFS-adapter', () => {
|
||||
uut.config.isCircuitRelay = false
|
||||
|
||||
// Mock dependencies and force desired code path.
|
||||
let beenCalled = false
|
||||
sandbox.stub(uut, 'getKeychain').resolves({
|
||||
exportPeerId: async () => {
|
||||
if (!beenCalled) {
|
||||
beenCalled = true
|
||||
throw new Error('test error')
|
||||
}
|
||||
return peerIdFromString('12D3KooWSXF1PnEfiA8bCG8SJduCvzdwHtvhVPK4WC6zzDoto2XP')
|
||||
},
|
||||
createKey: async () => {}
|
||||
})
|
||||
// const beenCalled = false
|
||||
// sandbox.stub(uut, 'getKeychain').resolves({
|
||||
// exportPeerId: async () => {
|
||||
// if (!beenCalled) {
|
||||
// beenCalled = true
|
||||
// throw new Error('test error')
|
||||
// }
|
||||
// return peerIdFromString('12D3KooWSXF1PnEfiA8bCG8SJduCvzdwHtvhVPK4WC6zzDoto2XP')
|
||||
// },
|
||||
// createKey: async () => {}
|
||||
// })
|
||||
sandbox.stub(uut, 'createLibp2p').resolves()
|
||||
sandbox.stub(uut, 'createHelia').resolves({})
|
||||
|
||||
@@ -203,40 +203,40 @@ describe('#IPFS-adapter', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('#getSeed', () => {
|
||||
it('should read the seed from the JSON file', async () => {
|
||||
// Mock dependencies and force desired code path
|
||||
sandbox.stub(uut.jsonFiles, 'readJSON').resolves('12345678')
|
||||
// describe('#getSeed', () => {
|
||||
// it('should read the seed from the JSON file', async () => {
|
||||
// // Mock dependencies and force desired code path
|
||||
// sandbox.stub(uut.jsonFiles, 'readJSON').resolves('12345678')
|
||||
|
||||
const result = await uut.getSeed()
|
||||
// console.log('result: ', result)
|
||||
// const result = await uut.getSeed()
|
||||
// // console.log('result: ', result)
|
||||
|
||||
assert.isString(result)
|
||||
})
|
||||
// assert.isString(result)
|
||||
// })
|
||||
|
||||
it('should generate a new seed if the JSON file is not found', async () => {
|
||||
// Mock dependencies and force desired code path
|
||||
sandbox.stub(uut.jsonFiles, 'readJSON').rejects(new Error('test error'))
|
||||
sandbox.stub(uut.jsonFiles, 'writeJSON').resolves()
|
||||
// it('should generate a new seed if the JSON file is not found', async () => {
|
||||
// // Mock dependencies and force desired code path
|
||||
// sandbox.stub(uut.jsonFiles, 'readJSON').rejects(new Error('test error'))
|
||||
// sandbox.stub(uut.jsonFiles, 'writeJSON').resolves()
|
||||
|
||||
const result = await uut.getSeed()
|
||||
// console.log('result: ', result)
|
||||
// const result = await uut.getSeed()
|
||||
// // console.log('result: ', result)
|
||||
|
||||
assert.isString(result)
|
||||
})
|
||||
// assert.isString(result)
|
||||
// })
|
||||
|
||||
it('should catch, report, and throw errors', async () => {
|
||||
try {
|
||||
// Force an error
|
||||
sandbox.stub(uut.jsonFiles, 'readJSON').rejects(new Error('test error'))
|
||||
sandbox.stub(uut.jsonFiles, 'writeJSON').rejects(new Error('test error'))
|
||||
// it('should catch, report, and throw errors', async () => {
|
||||
// try {
|
||||
// // Force an error
|
||||
// sandbox.stub(uut.jsonFiles, 'readJSON').rejects(new Error('test error'))
|
||||
// sandbox.stub(uut.jsonFiles, 'writeJSON').rejects(new Error('test error'))
|
||||
|
||||
await uut.getSeed()
|
||||
// await uut.getSeed()
|
||||
|
||||
assert.fail('Unexpected code path')
|
||||
} catch (err) {
|
||||
assert.include(err.message, 'test error')
|
||||
}
|
||||
})
|
||||
})
|
||||
// assert.fail('Unexpected code path')
|
||||
// } catch (err) {
|
||||
// assert.include(err.message, 'test error')
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user