@leofcoin/peernet 1.2.23 → 1.2.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yml +34 -0
- package/exports/browser/{browser-Dx3X9MHO.js → browser-BOiH47em.js} +1 -1
- package/exports/browser/{browser-BKlRwB0A.js → browser-BuaFyOQj.js} +1 -1
- package/exports/browser/{client-eYBPUrVq.js → client-B2wkkpij.js} +4 -4
- package/exports/browser/{identity-BS_eDrwh.js → identity-DWchlbmt.js} +35 -13
- package/exports/browser/identity.js +1 -1
- package/exports/browser/{index-B91mcwxm.js → index-s61gSKAd.js} +1 -1
- package/exports/browser/{messages-D0Goitr6.js → messages-CZ-3jxiD.js} +2 -2
- package/exports/browser/{peernet-CgU-ZdIe.js → peernet-Coi40mR_.js} +3 -3
- package/exports/browser/peernet.js +2 -2
- package/exports/identity.js +34 -12
- package/exports/store.js +0 -3
- package/exports/types/identity.d.ts +8 -0
- package/package.json +6 -1
- package/rollup.config.js +10 -23
- package/src/identity.ts +48 -18
- package/test/peernet.test.js +25 -1
- package/test-output.log +0 -84
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Release package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: release-package
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
publish:
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v7
|
|
19
|
+
|
|
20
|
+
- uses: actions/setup-node@v7
|
|
21
|
+
with:
|
|
22
|
+
node-version: 24
|
|
23
|
+
registry-url: https://registry.npmjs.org
|
|
24
|
+
cache: npm
|
|
25
|
+
|
|
26
|
+
- name: Use supported npm CLI
|
|
27
|
+
run: npm install --global npm@11.17.0
|
|
28
|
+
|
|
29
|
+
- run: npm ci
|
|
30
|
+
- run: npm run build
|
|
31
|
+
- run: npm test
|
|
32
|
+
|
|
33
|
+
- name: Publish with provenance
|
|
34
|
+
run: npm publish --access public --provenance
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as LittlePubSub, d as deflate_1, i as inflate_1, c as createDebugger } from './peernet-
|
|
2
|
-
import './identity-
|
|
1
|
+
import { L as LittlePubSub, d as deflate_1, i as inflate_1, c as createDebugger } from './peernet-Coi40mR_.js';
|
|
2
|
+
import './identity-DWchlbmt.js';
|
|
3
3
|
import 'crypto';
|
|
4
4
|
import './value-C3vAp-wb.js';
|
|
5
5
|
|
|
@@ -232,7 +232,7 @@ class SocketRequestClient {
|
|
|
232
232
|
const init = async () => {
|
|
233
233
|
// @ts-ignore
|
|
234
234
|
if (!globalThis.WebSocket && !this.#experimentalWebsocket)
|
|
235
|
-
globalThis.WebSocket = (await import('./browser-
|
|
235
|
+
globalThis.WebSocket = (await import('./browser-BuaFyOQj.js').then(function (n) { return n.b; })).default.w3cwebsocket;
|
|
236
236
|
const client = new WebSocket(this.#url, this.#protocol);
|
|
237
237
|
if (this.#experimentalWebsocket) {
|
|
238
238
|
client.addEventListener('error', this.onerror);
|
|
@@ -1303,7 +1303,7 @@ class Client {
|
|
|
1303
1303
|
}
|
|
1304
1304
|
}
|
|
1305
1305
|
async #loadNodeWebrtcImplementation() {
|
|
1306
|
-
const koushWrtcModule = await import('./browser-
|
|
1306
|
+
const koushWrtcModule = await import('./browser-BOiH47em.js').then(function (n) { return n.b; });
|
|
1307
1307
|
const koushWrtc = koushWrtcModule.default;
|
|
1308
1308
|
if (!isWrtcImplementation(koushWrtc)) {
|
|
1309
1309
|
throw new Error('@koush/wrtc does not match required wrtc contract');
|
|
@@ -8259,6 +8259,38 @@ function requireBrowser () {
|
|
|
8259
8259
|
var browserExports = requireBrowser();
|
|
8260
8260
|
var qrcode = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
|
|
8261
8261
|
|
|
8262
|
+
const accountDerivationSchemes = [
|
|
8263
|
+
{
|
|
8264
|
+
name: 'current',
|
|
8265
|
+
accountIndex: (index) => index + 1,
|
|
8266
|
+
addressIndex: 1
|
|
8267
|
+
},
|
|
8268
|
+
{
|
|
8269
|
+
name: 'legacy-v1',
|
|
8270
|
+
accountIndex: (index) => index,
|
|
8271
|
+
addressIndex: 0
|
|
8272
|
+
}
|
|
8273
|
+
];
|
|
8274
|
+
const resolveAccountWallets = async (wallet, accounts) => {
|
|
8275
|
+
for (const scheme of accountDerivationSchemes) {
|
|
8276
|
+
const wallets = new Map();
|
|
8277
|
+
let matches = true;
|
|
8278
|
+
for (const [index, [, externalAddress, internalAddress]] of accounts.entries()) {
|
|
8279
|
+
const account = wallet.account(scheme.accountIndex(index));
|
|
8280
|
+
const external = (await account.external(scheme.addressIndex));
|
|
8281
|
+
const internal = (await account.internal(scheme.addressIndex));
|
|
8282
|
+
if ((await external.address) !== externalAddress || (await internal.address) !== internalAddress) {
|
|
8283
|
+
matches = false;
|
|
8284
|
+
break;
|
|
8285
|
+
}
|
|
8286
|
+
wallets.set(externalAddress, external);
|
|
8287
|
+
wallets.set(internalAddress, internal);
|
|
8288
|
+
}
|
|
8289
|
+
if (matches)
|
|
8290
|
+
return wallets;
|
|
8291
|
+
}
|
|
8292
|
+
throw new Error('stored accounts do not match this identity under a supported derivation scheme');
|
|
8293
|
+
};
|
|
8262
8294
|
class Identity {
|
|
8263
8295
|
#wallet;
|
|
8264
8296
|
#accountWallets = new Map();
|
|
@@ -8299,7 +8331,7 @@ class Identity {
|
|
|
8299
8331
|
this.selectedAccount = new TextDecoder().decode(selected);
|
|
8300
8332
|
}
|
|
8301
8333
|
else {
|
|
8302
|
-
const importee = await import(/* webpackChunkName: "generate-account" */ './index-
|
|
8334
|
+
const importee = await import(/* webpackChunkName: "generate-account" */ './index-s61gSKAd.js');
|
|
8303
8335
|
const { identity, accounts } = await importee.default(password, this.network);
|
|
8304
8336
|
await globalThis.accountStore.put('public', JSON.stringify({ walletId: identity.walletId }));
|
|
8305
8337
|
await globalThis.walletStore.put('version', String(1));
|
|
@@ -8316,18 +8348,8 @@ class Identity {
|
|
|
8316
8348
|
await this.#loadAccountWallets();
|
|
8317
8349
|
}
|
|
8318
8350
|
async #loadAccountWallets() {
|
|
8319
|
-
this.#accountWallets.clear();
|
|
8320
8351
|
const accounts = await this.getAccounts();
|
|
8321
|
-
|
|
8322
|
-
const account = this.#wallet.account(index + 1);
|
|
8323
|
-
const external = (await account.external(1));
|
|
8324
|
-
const internal = (await account.internal(1));
|
|
8325
|
-
if ((await external.address) !== externalAddress || (await internal.address) !== internalAddress) {
|
|
8326
|
-
throw new Error(`stored account ${index + 1} does not match this identity`);
|
|
8327
|
-
}
|
|
8328
|
-
this.#accountWallets.set(externalAddress, external);
|
|
8329
|
-
this.#accountWallets.set(internalAddress, internal);
|
|
8330
|
-
}
|
|
8352
|
+
this.#accountWallets = await resolveAccountWallets(this.#wallet, accounts);
|
|
8331
8353
|
if (!this.#accountWallets.has(this.selectedAccount)) {
|
|
8332
8354
|
throw new Error(`selected account ${this.selectedAccount} is not part of this identity`);
|
|
8333
8355
|
}
|
|
@@ -8368,4 +8390,4 @@ class Identity {
|
|
|
8368
8390
|
}
|
|
8369
8391
|
}
|
|
8370
8392
|
|
|
8371
|
-
export { Identity as I, MultiWallet as M, base58$1 as a, base as b, index as c, index$2 as d, index$4 as e, createSHA512 as f, createSHA384 as g, createSHA256 as h, index$3 as i, createSHA224 as j, createSHA1 as k, encrypt as l, getDefaultExportFromCjs as m };
|
|
8393
|
+
export { Identity as I, MultiWallet as M, base58$1 as a, base as b, index as c, index$2 as d, index$4 as e, createSHA512 as f, createSHA384 as g, createSHA256 as h, index$3 as i, createSHA224 as j, createSHA1 as k, encrypt as l, getDefaultExportFromCjs as m, resolveAccountWallets as r };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { I as default } from './identity-
|
|
1
|
+
export { I as default, r as resolveAccountWallets } from './identity-DWchlbmt.js';
|
|
2
2
|
import 'crypto';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as index$2, b as base, a as base58$1, c as index$3, d as index$4, e as index$5, f as createSHA512, g as createSHA384, h as createSHA256, j as createSHA224, k as createSHA1, I as Identity } from './identity-
|
|
1
|
+
import { i as index$2, b as base, a as base58$1, c as index$3, d as index$4, e as index$5, f as createSHA512, g as createSHA384, h as createSHA256, j as createSHA224, k as createSHA1, I as Identity } from './identity-DWchlbmt.js';
|
|
2
2
|
import { K as KeyPath, a as KeyValue } from './value-C3vAp-wb.js';
|
|
3
3
|
|
|
4
4
|
const getTargets = () => Array.from([]);
|
|
@@ -8615,7 +8615,7 @@ class Peernet {
|
|
|
8615
8615
|
await getAddress();
|
|
8616
8616
|
this.storePrefix = options.storePrefix;
|
|
8617
8617
|
this.root = options.root;
|
|
8618
|
-
const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile } = await import(/* webpackChunkName: "messages" */ './messages-
|
|
8618
|
+
const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile } = await import(/* webpackChunkName: "messages" */ './messages-CZ-3jxiD.js');
|
|
8619
8619
|
/**
|
|
8620
8620
|
* proto Object containing protos
|
|
8621
8621
|
* @type {Object}
|
|
@@ -8662,7 +8662,7 @@ class Peernet {
|
|
|
8662
8662
|
if (this.#starting || this.#started)
|
|
8663
8663
|
return;
|
|
8664
8664
|
this.#starting = true;
|
|
8665
|
-
const importee = await import('./client-
|
|
8665
|
+
const importee = await import('./client-B2wkkpij.js');
|
|
8666
8666
|
/**
|
|
8667
8667
|
* @access public
|
|
8668
8668
|
* @type {PeernetClient}
|
package/exports/identity.js
CHANGED
|
@@ -4,6 +4,38 @@ import { decrypt } from '@leofcoin/identity-utils';
|
|
|
4
4
|
import QrScanner from 'qr-scanner';
|
|
5
5
|
import qrcode from 'qrcode';
|
|
6
6
|
|
|
7
|
+
const accountDerivationSchemes = [
|
|
8
|
+
{
|
|
9
|
+
name: 'current',
|
|
10
|
+
accountIndex: (index) => index + 1,
|
|
11
|
+
addressIndex: 1
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: 'legacy-v1',
|
|
15
|
+
accountIndex: (index) => index,
|
|
16
|
+
addressIndex: 0
|
|
17
|
+
}
|
|
18
|
+
];
|
|
19
|
+
const resolveAccountWallets = async (wallet, accounts) => {
|
|
20
|
+
for (const scheme of accountDerivationSchemes) {
|
|
21
|
+
const wallets = new Map();
|
|
22
|
+
let matches = true;
|
|
23
|
+
for (const [index, [, externalAddress, internalAddress]] of accounts.entries()) {
|
|
24
|
+
const account = wallet.account(scheme.accountIndex(index));
|
|
25
|
+
const external = (await account.external(scheme.addressIndex));
|
|
26
|
+
const internal = (await account.internal(scheme.addressIndex));
|
|
27
|
+
if ((await external.address) !== externalAddress || (await internal.address) !== internalAddress) {
|
|
28
|
+
matches = false;
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
wallets.set(externalAddress, external);
|
|
32
|
+
wallets.set(internalAddress, internal);
|
|
33
|
+
}
|
|
34
|
+
if (matches)
|
|
35
|
+
return wallets;
|
|
36
|
+
}
|
|
37
|
+
throw new Error('stored accounts do not match this identity under a supported derivation scheme');
|
|
38
|
+
};
|
|
7
39
|
class Identity {
|
|
8
40
|
#wallet;
|
|
9
41
|
#accountWallets = new Map();
|
|
@@ -61,18 +93,8 @@ class Identity {
|
|
|
61
93
|
await this.#loadAccountWallets();
|
|
62
94
|
}
|
|
63
95
|
async #loadAccountWallets() {
|
|
64
|
-
this.#accountWallets.clear();
|
|
65
96
|
const accounts = await this.getAccounts();
|
|
66
|
-
|
|
67
|
-
const account = this.#wallet.account(index + 1);
|
|
68
|
-
const external = (await account.external(1));
|
|
69
|
-
const internal = (await account.internal(1));
|
|
70
|
-
if ((await external.address) !== externalAddress || (await internal.address) !== internalAddress) {
|
|
71
|
-
throw new Error(`stored account ${index + 1} does not match this identity`);
|
|
72
|
-
}
|
|
73
|
-
this.#accountWallets.set(externalAddress, external);
|
|
74
|
-
this.#accountWallets.set(internalAddress, internal);
|
|
75
|
-
}
|
|
97
|
+
this.#accountWallets = await resolveAccountWallets(this.#wallet, accounts);
|
|
76
98
|
if (!this.#accountWallets.has(this.selectedAccount)) {
|
|
77
99
|
throw new Error(`selected account ${this.selectedAccount} is not part of this identity`);
|
|
78
100
|
}
|
|
@@ -113,4 +135,4 @@ class Identity {
|
|
|
113
135
|
}
|
|
114
136
|
}
|
|
115
137
|
|
|
116
|
-
export { Identity as default };
|
|
138
|
+
export { Identity as default, resolveAccountWallets };
|
package/exports/store.js
CHANGED
|
@@ -102,9 +102,6 @@ class Store {
|
|
|
102
102
|
this.root = await init(root, homedir);
|
|
103
103
|
this.version = version;
|
|
104
104
|
this.db = new ClassicLevel(join(this.root, this.name), { valueEncoding: 'view' });
|
|
105
|
-
if (typeof this.db.open === 'function') {
|
|
106
|
-
await this.db.open();
|
|
107
|
-
}
|
|
108
105
|
}
|
|
109
106
|
toKeyPath(key) {
|
|
110
107
|
if (!key.isKeyPath())
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
+
import MultiWallet from '@leofcoin/multi-wallet';
|
|
1
2
|
import type { base58String } from '@vandeurenglenn/base58';
|
|
3
|
+
type StoredAccount = [name: string, externalAddress: string, internalAddress: string];
|
|
4
|
+
type AccountWallet = {
|
|
5
|
+
address: Promise<string>;
|
|
6
|
+
sign: (hash: Uint8Array) => Promise<Uint8Array>;
|
|
7
|
+
};
|
|
8
|
+
export declare const resolveAccountWallets: (wallet: MultiWallet, accounts: StoredAccount[]) => Promise<Map<string, AccountWallet>>;
|
|
2
9
|
export default class Identity {
|
|
3
10
|
#private;
|
|
4
11
|
network: string;
|
|
@@ -17,3 +24,4 @@ export default class Identity {
|
|
|
17
24
|
exportQR(password: string): Promise<string>;
|
|
18
25
|
importQR(image: File | Blob, password: string): Promise<void>;
|
|
19
26
|
}
|
|
27
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leofcoin/peernet",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.25",
|
|
4
4
|
"description": "",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/leofcoin/peernet.git"
|
|
8
|
+
},
|
|
5
9
|
"browser": "./exports/browser/peernet.js",
|
|
6
10
|
"exports": {
|
|
7
11
|
".": {
|
|
@@ -99,6 +103,7 @@
|
|
|
99
103
|
"keywords": [],
|
|
100
104
|
"author": "",
|
|
101
105
|
"license": "MIT",
|
|
106
|
+
"packageManager": "npm@11.17.0",
|
|
102
107
|
"dependencies": {
|
|
103
108
|
"@leofcoin/codec-format-interface": "^1.8.2",
|
|
104
109
|
"@leofcoin/codecs": "^1.1.2",
|
package/rollup.config.js
CHANGED
|
@@ -27,20 +27,10 @@ const walk = async (dir) => {
|
|
|
27
27
|
|
|
28
28
|
const isHashedChunk = (runtimePath) => /-[A-Za-z0-9_-]{8,}\.js$/.test(runtimePath)
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const code = await readFile(filePath, 'utf8')
|
|
35
|
-
const normalized = code
|
|
36
|
-
.replaceAll("'./src/prompts/password.js'", "'./prompts/password.js'")
|
|
37
|
-
.replace(/(["'])\.\/Users\/[^"']*\/src\/prompts\/password\.js\1/g, '$1./prompts/password.js$1')
|
|
38
|
-
|
|
39
|
-
if (normalized !== code) {
|
|
40
|
-
await writeFile(filePath, normalized)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
})
|
|
30
|
+
const isPromptImport = (id) =>
|
|
31
|
+
id === './prompts/password.js' ||
|
|
32
|
+
id === './src/prompts/password.js' ||
|
|
33
|
+
id.endsWith('/src/prompts/password.js')
|
|
44
34
|
|
|
45
35
|
const runtimeFirstExports = ({ exportsDir = 'exports', declarationsDir = 'exports/types' } = {}) => ({
|
|
46
36
|
name: 'runtime-first-exports',
|
|
@@ -124,7 +114,7 @@ export default [
|
|
|
124
114
|
output: {
|
|
125
115
|
format: 'es',
|
|
126
116
|
dir: 'exports',
|
|
127
|
-
paths: (id) => (id
|
|
117
|
+
paths: (id) => (isPromptImport(id) ? './prompts/password.js' : id)
|
|
128
118
|
},
|
|
129
119
|
plugins: [
|
|
130
120
|
typescript({
|
|
@@ -132,15 +122,12 @@ export default [
|
|
|
132
122
|
outDir: 'exports',
|
|
133
123
|
declarationDir: 'exports/types'
|
|
134
124
|
}
|
|
135
|
-
})
|
|
136
|
-
normalizeNodePromptImport()
|
|
125
|
+
})
|
|
137
126
|
],
|
|
138
|
-
external:
|
|
139
|
-
|
|
140
|
-
'./
|
|
141
|
-
'./prompts/password/
|
|
142
|
-
'./prompts/password/node.js'
|
|
143
|
-
]
|
|
127
|
+
external: (id) =>
|
|
128
|
+
isPromptImport(id) ||
|
|
129
|
+
id === './prompts/password/browser.js' ||
|
|
130
|
+
id === './prompts/password/node.js'
|
|
144
131
|
},
|
|
145
132
|
{
|
|
146
133
|
input: ['./src/prompts/password/browser.js'],
|
package/src/identity.ts
CHANGED
|
@@ -5,9 +5,55 @@ import { encrypt, decrypt } from '@leofcoin/identity-utils'
|
|
|
5
5
|
import QrScanner from 'qr-scanner'
|
|
6
6
|
import qrcode from 'qrcode'
|
|
7
7
|
|
|
8
|
+
type StoredAccount = [name: string, externalAddress: string, internalAddress: string]
|
|
9
|
+
type AccountWallet = {
|
|
10
|
+
address: Promise<string>
|
|
11
|
+
sign: (hash: Uint8Array) => Promise<Uint8Array>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const accountDerivationSchemes = [
|
|
15
|
+
{
|
|
16
|
+
name: 'current',
|
|
17
|
+
accountIndex: (index: number) => index + 1,
|
|
18
|
+
addressIndex: 1
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'legacy-v1',
|
|
22
|
+
accountIndex: (index: number) => index,
|
|
23
|
+
addressIndex: 0
|
|
24
|
+
}
|
|
25
|
+
] as const
|
|
26
|
+
|
|
27
|
+
export const resolveAccountWallets = async (
|
|
28
|
+
wallet: MultiWallet,
|
|
29
|
+
accounts: StoredAccount[]
|
|
30
|
+
): Promise<Map<string, AccountWallet>> => {
|
|
31
|
+
for (const scheme of accountDerivationSchemes) {
|
|
32
|
+
const wallets = new Map<string, AccountWallet>()
|
|
33
|
+
let matches = true
|
|
34
|
+
|
|
35
|
+
for (const [index, [, externalAddress, internalAddress]] of accounts.entries()) {
|
|
36
|
+
const account = wallet.account(scheme.accountIndex(index))
|
|
37
|
+
const external = (await account.external(scheme.addressIndex)) as unknown as AccountWallet
|
|
38
|
+
const internal = (await account.internal(scheme.addressIndex)) as unknown as AccountWallet
|
|
39
|
+
|
|
40
|
+
if ((await external.address) !== externalAddress || (await internal.address) !== internalAddress) {
|
|
41
|
+
matches = false
|
|
42
|
+
break
|
|
43
|
+
}
|
|
44
|
+
wallets.set(externalAddress, external)
|
|
45
|
+
wallets.set(internalAddress, internal)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (matches) return wallets
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
throw new Error('stored accounts do not match this identity under a supported derivation scheme')
|
|
52
|
+
}
|
|
53
|
+
|
|
8
54
|
export default class Identity {
|
|
9
55
|
#wallet: MultiWallet
|
|
10
|
-
#accountWallets = new Map<string,
|
|
56
|
+
#accountWallets = new Map<string, AccountWallet>()
|
|
11
57
|
network
|
|
12
58
|
id: string
|
|
13
59
|
selectedAccount: string
|
|
@@ -68,24 +114,8 @@ export default class Identity {
|
|
|
68
114
|
}
|
|
69
115
|
|
|
70
116
|
async #loadAccountWallets() {
|
|
71
|
-
this.#accountWallets.clear()
|
|
72
117
|
const accounts = await this.getAccounts()
|
|
73
|
-
|
|
74
|
-
const account = this.#wallet.account(index + 1)
|
|
75
|
-
const external = (await account.external(1)) as unknown as {
|
|
76
|
-
address: Promise<string>
|
|
77
|
-
sign: (hash: Uint8Array) => Promise<Uint8Array>
|
|
78
|
-
}
|
|
79
|
-
const internal = (await account.internal(1)) as unknown as {
|
|
80
|
-
address: Promise<string>
|
|
81
|
-
sign: (hash: Uint8Array) => Promise<Uint8Array>
|
|
82
|
-
}
|
|
83
|
-
if ((await external.address) !== externalAddress || (await internal.address) !== internalAddress) {
|
|
84
|
-
throw new Error(`stored account ${index + 1} does not match this identity`)
|
|
85
|
-
}
|
|
86
|
-
this.#accountWallets.set(externalAddress, external)
|
|
87
|
-
this.#accountWallets.set(internalAddress, internal)
|
|
88
|
-
}
|
|
118
|
+
this.#accountWallets = await resolveAccountWallets(this.#wallet, accounts)
|
|
89
119
|
if (!this.#accountWallets.has(this.selectedAccount)) {
|
|
90
120
|
throw new Error(`selected account ${this.selectedAccount} is not part of this identity`)
|
|
91
121
|
}
|
package/test/peernet.test.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import test from 'node:test'
|
|
2
2
|
import assert from 'node:assert/strict'
|
|
3
|
+
import { readFile } from 'node:fs/promises'
|
|
3
4
|
|
|
4
5
|
import Peernet from '../exports/peernet.js'
|
|
5
|
-
import Identity from '../exports/identity.js'
|
|
6
|
+
import Identity, { resolveAccountWallets } from '../exports/identity.js'
|
|
6
7
|
import MultiWallet from '@leofcoin/multi-wallet'
|
|
7
8
|
import { fromBase58, toBase58 } from '@vandeurenglenn/typed-array-utils'
|
|
8
9
|
|
|
@@ -18,6 +19,12 @@ const options = {
|
|
|
18
19
|
const password = 'password'
|
|
19
20
|
const peernet = await new Peernet(options, password)
|
|
20
21
|
|
|
22
|
+
test('node bundle uses a portable password prompt import', async () => {
|
|
23
|
+
const identityBundle = await readFile(new URL('../exports/identity.js', import.meta.url), 'utf8')
|
|
24
|
+
assert.match(identityBundle, /import\(['"]\.\/prompts\/password\.js['"]\)/)
|
|
25
|
+
assert.doesNotMatch(identityBundle, /(?:\/home\/|\/Users\/|[A-Za-z]:\\)/)
|
|
26
|
+
})
|
|
27
|
+
|
|
21
28
|
test('initializes with provided options', () => {
|
|
22
29
|
assert.equal(peernet.network, options.network)
|
|
23
30
|
assert.equal(peernet.version, options.version)
|
|
@@ -244,6 +251,23 @@ test('identity signatures authenticate the selected account', async () => {
|
|
|
244
251
|
assert.equal(await verifier.verify(fromBase58(signature), payload), true)
|
|
245
252
|
})
|
|
246
253
|
|
|
254
|
+
test('legacy account(0)/address(0) identities keep their original signer', async () => {
|
|
255
|
+
const wallet = new MultiWallet(peernet.network)
|
|
256
|
+
await wallet.generate()
|
|
257
|
+
const legacyAccount = wallet.account(0)
|
|
258
|
+
const external = await legacyAccount.external(0)
|
|
259
|
+
const internal = await legacyAccount.internal(0)
|
|
260
|
+
const externalAddress = await external.address
|
|
261
|
+
const wallets = await resolveAccountWallets(wallet, [
|
|
262
|
+
['legacy account', externalAddress, await internal.address]
|
|
263
|
+
])
|
|
264
|
+
const payload = new Uint8Array(32).fill(9)
|
|
265
|
+
const signature = toBase58(await wallets.get(externalAddress).sign(payload))
|
|
266
|
+
const verifier = new MultiWallet(peernet.network)
|
|
267
|
+
await verifier.fromAddress(externalAddress, null, peernet.network)
|
|
268
|
+
assert.equal(await verifier.verify(fromBase58(signature), payload), true)
|
|
269
|
+
})
|
|
270
|
+
|
|
247
271
|
test('error handling methods exist', () => {
|
|
248
272
|
assert.equal(typeof peernet.handleDHT, 'function')
|
|
249
273
|
assert.equal(typeof peernet.handleData, 'function')
|
package/test-output.log
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
✔ initializes with provided options (0.407125ms)
|
|
2
|
-
✔ exposes identity instance (0.051667ms)
|
|
3
|
-
✔ has a DHT instance (0.04425ms)
|
|
4
|
-
✔ returns peers and connections safely (0.267542ms)
|
|
5
|
-
✔ provides callable helpers (0.048958ms)
|
|
6
|
-
✔ pubsub subscribe registers callback (10.395584ms)
|
|
7
|
-
✔ addProto registers protocol (0.160417ms)
|
|
8
|
-
✔ addProto does not overwrite existing protocol (0.057709ms)
|
|
9
|
-
✔ addCodec is callable (0.063084ms)
|
|
10
|
-
✔ selectAccount delegates to identity (0.068584ms)
|
|
11
|
-
✔ identity has loaded account data (0.241875ms)
|
|
12
|
-
✔ peerId matches identity id (0.031375ms)
|
|
13
|
-
✔ data store operations (0.030125ms)
|
|
14
|
-
✔ get attempts to retrieve from store (0.035667ms)
|
|
15
|
-
✔ message object provides get/put/has (0.053917ms)
|
|
16
|
-
✔ data object provides get/put/has (0.045833ms)
|
|
17
|
-
✔ block object provides get/put/has (0.067375ms)
|
|
18
|
-
✔ transaction object provides get/put/has (0.042333ms)
|
|
19
|
-
✔ folder object provides get/put/has (0.034167ms)
|
|
20
|
-
✔ Buffer property is available (0.024417ms)
|
|
21
|
-
✔ handleData is callable (0.017709ms)
|
|
22
|
-
✔ handleDHT is callable (0.016167ms)
|
|
23
|
-
✔ handleRequest is callable (0.016417ms)
|
|
24
|
-
✔ walk is callable (0.015459ms)
|
|
25
|
-
✔ providersFor is callable (0.015583ms)
|
|
26
|
-
✔ addRequestHandler is callable (0.015375ms)
|
|
27
|
-
✔ sendMessage is callable (0.01625ms)
|
|
28
|
-
✔ start method exists (0.02675ms)
|
|
29
|
-
✔ default stores are initialized (0.0275ms)
|
|
30
|
-
✔ identity has all expected methods (0.020084ms)
|
|
31
|
-
✔ identity wallet is loaded (0.019333ms)
|
|
32
|
-
✔ selected account is set (0.016208ms)
|
|
33
|
-
✔ error handling methods exist (0.017083ms)
|
|
34
|
-
DEBUG_HANDLE_DATA: entering in-memory branch { hash: 'BA43QACTNQLBH6SW7NO7ZQ63I3USRUBTD5DOWLEUFJGMY6JN2BSUAES54X' }
|
|
35
|
-
DEBUG_HANDLE_DATA: got from _inMemoryBroadcasts {
|
|
36
|
-
type: 'object',
|
|
37
|
-
isUint8Array: true,
|
|
38
|
-
length: 34,
|
|
39
|
-
slice: [
|
|
40
|
-
230, 224, 1, 5, 47,
|
|
41
|
-
116, 101, 115, 116, 21,
|
|
42
|
-
104, 101, 108, 108, 111,
|
|
43
|
-
32
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
✔ in-memory broadcast and handleData returns correct data (4.52275ms)
|
|
47
|
-
DEBUG_HANDLE_DATA: entering in-memory branch { hash: 'BA43QACYLVOY2HRRGV4NOUDQ3GWPQ7YZVBBM5DOKGZIY4UOYMS3K3JSCVV' }
|
|
48
|
-
DEBUG_HANDLE_DATA: got from _inMemoryBroadcasts {
|
|
49
|
-
type: 'object',
|
|
50
|
-
isUint8Array: true,
|
|
51
|
-
length: 1048599,
|
|
52
|
-
slice: [
|
|
53
|
-
230, 224, 1, 13, 47, 108,
|
|
54
|
-
97, 114, 103, 101, 45, 98,
|
|
55
|
-
105, 110, 97, 114
|
|
56
|
-
]
|
|
57
|
-
}
|
|
58
|
-
DEBUG_TEST receivedBuffer {
|
|
59
|
-
type: 'object',
|
|
60
|
-
isUint8Array: true,
|
|
61
|
-
length: 1048576,
|
|
62
|
-
slice: [
|
|
63
|
-
0, 1, 2, 3, 4, 5,
|
|
64
|
-
6, 7, 8, 9, 10, 11,
|
|
65
|
-
12, 13, 14, 15
|
|
66
|
-
]
|
|
67
|
-
}
|
|
68
|
-
DEBUG_TEST originalBuffer {
|
|
69
|
-
length: 1048576,
|
|
70
|
-
slice: [
|
|
71
|
-
0, 1, 2, 3, 4, 5,
|
|
72
|
-
6, 7, 8, 9, 10, 11,
|
|
73
|
-
12, 13, 14, 15
|
|
74
|
-
]
|
|
75
|
-
}
|
|
76
|
-
✔ in-memory broadcast and handleData supports large binary data (163.195292ms)
|
|
77
|
-
ℹ tests 35
|
|
78
|
-
ℹ suites 0
|
|
79
|
-
ℹ pass 35
|
|
80
|
-
ℹ fail 0
|
|
81
|
-
ℹ cancelled 0
|
|
82
|
-
ℹ skipped 0
|
|
83
|
-
ℹ todo 0
|
|
84
|
-
ℹ duration_ms 366.132458
|