Skip to content

Commit

Permalink
shuffle around methods
Browse files Browse the repository at this point in the history
  • Loading branch information
LiranCohen committed Aug 20, 2024
1 parent 424a582 commit f27e4cd
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 36 deletions.
12 changes: 12 additions & 0 deletions packages/agent/src/dwn-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
DataStoreLevel,
Dwn,
DwnConfig,
DwnInterfaceName,
DwnMethodName,
EventLogLevel,
GenericMessage,
Expand All @@ -23,8 +24,11 @@ import type {
DwnMessageInstance,
DwnMessageParams,
DwnMessageReply,
DwnMessagesPermissionScope,
DwnMessageWithData,
DwnPermissionScope,
DwnRecordsInterfaces,
DwnRecordsPermissionScope,
DwnResponse,
DwnSigner,
MessageHandler,
Expand Down Expand Up @@ -70,6 +74,14 @@ export function isRecordsType(messageType: DwnInterface): messageType is DwnReco
messageType === DwnInterface.RecordsWrite;
}

export function isRecordPermissionScope(scope: DwnPermissionScope): scope is DwnRecordsPermissionScope {
return scope.interface === DwnInterfaceName.Records;
}

export function isMessagesPermissionScope(scope: DwnPermissionScope): scope is DwnMessagesPermissionScope {
return scope.interface === DwnInterfaceName.Messages;
}

export class AgentDwnApi {
/**
* Holds the instance of a `Web5PlatformAgent` that represents the current execution context for
Expand Down
Empty file.
31 changes: 0 additions & 31 deletions packages/api/src/dwn-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,35 +800,4 @@ export class DwnApi {
},
};
}

/**
* A static method to process connected grants for a delegate DID.
*
* This will store the grants as the DWN owner to be used later when impersonating the connected DID.
*/
static async processConnectedGrants({ grants, agent, delegateDid }: {
grants: DwnDataEncodedRecordsWriteMessage[],
agent: Web5Agent,
delegateDid: string,
}): Promise<string[]> {
const connectedProtocols = new Set<string>();
for (const grantMessage of grants) {
// use the delegateDid as the connectedDid of the grant as they do not yet support impersonation/delegation
const grant = await PermissionGrant.parse({ connectedDid: delegateDid, agent, message: grantMessage });
// store the grant as the owner of the DWN, this will allow the delegateDid to use the grant when impersonating the connectedDid
const { status } = await grant.store(true);
if (status.code !== 202) {
throw new Error(`AgentDwnApi: Failed to process connected grant: ${status.detail}`);
}

const protocol = (grant.scope as DwnMessagesPermissionScope | DwnRecordsPermissionScope).protocol;
if (protocol) {
connectedProtocols.add(protocol);
}
}

// currently we return a de-duped set of protocols represented by these grants, this is used to register protocols for sync
// we expect that any connected protocols will include MessagesQuery and MessagesRead grants that will allow it to sync
return [...connectedProtocols];
}
}
56 changes: 51 additions & 5 deletions packages/api/src/web5.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@

import type {
BearerIdentity,
DwnDataEncodedRecordsWriteMessage,
DwnMessagesPermissionScope,
DwnRecordsPermissionScope,
HdIdentityVault,
WalletConnectOptions,
Web5Agent,
} from '@web5/agent';

import { Web5UserAgent } from '@web5/user-agent';
import { DwnRegistrar, WalletConnect } from '@web5/agent';
import { DwnRegistrar, isMessagesPermissionScope, isRecordPermissionScope, WalletConnect } from '@web5/agent';

import { DidApi } from './did-api.js';
import { DwnApi } from './dwn-api.js';
import { VcApi } from './vc-api.js';
import { PermissionGrant } from './permission-grant.js';

/** Override defaults configured during the technical preview phase. */
export type TechPreviewOptions = {
Expand Down Expand Up @@ -258,6 +262,12 @@ export class Web5 {
// TODO: In the future, implement a way to re-connect an already connected identity and apply additional grants/protocols
identity = connectedIdentity;
} else if (walletConnectOptions) {
if (sync === 'off') {
// Currently we require sync to be enabled when using WalletConnect
// This is to ensure a connected app is not in a disjointed state from any other clients/app using the connectedDid
throw new Error('Sync must not be disabled when using WalletConnect');
}

// No connected identity found and connectOptions are provided, attempt to import a delegated DID from an external wallet
try {
// TEMPORARY: Placeholder for WalletConnect integration
Expand All @@ -278,7 +288,8 @@ export class Web5 {

// Attempts to process the connected grants to be used by the delegateDID
// If the process fails, we want to clean up the identity
connectedProtocols = await DwnApi.processConnectedGrants({ agent, delegateDid: delegateDid.uri, grants: delegateGrants });
// the connected grants will return a de-duped array of protocol URIs that are used to register sync for those protocols
connectedProtocols = await this.processConnectedGrants({ agent, delegateDid: delegateDid.uri, grants: delegateGrants });
} catch (error:any) {
// clean up the DID and Identity if import fails and throw
// TODO: Implement the ability to purge all of our messages as a tenant
Expand Down Expand Up @@ -371,9 +382,13 @@ export class Web5 {
// Enable sync, unless explicitly disabled.
if (sync !== 'off') {
// First, register the user identity for sync.
await userAgent.sync.registerIdentity({ did : connectedDid, options : {
protocols: connectedProtocols
} });
// The connected protocols are used to register sync for only a subset of protocols from the connectedDid's DWN
await userAgent.sync.registerIdentity({
did : connectedDid,
options : {
protocols: connectedProtocols
}
});

// Enable sync using the specified interval or default.
sync ??= '2m';
Expand Down Expand Up @@ -415,4 +430,35 @@ export class Web5 {
console.error(`Failed to delete Identity ${identity.metadata.name}: ${error.message}`);
}
}

/**
* A static method to process connected grants for a delegate DID.
*
* This will store the grants as the DWN owner to be used later when impersonating the connected DID.
*/
static async processConnectedGrants({ grants, agent, delegateDid }: {
grants: DwnDataEncodedRecordsWriteMessage[],
agent: Web5Agent,
delegateDid: string,
}): Promise<string[]> {
const connectedProtocols = new Set<string>();
for (const grantMessage of grants) {
// use the delegateDid as the connectedDid of the grant as they do not yet support impersonation/delegation
const grant = await PermissionGrant.parse({ connectedDid: delegateDid, agent, message: grantMessage });
// store the grant as the owner of the DWN, this will allow the delegateDid to use the grant when impersonating the connectedDid
const { status } = await grant.store(true);
if (status.code !== 202) {
throw new Error(`AgentDwnApi: Failed to process connected grant: ${status.detail}`);
}

const protocol = (grant.scope as DwnMessagesPermissionScope | DwnRecordsPermissionScope).protocol;
if (protocol) {
connectedProtocols.add(protocol);
}
}

// currently we return a de-duped set of protocols represented by these grants, this is used to register protocols for sync
// we expect that any connected protocols will include MessagesQuery and MessagesRead grants that will allow it to sync
return [...connectedProtocols];
}
}

0 comments on commit f27e4cd

Please sign in to comment.