214 lines
10 KiB
JavaScript
214 lines
10 KiB
JavaScript
|
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
|
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||
|
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
|
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
|
});
|
||
|
|
};
|
||
|
|
import { Level } from 'level';
|
||
|
|
import { LevelStore, MemoryStore } from '@web5/common';
|
||
|
|
import { DataStoreLevel, EventEmitterStream, EventLogLevel, MessageStoreLevel } from '@tbd54566975/dwn-sdk-js';
|
||
|
|
import { DidDht, DidJwk, DidResolverCacheLevel } from '@web5/dids';
|
||
|
|
import { AgentDidApi } from './did-api.js';
|
||
|
|
import { AgentDwnApi } from './dwn-api.js';
|
||
|
|
import { AgentSyncApi } from './sync-api.js';
|
||
|
|
import { Web5RpcClient } from './rpc-client.js';
|
||
|
|
import { AgentCryptoApi } from './crypto-api.js';
|
||
|
|
import { AgentIdentityApi } from './identity-api.js';
|
||
|
|
import { HdIdentityVault } from './hd-identity-vault.js';
|
||
|
|
import { LocalKeyManager } from './local-key-manager.js';
|
||
|
|
import { SyncEngineLevel } from './sync-engine-level.js';
|
||
|
|
import { DwnDidStore, InMemoryDidStore } from './store-did.js';
|
||
|
|
import { DwnKeyStore, InMemoryKeyStore } from './store-key.js';
|
||
|
|
import { DwnIdentityStore, InMemoryIdentityStore } from './store-identity.js';
|
||
|
|
import { DidResolverCacheMemory } from './prototyping/dids/resolver-cache-memory.js';
|
||
|
|
export class PlatformAgentTestHarness {
|
||
|
|
constructor(params) {
|
||
|
|
this.agent = params.agent;
|
||
|
|
this.agentStores = params.agentStores;
|
||
|
|
this.didResolverCache = params.didResolverCache;
|
||
|
|
this.dwn = params.dwn;
|
||
|
|
this.dwnDataStore = params.dwnDataStore;
|
||
|
|
this.dwnEventLog = params.dwnEventLog;
|
||
|
|
this.dwnMessageStore = params.dwnMessageStore;
|
||
|
|
this.syncStore = params.syncStore;
|
||
|
|
this.vaultStore = params.vaultStore;
|
||
|
|
}
|
||
|
|
clearStorage() {
|
||
|
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
|
// @ts-expect-error since normally this property shouldn't be set to undefined.
|
||
|
|
this.agent.agentDid = undefined;
|
||
|
|
yield this.didResolverCache.clear();
|
||
|
|
yield this.dwnDataStore.clear();
|
||
|
|
yield this.dwnEventLog.clear();
|
||
|
|
yield this.dwnMessageStore.clear();
|
||
|
|
yield this.syncStore.clear();
|
||
|
|
yield this.vaultStore.clear();
|
||
|
|
// Reset the indexes and caches for the Agent's DWN data stores.
|
||
|
|
// if (this.agentStores === 'dwn') {
|
||
|
|
// const { didApi, identityApi } = PlatformAgentTestHarness.useDiskStores({ testDataLocation: '__TESTDATA__', agent: this.agent });
|
||
|
|
// this.agent.crypto = cryptoApi;
|
||
|
|
// this.agent.did = didApi;
|
||
|
|
// this.agent.identity = identityApi;
|
||
|
|
// }
|
||
|
|
// Easiest way to start with fresh in-memory stores is to re-instantiate Agent components.
|
||
|
|
if (this.agentStores === 'memory') {
|
||
|
|
const { didApi, identityApi, keyManager } = PlatformAgentTestHarness.useMemoryStores({ agent: this.agent });
|
||
|
|
this.agent.did = didApi;
|
||
|
|
this.agent.identity = identityApi;
|
||
|
|
this.agent.keyManager = keyManager;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
closeStorage() {
|
||
|
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
|
yield this.didResolverCache.close();
|
||
|
|
yield this.dwnDataStore.close();
|
||
|
|
yield this.dwnEventLog.close();
|
||
|
|
yield this.dwnMessageStore.close();
|
||
|
|
yield this.syncStore.close();
|
||
|
|
yield this.vaultStore.close();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
createAgentDid() {
|
||
|
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
|
// Create a DID for the Agent.
|
||
|
|
this.agent.agentDid = yield DidJwk.create({
|
||
|
|
options: { algorithm: 'Ed25519' }
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
createIdentity({ name, testDwnUrls }) {
|
||
|
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
|
const bearerIdentity = yield this.agent.identity.create({
|
||
|
|
didMethod: 'dht',
|
||
|
|
didOptions: {
|
||
|
|
services: [
|
||
|
|
{
|
||
|
|
id: 'dwn',
|
||
|
|
type: 'DecentralizedWebNode',
|
||
|
|
serviceEndpoint: testDwnUrls,
|
||
|
|
enc: '#enc',
|
||
|
|
sig: '#sig',
|
||
|
|
}
|
||
|
|
],
|
||
|
|
verificationMethods: [
|
||
|
|
{
|
||
|
|
algorithm: 'Ed25519',
|
||
|
|
id: 'sig',
|
||
|
|
purposes: ['assertionMethod', 'authentication']
|
||
|
|
},
|
||
|
|
{
|
||
|
|
algorithm: 'secp256k1',
|
||
|
|
id: 'enc',
|
||
|
|
purposes: ['keyAgreement']
|
||
|
|
}
|
||
|
|
]
|
||
|
|
},
|
||
|
|
metadata: { name }
|
||
|
|
});
|
||
|
|
return bearerIdentity;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
preloadResolverCache({ didUri, resolutionResult }) {
|
||
|
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
|
yield this.didResolverCache.set(didUri, resolutionResult);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
static setup({ agentClass, agentStores, testDataLocation }) {
|
||
|
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
|
agentStores !== null && agentStores !== void 0 ? agentStores : (agentStores = 'memory');
|
||
|
|
testDataLocation !== null && testDataLocation !== void 0 ? testDataLocation : (testDataLocation = '__TESTDATA__');
|
||
|
|
const testDataPath = (path) => `${testDataLocation}/${path}`;
|
||
|
|
// Instantiate Agent's Crypto API.
|
||
|
|
const cryptoApi = new AgentCryptoApi();
|
||
|
|
// Instantiate Agent's RPC Client.
|
||
|
|
const rpcClient = new Web5RpcClient();
|
||
|
|
const { agentVault, didApi, identityApi, keyManager, didResolverCache, vaultStore } = (agentStores === 'memory')
|
||
|
|
? PlatformAgentTestHarness.useMemoryStores()
|
||
|
|
: PlatformAgentTestHarness.useDiskStores({ testDataLocation });
|
||
|
|
// Instantiate custom stores to use with DWN instance.
|
||
|
|
// Note: There is no in-memory store for DWN, so we always use LevelDB-based disk stores.
|
||
|
|
const dwnDataStore = new DataStoreLevel({ blockstoreLocation: testDataPath('DWN_DATASTORE') });
|
||
|
|
const dwnEventLog = new EventLogLevel({ location: testDataPath('DWN_EVENTLOG') });
|
||
|
|
const dwnEventStream = new EventEmitterStream();
|
||
|
|
const dwnMessageStore = new MessageStoreLevel({
|
||
|
|
blockstoreLocation: testDataPath('DWN_MESSAGESTORE'),
|
||
|
|
indexLocation: testDataPath('DWN_MESSAGEINDEX')
|
||
|
|
});
|
||
|
|
// Instantiate DWN instance using the custom stores.
|
||
|
|
const dwn = yield AgentDwnApi.createDwn({
|
||
|
|
dataPath: testDataLocation,
|
||
|
|
dataStore: dwnDataStore,
|
||
|
|
didResolver: didApi,
|
||
|
|
eventLog: dwnEventLog,
|
||
|
|
eventStream: dwnEventStream,
|
||
|
|
messageStore: dwnMessageStore,
|
||
|
|
});
|
||
|
|
// Instantiate Agent's DWN API using the custom DWN instance.
|
||
|
|
const dwnApi = new AgentDwnApi({ dwn });
|
||
|
|
// Instantiate Agent's Sync API using a custom LevelDB-backed store.
|
||
|
|
const syncStore = new Level(testDataPath('SYNC_STORE'));
|
||
|
|
const syncEngine = new SyncEngineLevel({ db: syncStore });
|
||
|
|
const syncApi = new AgentSyncApi({ syncEngine });
|
||
|
|
// Create Web5PlatformAgent instance
|
||
|
|
const agent = new agentClass({
|
||
|
|
agentVault,
|
||
|
|
cryptoApi,
|
||
|
|
didApi,
|
||
|
|
dwnApi,
|
||
|
|
identityApi,
|
||
|
|
keyManager,
|
||
|
|
rpcClient,
|
||
|
|
syncApi,
|
||
|
|
});
|
||
|
|
return new PlatformAgentTestHarness({
|
||
|
|
agent,
|
||
|
|
agentStores,
|
||
|
|
didResolverCache,
|
||
|
|
dwn,
|
||
|
|
dwnDataStore,
|
||
|
|
dwnEventLog,
|
||
|
|
dwnMessageStore,
|
||
|
|
syncStore,
|
||
|
|
vaultStore
|
||
|
|
});
|
||
|
|
});
|
||
|
|
}
|
||
|
|
static useDiskStores({ agent, testDataLocation }) {
|
||
|
|
const testDataPath = (path) => `${testDataLocation}/${path}`;
|
||
|
|
const vaultStore = new LevelStore({ location: testDataPath('VAULT_STORE') });
|
||
|
|
const agentVault = new HdIdentityVault({ keyDerivationWorkFactor: 1, store: vaultStore });
|
||
|
|
// Setup DID Resolver Cache
|
||
|
|
const didResolverCache = new DidResolverCacheLevel({
|
||
|
|
location: testDataPath('DID_RESOLVERCACHE')
|
||
|
|
});
|
||
|
|
const didApi = new AgentDidApi({
|
||
|
|
agent: agent,
|
||
|
|
didMethods: [DidDht, DidJwk],
|
||
|
|
resolverCache: didResolverCache,
|
||
|
|
store: new DwnDidStore()
|
||
|
|
});
|
||
|
|
const identityApi = new AgentIdentityApi({ agent, store: new DwnIdentityStore() });
|
||
|
|
const keyManager = new LocalKeyManager({ agent, keyStore: new DwnKeyStore() });
|
||
|
|
return { agentVault, didApi, didResolverCache, identityApi, keyManager, vaultStore };
|
||
|
|
}
|
||
|
|
static useMemoryStores({ agent } = {}) {
|
||
|
|
const vaultStore = new MemoryStore();
|
||
|
|
const agentVault = new HdIdentityVault({ keyDerivationWorkFactor: 1, store: vaultStore });
|
||
|
|
// Setup DID Resolver Cache
|
||
|
|
const didResolverCache = new DidResolverCacheMemory();
|
||
|
|
const didApi = new AgentDidApi({
|
||
|
|
agent: agent,
|
||
|
|
didMethods: [DidDht, DidJwk],
|
||
|
|
resolverCache: didResolverCache,
|
||
|
|
store: new InMemoryDidStore()
|
||
|
|
});
|
||
|
|
const keyManager = new LocalKeyManager({ agent, keyStore: new InMemoryKeyStore() });
|
||
|
|
const identityApi = new AgentIdentityApi({ agent, store: new InMemoryIdentityStore() });
|
||
|
|
return { agentVault, didApi, didResolverCache, identityApi, keyManager, vaultStore };
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=test-harness.js.map
|