-
Notifications
You must be signed in to change notification settings - Fork 443
/
index.ts
127 lines (108 loc) · 4.96 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
* @packageDocumentation
*
* An implementation of a peer id
*
* @example
*
* ```TypeScript
* import { peerIdFromString } from '@libp2p/peer-id'
* const peer = peerIdFromString('k51qzi5uqu5dkwkqm42v9j9kqcam2jiuvloi16g72i4i4amoo2m8u3ol3mqu6s')
*
* console.log(peer.toCID()) // CID(bafzaa...)
* console.log(peer.toString()) // "12D3K..."
* ```
*/
import { publicKeyFromMultihash } from '@libp2p/crypto/keys'
import { InvalidCIDError, InvalidMultihashError, InvalidParametersError, UnsupportedKeyTypeError } from '@libp2p/interface'
import { base58btc } from 'multiformats/bases/base58'
import { type CID, type MultibaseDecoder } from 'multiformats/cid'
import * as Digest from 'multiformats/hashes/digest'
import { identity } from 'multiformats/hashes/identity'
import { sha256 } from 'multiformats/hashes/sha2'
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
import { RSAPeerId as RSAPeerIdClass, Ed25519PeerId as Ed25519PeerIdClass, Secp256k1PeerId as Secp256k1PeerIdClass, URLPeerId as URLPeerIdClass } from './peer-id.js'
import type { Ed25519PeerId, RSAPeerId, URLPeerId, Secp256k1PeerId, PeerId, PublicKey, Ed25519PublicKey, Secp256k1PublicKey, RSAPublicKey, Ed25519PrivateKey, Secp256k1PrivateKey, RSAPrivateKey, PrivateKey } from '@libp2p/interface'
import type { MultihashDigest } from 'multiformats/hashes/interface'
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
const LIBP2P_KEY_CODE = 0x72
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920
export function peerIdFromString (str: string, decoder?: MultibaseDecoder<any>): Ed25519PeerId | Secp256k1PeerId | RSAPeerId | URLPeerId {
let multihash: MultihashDigest
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
// identity hash ed25519/secp256k1 key or sha2-256 hash of
// rsa public key - base58btc encoded either way
multihash = Digest.decode(base58btc.decode(`z${str}`))
} else {
if (decoder == null) {
throw new InvalidParametersError('Please pass a multibase decoder for strings that do not start with "1" or "Q"')
}
multihash = Digest.decode(decoder.decode(str))
}
return peerIdFromMultihash(multihash)
}
export function peerIdFromPublicKey (publicKey: Ed25519PublicKey): Ed25519PeerId
export function peerIdFromPublicKey (publicKey: Secp256k1PublicKey): Secp256k1PeerId
export function peerIdFromPublicKey (publicKey: RSAPublicKey): RSAPeerId
export function peerIdFromPublicKey (publicKey: PublicKey): PeerId
export function peerIdFromPublicKey (publicKey: PublicKey): PeerId {
if (publicKey.type === 'Ed25519') {
return new Ed25519PeerIdClass({
multihash: publicKey.toCID().multihash,
publicKey
})
} else if (publicKey.type === 'secp256k1') {
return new Secp256k1PeerIdClass({
multihash: publicKey.toCID().multihash,
publicKey
})
} else if (publicKey.type === 'RSA') {
return new RSAPeerIdClass({
multihash: publicKey.toCID().multihash,
publicKey
})
}
throw new UnsupportedKeyTypeError()
}
export function peerIdFromPrivateKey (privateKey: Ed25519PrivateKey): Ed25519PeerId
export function peerIdFromPrivateKey (privateKey: Secp256k1PrivateKey): Secp256k1PeerId
export function peerIdFromPrivateKey (privateKey: RSAPrivateKey): RSAPeerId
export function peerIdFromPrivateKey (privateKey: PrivateKey): PeerId
export function peerIdFromPrivateKey (privateKey: PrivateKey): PeerId {
return peerIdFromPublicKey(privateKey.publicKey)
}
export function peerIdFromMultihash (multihash: MultihashDigest): PeerId {
if (isSha256Multihash(multihash)) {
return new RSAPeerIdClass({ multihash })
} else if (isIdentityMultihash(multihash)) {
try {
const publicKey = publicKeyFromMultihash(multihash)
if (publicKey.type === 'Ed25519') {
return new Ed25519PeerIdClass({ multihash, publicKey })
} else if (publicKey.type === 'secp256k1') {
return new Secp256k1PeerIdClass({ multihash, publicKey })
}
} catch (err) {
// was not Ed or secp key, try URL
const url = uint8ArrayToString(multihash.digest)
return new URLPeerIdClass(new URL(url))
}
}
throw new InvalidMultihashError('Supplied PeerID Multihash is invalid')
}
export function peerIdFromCID (cid: CID): Ed25519PeerId | Secp256k1PeerId | RSAPeerId | URLPeerId {
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
throw new InvalidCIDError('Supplied PeerID CID is invalid')
}
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
const url = uint8ArrayToString(cid.multihash.digest)
return new URLPeerIdClass(new URL(url))
}
return peerIdFromMultihash(cid.multihash)
}
function isIdentityMultihash (multihash: MultihashDigest): multihash is MultihashDigest<0x0> {
return multihash.code === identity.code
}
function isSha256Multihash (multihash: MultihashDigest): multihash is MultihashDigest<0x12> {
return multihash.code === sha256.code
}