diff --git a/packages/agent-explore/src/plugins/chats/ShareForm.tsx b/packages/agent-explore/src/plugins/chats/ShareForm.tsx index 6e82de7..f5af88c 100644 --- a/packages/agent-explore/src/plugins/chats/ShareForm.tsx +++ b/packages/agent-explore/src/plugins/chats/ShareForm.tsx @@ -8,6 +8,7 @@ import Editor from '@monaco-editor/react'; import { ResponsiveContainer } from '../../components/ResponsiveContainer' import { v4 } from 'uuid' import { useNavigate } from 'react-router' +import { computeEntryHash } from '@veramo/utils' export const ShareForm: React.FC = () => { @@ -15,6 +16,7 @@ export const ShareForm: React.FC = () => { console.log('here') const [message, setMessage] = useState(window.localStorage.getItem('bs-post') || '') + const attachment = window.localStorage.getItem('attachment') const { notification } = App.useApp() const navigate = useNavigate() @@ -26,19 +28,31 @@ console.log('here') window.localStorage.setItem('bs-post', message) }, [message]) + console.log("attachment: ", attachment) const handleSend = async (did: string, issuerAgent: TAgent) => { setIsSending(true) try { - const threadId = v4() + const messageId = v4() + + const parsedAttachment = JSON.parse(attachment!)! + const canonicalCredential = parsedAttachment?.proof?.type === 'JwtProof2020' && + typeof parsedAttachment?.proof?.jwt === 'string' + ? parsedAttachment?.proof?.jwt + : parsedAttachment + const threadId = computeEntryHash(canonicalCredential) const shareMessage = { type: 'https://didcomm.org/basicmessage/2.0/message', from: did, created_time: new Date().getTime(), to: recepient, - id: threadId, + id: messageId, thid: threadId, - body: { content: message } + body: { content: message }, + attachments: [{ + media_type: 'credential+ld+json', + data: { json: JSON.parse(attachment!) } + }] } const packedMessage = await issuerAgent.packDIDCommMessage({ message: shareMessage, diff --git a/packages/agent-explore/src/plugins/chats/menu.tsx b/packages/agent-explore/src/plugins/chats/menu.tsx index 771b4bd..338b97f 100644 --- a/packages/agent-explore/src/plugins/chats/menu.tsx +++ b/packages/agent-explore/src/plugins/chats/menu.tsx @@ -17,6 +17,7 @@ export const getCredentialContextMenuItems = (credential: UniqueVerifiableCreden } window.localStorage.setItem('bs-post', embed) + window.localStorage.setItem('attachment', JSON.stringify(credential.verifiableCredential)) navigate(`/chats/share`) } diff --git a/packages/agent-explore/src/plugins/chats/saveMessageHandler.ts b/packages/agent-explore/src/plugins/chats/saveMessageHandler.ts index a426381..016ae5f 100644 --- a/packages/agent-explore/src/plugins/chats/saveMessageHandler.ts +++ b/packages/agent-explore/src/plugins/chats/saveMessageHandler.ts @@ -34,6 +34,15 @@ export class SaveMessageHandler extends AbstractMessageHandler { if (!localMessage) { console.log('Saving message', message) await context.agent.dataStoreSaveMessage({ message }) + if (message.attachments && message.attachments.length > 0) { + console.log("attachments found") + for (const attachment of message.attachments) { + if (attachment.media_type === 'credential+ld+json') { + const credential = await context.agent.dataStoreSaveVerifiableCredential({ verifiableCredential: attachment.data.json}) + console.log("saved attached credential: ", credential) + } + } + } } } diff --git a/packages/plugin/src/components/VerifiableCredentialComponent.tsx b/packages/plugin/src/components/VerifiableCredentialComponent.tsx index 4a328b1..2c69208 100644 --- a/packages/plugin/src/components/VerifiableCredentialComponent.tsx +++ b/packages/plugin/src/components/VerifiableCredentialComponent.tsx @@ -43,6 +43,24 @@ export const VerifiableCredentialComponent = ( console.log({actionComponents}) + + const headerComponents = React.useMemo(() => { + let headerComponents: React.FC[] = [] + plugins.forEach((plugin) => { + if (plugin.config?.enabled && plugin.getCredentialHeaderComponent) { + const components = plugin.getCredentialHeaderComponent(credential) + if (components) { + headerComponents.push(components) + } + } + }) + return headerComponents + }, [plugins]) + + console.log({headerComponents}) + + console.log("verifiableCredentail: ", credential) + React.useEffect(() => { if (verify && !verifyResult && !isVerifying) { setIsVerifying(true) @@ -117,25 +135,29 @@ export const VerifiableCredentialComponent = ( >
-
- {!isLoadingProfile && } - {isLoadingProfile && } -
- - - {isLoadingProfile ? shortId(did): profile?.name} - - - - {formatRelative( - new Date(credential.verifiableCredential.issuanceDate), - new Date() - )} - {isVerifying && } +
+ {!isLoadingProfile && } + {isLoadingProfile && } +
+ + + {isLoadingProfile ? shortId(did): profile?.name} + + + + {formatRelative( + new Date(credential.verifiableCredential.issuanceDate), + new Date() + )} + {isVerifying && } {verifyResult?.error && {verifyResult.error.message}} + {headerComponents.length > 0 && <> + {headerComponents.map((Component, index) => ( + React.createElement(Component, { credential }) + ))} + }
- {isLoadingProfile && }
diff --git a/packages/plugin/src/types.ts b/packages/plugin/src/types.ts index ef699f2..11de64d 100644 --- a/packages/plugin/src/types.ts +++ b/packages/plugin/src/types.ts @@ -78,6 +78,9 @@ export type IAgentExplorerPlugin = { /** Returns a react component for a given verifiable credential */ getCredentialComponent?: (credential: UniqueVerifiableCredential) => React.FC | undefined; + /** Returns a react header component for a given verifiable credential */ + getCredentialHeaderComponent?: (credential: UniqueVerifiableCredential) => React.FC | undefined; + /** Returns a react component that will be displayed in the identifier hover component */ getIdentifierHoverComponent?: () => React.FC;