dwnpm
Version:
Decentralized Registry Package Manager (DRPM) helps developers publish, install, find and manage Decentralized Packages (DPKs) published to Decentralized Web Nodes (DWNs). DRPM does this by looking up a Decentralized Identifier (DID) to find its DID docum
141 lines • 5.26 kB
JavaScript
import { Web5 } from '@web5/api';
import { Web5UserAgent } from '@web5/user-agent';
import fsx from 'fs-extra';
import { DRPM_HOME } from '../../config.js';
import { Logger } from '../../utils/logger.js';
import { cleanEndpoint, createPassword, scuid } from '../../utils/misc.js';
import { Profile } from '../profile.js';
// import cuid from '@bugsnag/cuid';
export class DhtAgent {
userAgent;
recoveryPhrase;
connectedDid;
constructor({ userAgent }) {
this.userAgent = userAgent;
}
static async create({ dataPath }) {
const userAgent = await Web5UserAgent.create({ dataPath });
return new DhtAgent({ userAgent });
}
async launch({ password }) {
try {
if (await this.userAgent.firstLaunch()) {
this.recoveryPhrase = await this.userAgent.initialize({ password });
}
await this.userAgent.start({ password });
}
catch (error) {
Logger.error(`Failed to setup agent: ${error.message}`);
process.exit(1);
}
}
json() {
return {
userAgent: this.userAgent,
recoveryPhrase: this.recoveryPhrase,
connectedDid: this.connectedDid
};
}
async identity({ dwnEndpoints }) {
try {
const identity = await this.userAgent.identity.create({
didMethod: 'dht',
metadata: { name: 'DRPM' },
didOptions: {
services: [
{
id: 'dwn',
type: 'DecentralizedWebNode',
serviceEndpoint: dwnEndpoints,
enc: '#enc',
sig: '#sig',
}
],
verificationMethods: [
{
algorithm: 'Ed25519',
id: 'sig',
purposes: ['assertionMethod', 'authentication']
},
{
algorithm: 'secp256k1',
id: 'enc',
purposes: ['keyAgreement']
}
]
}
});
this.connectedDid = identity.metadata.connectedDid ?? identity.did.uri;
return this.connectedDid;
}
catch (error) {
Logger.error(`Failed to create agent identity: ${error.message}`);
process.exit(1);
}
}
}
export class DhtProfile {
// Used by cli drpm profile create to create new DHT profile
static async create(params) {
try {
const dwnEndpoints = params.dwnEndpoints.split(',');
const endpoints = dwnEndpoints
.map((dwnEndpoint) => cleanEndpoint(dwnEndpoint))
.filter(endpoint => !fsx.existsSync(`${DRPM_HOME}/DHT/${endpoint}`));
const endpointPath = endpoints.length
? `${endpoints[0]}/0/DATA/AGENT`
: `${cleanEndpoint(dwnEndpoints[0])}/${scuid()}/DATA/AGENT`;
const dataPath = `${DRPM_HOME}/DHT/${endpointPath}`;
const web5DataPath = params.web5DataPath ?? dataPath;
const password = params.password ?? createPassword();
const dhtAgent = await DhtAgent.create({ dataPath: web5DataPath });
await dhtAgent.launch({ password });
const { recoveryPhrase } = dhtAgent.json() ?? Profile.json.dht.recoveryPhrase;
const connectedDid = await dhtAgent.identity({ dwnEndpoints, recoveryPhrase });
const agent = dhtAgent.userAgent;
const { did } = await Web5.connect({
agent,
password,
connectedDid,
sync: 'off',
didCreateOptions: { dwnEndpoints },
});
Logger.info('Syncing dwn, please wait ...');
await agent.sync.sync();
Logger.info('Syncing complete!');
return {
name: 'dht',
dht: {
did,
password,
web5DataPath,
dwnEndpoints,
recoveryPhrase,
}
};
}
catch (error) {
Logger.error(`Failed to create DHT profile: ${error.message}`);
throw error;
}
}
// Used by cli in various contexts to use the existing profile to connect to Web5
static async connect({ did, password, dwnEndpoints, web5DataPath }) {
try {
const dhtAgent = await DhtAgent.create({ dataPath: web5DataPath });
await dhtAgent.launch({ password });
return await Web5.connect({
password,
connectedDid: did,
sync: '30s',
didCreateOptions: { dwnEndpoints },
agent: dhtAgent.userAgent,
});
}
catch (error) {
Logger.error(`Failed to connect to DHT profile: ${error.message}`);
throw error;
}
}
}
//# sourceMappingURL=dht.js.map