# NFT-Twitter # Taskslist - NFT-Webapp Single-Page UI (Simonas) - List Tweets (all Tweets, no filter) - List NFTs - Select active NFT - Tweet with (active) NFT - New: "Send private Message" to NFT - New: "Receive private Message" on Agent - Agent/API: - Expose VCs: /dataStoreGetVerifiableCredential :heavy_check_mark: - Expose Msg Endpoint to receive credentials :heavy_check_mark: - DID:NFT resolver must be working Server-Side :heavy_check_mark: - "Find/Read all NFTs" for Ethereum Address (via opensea) :heavy_check_mark: - MessageHandler-Chain to verif and unwrap Metamask-signed Messages (Mircea, Oliver, Martin) :heavy_check_mark: - No JSON-LD dependency. Special MM-JWT credential & Message Handler. @Martin @ @Oliver - Expose Opensea API calls in own backend with Opensea API Key :exclamation: - Metamask / Veramo Integration - KMS-Veramo Integration :heavy_check_mark: - MemoryDIDStore :heavy_check_mark: - MemoryKeyStore :heavy_check_mark: - Web3KeyManagementSystem (Sign) :heavy_check_mark: - Metamask cannot sign our Secp256k1 JWT representation - No JSON-LD dependency. Special MM-JWT credential & Message Handler. @Mircea - MetaMask Credential Signing with EIP-712 support. (Simonas): (may, for FRI) :heavy_check_mark: - Architecture Diagram (Oliver) :heavy_check_mark: - Demo Flow Design and Presentation (Rouven, Martin) :heavy_check_mark: - Demo transfer of NFT? (not part of friday demo) - Where does Veramo come in? - Where to go from here? - Break it down to "base components" - Central Hosted Accumulator (did:web agent) - Metamask KMS Integration - DID:NFT resolver - Credential Proof Format - :hammer: Migrate solution from JWT to JSON-LD Credentials (Martin) - Maybe in context with Metamask-Sig - "Web3-Veramo-Kit" should be separate from agent explorer codebase. - Out of scope for friday's demo # Outcome / Learning - Backend / Frontend Code Sharing within Projects like Pulsar - Wrap outcome into dApp Library for web3 frontend signing. (Preconfigured Web3 provider that is automatically provided to KeyManager, DIDManager and Messaging) -> Greg, Simonas - Web3 / Metamask Handling (e.g. Connect, Disconnect) is out-of-scope of Veramo. - "Profile Credential" for name and profile pic for any DID. - Prepare Deployment Infrastructure to dynamically handle bigger loads (e.g. provide Credit Card information) # Discussion Points - How to resolve messaging endpoints for `did:nfts?` - Martin: Is that relevant for MVP? - Client -> Twitter NFT Agent Hard-coded for demo? - Twitter NFT Agent -> Client: No communication - did:ethr as controller of did:nft: - ERC721 specifies an ethereum address as owner, not a did:ethr. Key rotations in did:ethr are not represented in ERC721. - Owner addresses of various NFTs are NOT necessarily DID compliant - [did:nft](https://github.com/ceramicnetwork/CIP/blob/main/CIPs/CIP-94/CIP-94.md) method by Ceramic - Relies heavily on chain-agnostic CAIP specs. - Faces the same problem as stated above. Existing NFTs do not present owner as DIDs - Mircea: We would have a different view of a did:nft method. On Friday start conversation with Ceramic. - Serto: https://serto.medium.com/verifiable-authorship-for-the-150-million-nft-art-market-8a7affe90186 - "Web3-Veramo-Kit" should be separate from agent explorer codebase. - EIP-1056 on Matic: not prioritized # Resources - [Olivers Whimsical](https://whimsical.com/nft-demo-J1vEefJnSqp4XVCU91g95t) - Original Design Notes on [Whimsical](https://whimsical.com/twitter-for-nfts-TLJBMoYBGaKLXfgK7Vx1r1) # Grooming Meeting 3/15/2021 ## Agenda: - Wednesday Meeting: What to show: - Rouven: Updated presentation / messaging - Demos? - DID:NFT Method - Veramo Client-side Metamask demo (NFT-Twitter) - DID-Chat (NFT-Chat): A->B hosted on Server C ## Protocol - Internal Consensys Meeting on 3/17 with Consensys Leadership Team - Extended Demo Ideas: - Simonas: Include Messaging Part in Same Demo. - Include "private Messaging" in Twitter NFT Demo - Be able to send messages to the messaging endpoint of the did:nft - Every client would need an endpoint to receive private messages. - Public "Messaging Instance" of Veramo: How would that work? - Message must be encrypted for receipient - Message must be able to integrity checked on server side - Retrieving (encrypted) messages should only be possible for receipient. - For Wednesday Demo: - Restrict to Demo to send private messages to personal endpoints. - Challenges: Where does the endpoint information live? - Rouven: Use different Skins for NFT-Twitter and Personal Message portal, so that audience understand the different - Simonas: Contact Form for NFTs? - Simonas: VC can be NFTs that are not in the Blockchain yet. YOU own -> VCs YOU own -> NFTs connection via (YOU). I don't see UC VC->NFT - Should VC (like Ethr) have a possibility to point to a on-chain transfer? - CredentialStatus with "Transfer" support. e.g. credentialSubject changed from DID1 to DID2. - Assigned new Tasks until Wednesday # Metamask Credential EIP712 Example: ``` const credential = { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3id.org/veramolabs/socialmedia/context/v1" ], "type": [ "VerifiableCredential", "VerifableSocialMediaPosting" ], "id": "https://example.org/post/1234", "issuer": "did:example:aadsfewfweasdfsfad", "issuanceDate": "2010-01-01T19:23:24Z", "credentialSubject": { // might contain reply tweet URL "id": "https://example.org/post/1234", "type": "SocialMediaPosting", "author": { "id": "did:nft:ebfeb1f712ebc6f1c276e12ec21", "type": "Person", "thumbnail": "https://google.com", "image": "https://google.com", "name": "cryptopunk" }, "headline": "punks are aliens", "articleBody": "waffles for zoomers" }, "credentialSchema": { "id": "https://www.w3id.org/veramolabs/socialmedia/context/v1/eip712.json", "type": "Eip712SchemaValidator2021" } }; // TODO: normally one should get eip712 schema from credentialSchema URI const eip712Schema = { VerifiableCredential: [ { name: '@context', type: 'string[]' }, { name: 'type', type: 'string[]' }, { name: 'id', type: 'string' }, { name: 'issuer', type: 'string' }, { name: 'issuanceDate', type: 'string' }, { name: 'credentialSubject', type: 'CredentialSubject' }, { name: 'credentialSchema', type: 'CredentialSchema' } ], CredentialSchema: [ { name: 'id', type: 'string' }, { name: 'type', type: 'string' }, ], CredentialSubject: [ { name: 'type', type: 'string' }, { name: 'id', type: 'string' }, { name: 'headline', type: 'string' }, { name: 'articleBody', type: 'string' }, { name: 'author', type: 'Person' } ], Person: [ { name: 'type', type: 'string' }, { name: 'id', type: 'string' }, { name: 'thumbnail', type: 'string' }, { name: 'image', type: 'string' }, { name: 'name', type: 'string' } ] }; // TODO: normalize credential using JCS const data = JSON.stringify({ types: { EIP712Domain: [ { name: 'name', type: 'string' }, { name: 'version', type: 'string' }, { name: 'chainId', type: 'uint256' }, { name: 'salt', type: 'bytes32' }, ], ... eip712Schema }, domain: { name: 'Sign Tweet', version: '2', chainId: 4, salt: '0xf2d857f4a3edcb9b78b4d503bfe733db1e3f6cdc2b7971ee739626c97e86a558', }, primaryType: 'VerifiableCredential', message: { ... credential } }); const signer = walletAddress; const params = [signer, data]; web3.currentProvider.sendAsync( { method: 'eth_signTypedData_v4', params, from: signer, jsonrpc: '2.0', id: new Date().getTime(), }, (error, response) => { if (error) { return setErrorMsg(error.message); } else if (response && response.error) { const errMsg = response.error.message.substring(0, 70).concat('...'); return setErrorMsg(errMsg); } else { const result = response && response.result; const signature = result && result.substring(2); const r = signature && '0x' + signature.substring(0, 64); const s = signature && '0x' + signature.substring(64, 128); const v = signature && parseInt(signature.substring(128, 130), 16); const signatures = { signature, r, s, v, }; setSuccessMsg(`Successfully signed data!! ${signature}`); setData({ signatures, ...JSON.parse(data) }); } } ); }; ``` Resulting Proof: ``` "proof": { "type": "EthereumEip712Signature2021", "verificationMethod": "did:ethr:0xabc#...", "proofPurpose": "assertionMethod", "domain": { "name": 'Sign Tweet', "version": '2', "chainId": 4, "salt": '0xf2d857f4a3edcb9b78b4d503bfe733db1e3f6cdc2b7971ee739626c97e86a558', }, "signature": "a5976468abf6b39242bd892c19047e4f83454f31c073b3d6e87954fbef259e156a3fbe2ae401054e6efaa1097647b2236cd11fdc322680405a1e840614d2ac601c" } ```