mirror of https://codeberg.org/pzp/pzp-db.git
detailed tag union for adding identity keys
This commit is contained in:
parent
07c2168f97
commit
79bc497911
37
lib/index.js
37
lib/index.js
|
@ -22,6 +22,7 @@ const { decrypt } = require('./encryption')
|
||||||
* @typedef {import('ppppp-keypair').KeypairPublicSlice} KeypairPublicSlice
|
* @typedef {import('ppppp-keypair').KeypairPublicSlice} KeypairPublicSlice
|
||||||
* @typedef {import('ppppp-keypair').KeypairPrivateSlice} KeypairPrivateSlice
|
* @typedef {import('ppppp-keypair').KeypairPrivateSlice} KeypairPrivateSlice
|
||||||
* @typedef {import('./msg-v3').Msg} Msg
|
* @typedef {import('./msg-v3').Msg} Msg
|
||||||
|
* @typedef {import('./msg-v3').IdentityData} IdentityData
|
||||||
* @typedef {import('./encryption').EncryptionFormat} EncryptionFormat
|
* @typedef {import('./encryption').EncryptionFormat} EncryptionFormat
|
||||||
*
|
*
|
||||||
* @typedef {Buffer | Uint8Array} B4A
|
* @typedef {Buffer | Uint8Array} B4A
|
||||||
|
@ -287,8 +288,13 @@ function initDB(peer, config) {
|
||||||
}
|
}
|
||||||
for (const msgHash of identityTangle.topoSort()) {
|
for (const msgHash of identityTangle.topoSort()) {
|
||||||
const msg = get(msgHash)
|
const msg = get(msgHash)
|
||||||
if (!msg?.data?.add) continue
|
if (!msg?.data) continue
|
||||||
pubkeys.add(msg.data.add)
|
/** @type {IdentityData} */
|
||||||
|
const data = msg.data
|
||||||
|
if (data.action !== 'add') continue
|
||||||
|
if (data.add.key.purpose !== 'sig') continue
|
||||||
|
if (data.add.key.algorithm !== 'ed25519') continue
|
||||||
|
pubkeys.add(data.add.key.bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,11 +366,10 @@ function initDB(peer, config) {
|
||||||
if (!rec) continue
|
if (!rec) continue
|
||||||
if (!rec.msg) continue
|
if (!rec.msg) continue
|
||||||
if (!rec.msg.data) continue
|
if (!rec.msg.data) continue
|
||||||
if (
|
if (rec.msg.metadata.identity !== IDENTITY_SELF) continue
|
||||||
rec.msg.metadata.identity === IDENTITY_SELF &&
|
if (rec.msg.metadata.domain !== domain) continue
|
||||||
rec.msg.data.add === keypair.public &&
|
const data = /** @type {IdentityData} */ (rec.msg.data)
|
||||||
rec.msg.metadata.domain === domain
|
if (data.action === 'add' && data.add.key.bytes === keypair.public) {
|
||||||
) {
|
|
||||||
const identityId = getIdentityId(rec)
|
const identityId = getIdentityId(rec)
|
||||||
if (identityId) {
|
if (identityId) {
|
||||||
cb(null, identityId)
|
cb(null, identityId)
|
||||||
|
@ -489,14 +494,26 @@ function initDB(peer, config) {
|
||||||
return cb(new Error('identity.add() failed because the consent is invalid'))
|
return cb(new Error('identity.add() failed because the consent is invalid'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @type {IdentityData} */
|
||||||
|
const data = {
|
||||||
|
action: 'add',
|
||||||
|
add: {
|
||||||
|
key: {
|
||||||
|
purpose: 'sig',
|
||||||
|
algorithm: 'ed25519',
|
||||||
|
bytes: addedKeypair.public,
|
||||||
|
},
|
||||||
|
consent,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// Fill-in tangle opts:
|
// Fill-in tangle opts:
|
||||||
const tangles = populateTangles([opts.identity])
|
|
||||||
const fullOpts = {
|
const fullOpts = {
|
||||||
identity: IDENTITY_SELF,
|
identity: IDENTITY_SELF,
|
||||||
identityTips: null,
|
identityTips: null,
|
||||||
tangles,
|
tangles: populateTangles([opts.identity]),
|
||||||
keypair: signingKeypair,
|
keypair: signingKeypair,
|
||||||
data: { add: addedKeypair.public, consent: opts.consent },
|
data,
|
||||||
domain: 'identity',
|
domain: 'identity',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,42 @@ const { IDENTITY_SELF, SIGNATURE_TAG_MSG_V3 } = require('./constants')
|
||||||
* }} Msg
|
* }} Msg
|
||||||
*
|
*
|
||||||
* @typedef {{
|
* @typedef {{
|
||||||
|
* action: 'add', add: IdentityAdd
|
||||||
|
* } | {
|
||||||
|
* action: 'del', del: IdentityDel
|
||||||
|
* }} IdentityData
|
||||||
|
*
|
||||||
|
* @typedef {{
|
||||||
|
* key: IdentityKey;
|
||||||
|
* nonce?: string;
|
||||||
|
* consent?: string;
|
||||||
|
* }} IdentityAdd
|
||||||
|
*
|
||||||
|
* @typedef {{
|
||||||
|
* key: IdentityKey;
|
||||||
|
* }} IdentityDel
|
||||||
|
*
|
||||||
|
* @typedef {{
|
||||||
|
* purpose: 'sig';
|
||||||
|
* algorithm: 'ed25519';
|
||||||
|
* bytes: string;
|
||||||
|
* }} SigKey
|
||||||
|
*
|
||||||
|
* @typedef {{
|
||||||
|
* purpose: 'subidentity';
|
||||||
|
* algorithm: 'tangle';
|
||||||
|
* bytes: string;
|
||||||
|
* }} SubidentityKey;
|
||||||
|
*
|
||||||
|
* @typedef {{
|
||||||
|
* purpose: 'box';
|
||||||
|
* algorithm: 'x25519-xsalsa20-poly1305';
|
||||||
|
* bytes: string;
|
||||||
|
* }} BoxKey;
|
||||||
|
*
|
||||||
|
* @typedef {SigKey | SubidentityKey | BoxKey} IdentityKey
|
||||||
|
*
|
||||||
|
* @typedef {{
|
||||||
* data: any;
|
* data: any;
|
||||||
* domain: string;
|
* domain: string;
|
||||||
* keypair: Keypair;
|
* keypair: Keypair;
|
||||||
|
@ -192,9 +228,21 @@ function getRandomNonce() {
|
||||||
* @returns {Msg}
|
* @returns {Msg}
|
||||||
*/
|
*/
|
||||||
function createIdentity(keypair, domain, nonce = getRandomNonce) {
|
function createIdentity(keypair, domain, nonce = getRandomNonce) {
|
||||||
const actualNonce = typeof nonce === 'function' ? nonce() : nonce
|
/** @type {IdentityData} */
|
||||||
|
const data = {
|
||||||
|
action: 'add',
|
||||||
|
add: {
|
||||||
|
key: {
|
||||||
|
purpose: 'sig',
|
||||||
|
algorithm: 'ed25519',
|
||||||
|
bytes: keypair.public,
|
||||||
|
},
|
||||||
|
nonce: typeof nonce === 'function' ? nonce() : nonce,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
return create({
|
return create({
|
||||||
data: { add: keypair.public, nonce: actualNonce },
|
data,
|
||||||
identity: IDENTITY_SELF,
|
identity: IDENTITY_SELF,
|
||||||
identityTips: null,
|
identityTips: null,
|
||||||
keypair,
|
keypair,
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"bs58": "~5.0.0",
|
"bs58": "~5.0.0",
|
||||||
"json-canon": "~1.0.0",
|
"json-canon": "~1.0.0",
|
||||||
"obz": "~1.1.0",
|
"obz": "~1.1.0",
|
||||||
"ppppp-keypair": "github:staltz/ppppp-keypair",
|
"ppppp-keypair": "file:../keypair",
|
||||||
"promisify-4loc": "~1.0.0",
|
"promisify-4loc": "~1.0.0",
|
||||||
"push-stream": "~11.2.0",
|
"push-stream": "~11.2.0",
|
||||||
"set.prototype.union": "~1.0.2"
|
"set.prototype.union": "~1.0.2"
|
||||||
|
|
82
protospec.md
82
protospec.md
|
@ -47,10 +47,7 @@ Msgs in an identity tangle are special because they have empty `identity` and `i
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
interface Msg {
|
interface Msg {
|
||||||
data: {
|
data: IdentityData
|
||||||
add: string // pubkey being added to the identity
|
|
||||||
nonce?: string // nonce required only on the identity tangle's root
|
|
||||||
}
|
|
||||||
metadata: {
|
metadata: {
|
||||||
dataHash: ContentHash
|
dataHash: ContentHash
|
||||||
dataSize: number
|
dataSize: number
|
||||||
|
@ -68,13 +65,82 @@ interface Msg {
|
||||||
pubkey: Pubkey
|
pubkey: Pubkey
|
||||||
sig: Signature
|
sig: Signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IdentityData =
|
||||||
|
| { action: 'add' add: IdentityAdd }
|
||||||
|
| { action: 'del' del: IdentityDel }
|
||||||
|
|
||||||
|
type IdentityAdd = {
|
||||||
|
key: Key
|
||||||
|
nonce?: string // nonce required only on the identity tangle's root
|
||||||
|
consent?: string // base58 encoded signature of the string `:identity-add:<ID>` where `<ID>` is the identity's ID, required only on non-root msgs
|
||||||
|
}
|
||||||
|
|
||||||
|
type IdentityDel = {
|
||||||
|
key: Key
|
||||||
|
}
|
||||||
|
|
||||||
|
type Key =
|
||||||
|
| {
|
||||||
|
purpose: 'sig' // digital signatures
|
||||||
|
algorithm: 'ed25519' // libsodium crypto_sign_detached
|
||||||
|
bytes: string // base58 encoded string for the public key being added
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
purpose: 'subidentity'
|
||||||
|
algorithm: 'tangle' // PPPPP tangle
|
||||||
|
bytes: string // subidentity ID
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
// WIP!!
|
||||||
|
purpose: 'box' // asymmetric encryption
|
||||||
|
algorithm: 'x25519-xsalsa20-poly1305' // libsodium crypto_box_easy
|
||||||
|
bytes: string // base58 encoded string of the public key
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The `data` object varies:
|
Examples of `IdentityData`:
|
||||||
|
|
||||||
- In the first message: `{ add: <pubkey>, nonce: <nonce> }`
|
- Registering the first signing pubkey:
|
||||||
- In subsequent messages: `{ add: <pubkey>, consent: <consent> }`
|
```json
|
||||||
- Where `<consent>` is the base58-encoded signature of the string `:identity-add:<ID>` where `<ID>` is the identity's ID
|
{
|
||||||
|
"action": "add",
|
||||||
|
"add": {
|
||||||
|
"key": {
|
||||||
|
"purpose": "sig",
|
||||||
|
"algorithm": "ed25519",
|
||||||
|
"bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9"
|
||||||
|
},
|
||||||
|
"nonce": "6GHR1ZFFSB3C5qAGwmSwVH8f7byNo8Cqwn5PcyG3qDvS"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Registering a subidentity:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "add",
|
||||||
|
"add": {
|
||||||
|
"key": {
|
||||||
|
"purpose": "subidentity",
|
||||||
|
"algorithm": "tangle",
|
||||||
|
"bytes": "6yqq7iwyJEKdofJ3xpRLEq"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
- Revoking a signing pubkey:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"action": "del",
|
||||||
|
"del": {
|
||||||
|
"key": {
|
||||||
|
"purpose": "sig",
|
||||||
|
"algorithm": "ed25519",
|
||||||
|
"bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Feed root
|
## Feed root
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,21 @@ test('identity.add()', async (t) => {
|
||||||
assert.ok(identityRec1, 'identityRec1 exists')
|
assert.ok(identityRec1, 'identityRec1 exists')
|
||||||
const { hash, msg } = identityRec1
|
const { hash, msg } = identityRec1
|
||||||
assert.ok(hash, 'hash exists')
|
assert.ok(hash, 'hash exists')
|
||||||
assert.equal(msg.data.add, keypair2.public, 'msg.data.add NEW KEY')
|
assert.deepEqual(
|
||||||
|
msg.data,
|
||||||
|
{
|
||||||
|
action: 'add',
|
||||||
|
add: {
|
||||||
|
key: {
|
||||||
|
purpose: 'sig',
|
||||||
|
algorithm: 'ed25519',
|
||||||
|
bytes: keypair2.public,
|
||||||
|
},
|
||||||
|
consent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'msg.data.add NEW KEY'
|
||||||
|
)
|
||||||
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
|
|
@ -19,10 +19,27 @@ test('identity.create() with just "domain"', async (t) => {
|
||||||
.call(null, { keypair, path: DIR })
|
.call(null, { keypair, path: DIR })
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
const identity = await p(peer.db.identity.create)({ domain: 'person' })
|
const identity = await p(peer.db.identity.create)({
|
||||||
|
domain: 'person',
|
||||||
|
_nonce: 'MYNONCE',
|
||||||
|
})
|
||||||
assert.ok(identity, 'identityRec0 exists')
|
assert.ok(identity, 'identityRec0 exists')
|
||||||
const msg = peer.db.get(identity)
|
const msg = peer.db.get(identity)
|
||||||
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
assert.deepEqual(
|
||||||
|
msg.data,
|
||||||
|
{
|
||||||
|
action: 'add',
|
||||||
|
add: {
|
||||||
|
key: {
|
||||||
|
purpose: 'sig',
|
||||||
|
algorithm: 'ed25519',
|
||||||
|
bytes: keypair.public,
|
||||||
|
},
|
||||||
|
nonce: 'MYNONCE',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'msg.data.add'
|
||||||
|
)
|
||||||
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -51,7 +68,7 @@ test('identity.create() with "keypair" and "domain"', async (t) => {
|
||||||
})
|
})
|
||||||
assert.ok(identity, 'identity created')
|
assert.ok(identity, 'identity created')
|
||||||
const msg = peer.db.get(identity)
|
const msg = peer.db.get(identity)
|
||||||
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
assert.equal(msg.data.add.key.bytes, keypair.public, 'msg.data.add')
|
||||||
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -117,8 +134,8 @@ test('identity.findOrCreate() can create', async (t) => {
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
let gotError = false
|
let gotError = false
|
||||||
await p(peer.db.identity.find)({ keypair, domain }).catch(err => {
|
await p(peer.db.identity.find)({ keypair, domain }).catch((err) => {
|
||||||
assert.equal(err.cause, 'ENOENT');
|
assert.equal(err.cause, 'ENOENT')
|
||||||
gotError = true
|
gotError = true
|
||||||
})
|
})
|
||||||
assert.ok(gotError, 'identity not found')
|
assert.ok(gotError, 'identity not found')
|
||||||
|
@ -126,7 +143,7 @@ test('identity.findOrCreate() can create', async (t) => {
|
||||||
const identity = await p(peer.db.identity.findOrCreate)({ keypair, domain })
|
const identity = await p(peer.db.identity.findOrCreate)({ keypair, domain })
|
||||||
assert.ok(identity, 'identity created')
|
assert.ok(identity, 'identity created')
|
||||||
const msg = peer.db.get(identity)
|
const msg = peer.db.get(identity)
|
||||||
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
assert.equal(msg.data.add.key.bytes, keypair.public, 'msg.data.add')
|
||||||
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -138,4 +155,3 @@ test('identity.findOrCreate() can create', async (t) => {
|
||||||
|
|
||||||
await p(peer.close)()
|
await p(peer.close)()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,23 @@ test('MsgV3.createIdentity()', (t) => {
|
||||||
const identityMsg0 = MsgV3.createIdentity(keypair, 'person', 'MYNONCE')
|
const identityMsg0 = MsgV3.createIdentity(keypair, 'person', 'MYNONCE')
|
||||||
console.log(JSON.stringify(identityMsg0, null, 2))
|
console.log(JSON.stringify(identityMsg0, null, 2))
|
||||||
|
|
||||||
assert.equal(identityMsg0.data.add, keypair.public, 'data.add')
|
assert.deepEqual(
|
||||||
assert.equal(identityMsg0.metadata.dataHash, 'THi3VkJeaf8aTkLSNJUdFD', 'hash')
|
identityMsg0.data,
|
||||||
assert.equal(identityMsg0.metadata.dataSize, 72, 'size')
|
{
|
||||||
|
action: 'add',
|
||||||
|
add: {
|
||||||
|
key: {
|
||||||
|
purpose: 'sig',
|
||||||
|
algorithm: 'ed25519',
|
||||||
|
bytes: keypair.public,
|
||||||
|
},
|
||||||
|
nonce: 'MYNONCE',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'data'
|
||||||
|
)
|
||||||
|
assert.equal(identityMsg0.metadata.dataHash, 'C9XZXiZV4kxD6MtVqNkuBw', 'hash')
|
||||||
|
assert.equal(identityMsg0.metadata.dataSize, 143, 'size')
|
||||||
assert.equal(identityMsg0.metadata.identity, 'self', 'identity')
|
assert.equal(identityMsg0.metadata.identity, 'self', 'identity')
|
||||||
assert.equal(identityMsg0.metadata.identityTips, null, 'identityTips')
|
assert.equal(identityMsg0.metadata.identityTips, null, 'identityTips')
|
||||||
assert.deepEqual(identityMsg0.metadata.tangles, {}, 'tangles')
|
assert.deepEqual(identityMsg0.metadata.tangles, {}, 'tangles')
|
||||||
|
@ -21,7 +35,7 @@ test('MsgV3.createIdentity()', (t) => {
|
||||||
assert.equal(identityMsg0.pubkey, keypair.public, 'pubkey')
|
assert.equal(identityMsg0.pubkey, keypair.public, 'pubkey')
|
||||||
|
|
||||||
identity = MsgV3.getMsgHash(identityMsg0)
|
identity = MsgV3.getMsgHash(identityMsg0)
|
||||||
assert.equal(identity, 'v7vBrnrCTahjgkpoaZrWm', 'identity ID')
|
assert.equal(identity, 'NwZbYERYSrShDwcKrrLVYe', 'identity ID')
|
||||||
})
|
})
|
||||||
|
|
||||||
let rootMsg = null
|
let rootMsg = null
|
||||||
|
@ -43,7 +57,7 @@ test('MsgV3.createRoot()', (t) => {
|
||||||
assert.equal(rootMsg.pubkey, keypair.public, 'pubkey')
|
assert.equal(rootMsg.pubkey, keypair.public, 'pubkey')
|
||||||
|
|
||||||
rootHash = MsgV3.getMsgHash(rootMsg)
|
rootHash = MsgV3.getMsgHash(rootMsg)
|
||||||
assert.equal(rootHash, 'HPtwPD552ajEurwpgQRfTX', 'root hash')
|
assert.equal(rootHash, '2yqmqJLffAeomD93izwjx9', 'root hash')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('MsgV3.create()', (t) => {
|
test('MsgV3.create()', (t) => {
|
||||||
|
@ -68,7 +82,15 @@ test('MsgV3.create()', (t) => {
|
||||||
assert.deepEqual(msg1.data, data, 'data')
|
assert.deepEqual(msg1.data, data, 'data')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
Object.keys(msg1.metadata),
|
Object.keys(msg1.metadata),
|
||||||
['dataHash', 'dataSize', 'identity', 'identityTips', 'tangles', 'domain', 'v'],
|
[
|
||||||
|
'dataHash',
|
||||||
|
'dataSize',
|
||||||
|
'identity',
|
||||||
|
'identityTips',
|
||||||
|
'tangles',
|
||||||
|
'domain',
|
||||||
|
'v',
|
||||||
|
],
|
||||||
'metadata shape'
|
'metadata shape'
|
||||||
)
|
)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -78,14 +100,22 @@ test('MsgV3.create()', (t) => {
|
||||||
)
|
)
|
||||||
assert.deepEqual(msg1.metadata.dataSize, 23, 'metadata.dataSize')
|
assert.deepEqual(msg1.metadata.dataSize, 23, 'metadata.dataSize')
|
||||||
assert.equal(msg1.metadata.identity, identity, 'metadata.identity')
|
assert.equal(msg1.metadata.identity, identity, 'metadata.identity')
|
||||||
assert.deepEqual(msg1.metadata.identityTips, [identity], 'metadata.identityTips')
|
assert.deepEqual(
|
||||||
|
msg1.metadata.identityTips,
|
||||||
|
[identity],
|
||||||
|
'metadata.identityTips'
|
||||||
|
)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
Object.keys(msg1.metadata.tangles),
|
Object.keys(msg1.metadata.tangles),
|
||||||
[rootHash],
|
[rootHash],
|
||||||
'metadata.tangles'
|
'metadata.tangles'
|
||||||
)
|
)
|
||||||
assert.equal(msg1.metadata.tangles[rootHash].depth, 1, 'tangle depth')
|
assert.equal(msg1.metadata.tangles[rootHash].depth, 1, 'tangle depth')
|
||||||
assert.deepEqual(msg1.metadata.tangles[rootHash].prev, [rootHash], 'tangle prev')
|
assert.deepEqual(
|
||||||
|
msg1.metadata.tangles[rootHash].prev,
|
||||||
|
[rootHash],
|
||||||
|
'tangle prev'
|
||||||
|
)
|
||||||
assert.equal(msg1.metadata.domain, 'post', 'metadata.domain')
|
assert.equal(msg1.metadata.domain, 'post', 'metadata.domain')
|
||||||
assert.deepEqual(msg1.metadata.v, 3, 'metadata.v')
|
assert.deepEqual(msg1.metadata.v, 3, 'metadata.v')
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
@ -95,11 +125,11 @@ test('MsgV3.create()', (t) => {
|
||||||
)
|
)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
msg1.sig,
|
msg1.sig,
|
||||||
'3ucLkFxXJkbX6N7qZQm5PNop2tQ5Z1E9oCVB4HCZjeD3Mn7EXMrgZzCDZfpLTVUUBRqSBQJFxL1j5jNWKFeidHgV',
|
'2GsXePCkaJk1emgjRmwTrn9qqA5GozG8BrDa9je4SeCNJX8KVYr45MyZGmfkJsGBoMocZCMhP4jiFgdL1PqURhx6',
|
||||||
'sig'
|
'sig'
|
||||||
)
|
)
|
||||||
|
|
||||||
const msgHash1 = 'FK4jCKFZDGwecydC8bitgR'
|
const msgHash1 = 'BTybPnRjVjVZMdWBr52kfz'
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
MsgV3.getMsgId(msg1),
|
MsgV3.getMsgId(msg1),
|
||||||
|
@ -128,7 +158,15 @@ test('MsgV3.create()', (t) => {
|
||||||
assert.deepEqual(msg2.data, data2, 'data')
|
assert.deepEqual(msg2.data, data2, 'data')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
Object.keys(msg2.metadata),
|
Object.keys(msg2.metadata),
|
||||||
['dataHash', 'dataSize', 'identity', 'identityTips', 'tangles', 'domain', 'v'],
|
[
|
||||||
|
'dataHash',
|
||||||
|
'dataSize',
|
||||||
|
'identity',
|
||||||
|
'identityTips',
|
||||||
|
'tangles',
|
||||||
|
'domain',
|
||||||
|
'v',
|
||||||
|
],
|
||||||
'metadata shape'
|
'metadata shape'
|
||||||
)
|
)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -138,14 +176,22 @@ test('MsgV3.create()', (t) => {
|
||||||
)
|
)
|
||||||
assert.deepEqual(msg2.metadata.dataSize, 21, 'metadata.dataSize')
|
assert.deepEqual(msg2.metadata.dataSize, 21, 'metadata.dataSize')
|
||||||
assert.equal(msg2.metadata.identity, identity, 'metadata.identity')
|
assert.equal(msg2.metadata.identity, identity, 'metadata.identity')
|
||||||
assert.deepEqual(msg2.metadata.identityTips, [identity], 'metadata.identityTips')
|
assert.deepEqual(
|
||||||
|
msg2.metadata.identityTips,
|
||||||
|
[identity],
|
||||||
|
'metadata.identityTips'
|
||||||
|
)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
Object.keys(msg2.metadata.tangles),
|
Object.keys(msg2.metadata.tangles),
|
||||||
[rootHash],
|
[rootHash],
|
||||||
'metadata.tangles'
|
'metadata.tangles'
|
||||||
)
|
)
|
||||||
assert.equal(msg2.metadata.tangles[rootHash].depth, 2, 'tangle depth')
|
assert.equal(msg2.metadata.tangles[rootHash].depth, 2, 'tangle depth')
|
||||||
assert.deepEqual(msg2.metadata.tangles[rootHash].prev, [msgHash1], 'tangle prev')
|
assert.deepEqual(
|
||||||
|
msg2.metadata.tangles[rootHash].prev,
|
||||||
|
[msgHash1],
|
||||||
|
'tangle prev'
|
||||||
|
)
|
||||||
assert.equal(msg2.metadata.domain, 'post', 'metadata.domain')
|
assert.equal(msg2.metadata.domain, 'post', 'metadata.domain')
|
||||||
assert.deepEqual(msg2.metadata.v, 3, 'metadata.v')
|
assert.deepEqual(msg2.metadata.v, 3, 'metadata.v')
|
||||||
assert.equal(
|
assert.equal(
|
||||||
|
@ -155,13 +201,13 @@ test('MsgV3.create()', (t) => {
|
||||||
)
|
)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
msg2.sig,
|
msg2.sig,
|
||||||
'RtHPPccZNp6c65SnCrfjsNVB6We6G4Ja1oi68AdLuzxSjWNayxepagYJQwgP635E4b55xNGckMiFvJF9Vsn3oAi',
|
'EA8PUp44ZBdgsXa4DRioejc4W5NMapoA9oUbgJwQSsvKDj9nh3oAHn7ScnZo2Hfw67JzHeZXeXVwgLCWzsKCFYw',
|
||||||
'sig'
|
'sig'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
MsgV3.getMsgId(msg2),
|
MsgV3.getMsgId(msg2),
|
||||||
`ppppp:message/v3/${identity}/post/AYXun8rEc3SNGZYM252TAS`,
|
`ppppp:message/v3/${identity}/post/3bwFna3PvkSNxssPd9QDYe`,
|
||||||
'getMsgId'
|
'getMsgId'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue