├── .eslintrc.js ├── .gitignore ├── .nojekyll ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── docs ├── images ├── lit-logo.png └── web-playground-logo.svg ├── index.html ├── package.json ├── prettier.config.js ├── src ├── app.ts └── decs.d.ts ├── tsconfig.json ├── walkthrough.md ├── yarn-error.log └── yarn.lock /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['3box', '3box/typescript'], 3 | rules: { 4 | '@typescript-eslint/ban-ts-comment': 'off', 5 | '@typescript-eslint/ban-ts-ignore': 'off', 6 | '@typescript-eslint/interface-name-prefix': 'off', 7 | '@typescript-eslint/no-unsafe-assignment': 'off', 8 | '@typescript-eslint/no-unsafe-call': 'off', 9 | '@typescript-eslint/no-unsafe-member-access': 'off', 10 | '@typescript-eslint/no-unsafe-return': 'off', 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .parcel-cache/ 3 | dist/ 4 | 5 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LIT-Protocol/CeramicIntegrationExample/46ec4985934206e95564fadeeab2243f7963cfc0/.nojekyll -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at 2 | 3 | http://www.apache.org/licenses/LICENSE-2.0 4 | 5 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 6 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lit Ceramic Integration 2 | 3 | ## Welcome! 4 | 5 | Welcome to the [Lit Ceramic Integration](https://github.com/LIT-Protocol/CeramicIntegration) web playground. This is a playground for the [lit-ceramic-sdk](https://www.npmjs.com/package/lit-ceramic-sdk) module, to show anyone who's interested what it looks like in practice! It uses this module to encrypt (with Lit) and store (with Cermamic) any string the user wants to store. It will be accessible only to those who control the wallet of the user that made it. It appears on the ceramic network as encrypted data. 6 | 7 | ## Quick and Dirty Instructions for running in dev 8 | 9 | Make sure to run `yarn` to install everything at first. 10 | 11 | Run `yarn start` to start the server. 12 | 13 | ## [Ceramic Web Playground](https://ceramicstudio.github.io/web-playground/) 14 | 15 | Test the full stack of [Ceramic Network](https://ceramic.network/) components in a web browser. This project is based off of the above ceramic playground. 16 | 17 | ## Technologies 18 | 19 | - [Lit Protocol Encryption](https://developer.litprotocol.com/docs/intro/): an open source, decentralized utility that uses encryption to provide blockchain users access to digital and real world experiences. The network acts as a decentralized access control list (ACL) which leverages on-chain data to grant users access to content, software, and other decentralized networks. 20 | - [Ceramic HTTP Client](https://developers.ceramic.network/reference/javascript/clients/#http-client): Provides access to the Ceramic Network via a remote node running Ceramic (and IPFS). 21 | - [3ID Connect](https://developers.ceramic.network/build/authentication/#did-provider-or-wallet): Provides authentication to a DID (used by Ceramic) from a blockchain wallet, and stores a link from this blockchain account to your DID in IDX. 22 | 23 | ## Usage 24 | 25 | The app is configured to only let users with at least 0.000001 ETH decrypt the content. This access control condition can be changed to anything you want. You can find some examples here: https://developer.litprotocol.com/docs/SDK/accessControlConditionExamples 26 | 27 | 1. Open the [Playground page, often localhost:1234 when running parcel](http://localhost:1234) 28 | 2. Open your browser's console by inspecting the page 29 | 3. Click Encrypt w/ Lit + Send button to begin process! 30 | 4. Authenticate by clicking "Connect wallet" 31 | 5. Approve prompts in your Web3 wallet for both Ceramic and Lit 32 | 6. Wait to see "Connected with DID" in your console 33 | 7. Write and read Lit-Encrypted documents on the Ceramic Network from the console using the referenced API methods 34 | 35 | ## License 36 | 37 | Apache-2.0 OR MIT 38 | -------------------------------------------------------------------------------- /docs: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### Table of Contents 4 | -------------------------------------------------------------------------------- /images/lit-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LIT-Protocol/CeramicIntegrationExample/46ec4985934206e95564fadeeab2243f7963cfc0/images/lit-logo.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Lit/Ceramic Integration Playground 7 | 11 | 12 | 16 | 119 | 120 | 121 | 122 |
123 |
124 |
125 | 126 |
127 | Not Connected 128 |
129 |
130 |
131 | 132 | + 133 | 134 |
135 |

Lit / Ceramic Web Playground

136 |

137 | Test out the Lit / Ceramic integration. 138 |
139 | Encrypt with Lit and commit to the Ceramic network 140 |
141 | then read from it back using ceramic and decrypt with Lit. 142 |

143 |
144 |
145 | 146 |
147 |
148 |
149 | 150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 | 164 |
165 |
166 | 171 |
172 |
173 | 174 |
175 | 183 |
184 | 185 |
186 | 194 |
195 |
196 |
197 |
198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-playground", 3 | "version": "1.0.0", 4 | "description": "Ceramic Web playground", 5 | "author": "Ceramic Studio", 6 | "license": "(Apache-2.0 OR MIT)", 7 | "homepage": "https://github.com/ceramicstudio/web-playground#readme", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/ceramicstudio/web-playground.git" 11 | }, 12 | "scripts": { 13 | "build": "parcel build index.html", 14 | "lint": "eslint src", 15 | "start": "parcel index.html" 16 | }, 17 | "dependencies": { 18 | "@3id/connect": "^0.1.6", 19 | "@ceramicnetwork/3id-did-resolver": "^1.2.7", 20 | "@ceramicnetwork/common": "^1.1.0", 21 | "@ceramicnetwork/http-client": "^1.0.7", 22 | "@ceramicstudio/idx": "^0.12.1", 23 | "@ceramicstudio/idx-tools": "^0.11.0", 24 | "@walletconnect/web3-provider": "^1.3.3", 25 | "authereum": "^0.1.0", 26 | "dag-jose": "^0.3.0", 27 | "dids": "^2.1.0", 28 | "fortmatic": "^2.2.1", 29 | "http-server": "^14.0.0", 30 | "key-did-resolver": "^1.2.0", 31 | "lit-ceramic-sdk": "^1.1.12", 32 | "lit-js-sdk": "^1.1.121", 33 | "multiformats": "~4.6.1", 34 | "skynet-js": "^4.0.5-beta", 35 | "uint8arrays": "^3.0.0", 36 | "web3modal": "^1.9.3" 37 | }, 38 | "devDependencies": { 39 | "@webpack-cli/serve": "^1.6.0", 40 | "did-jwt": "^5.2.0", 41 | "did-resolver": "^3.0.1", 42 | "eslint": "^7.25.0", 43 | "eslint-config-3box": "^0.2.0", 44 | "parcel": "^2.0.1", 45 | "prettier": "^2.2.1", 46 | "serve": "^12.0.1", 47 | "ts-loader": "^8.2.0", 48 | "typescript": "^4.2.4", 49 | "webpack-cli": "^4.9.1" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require('eslint-config-3box/prettier.config') 2 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import { DID } from 'dids' 2 | import { Integration } from 'lit-ceramic-sdk' 3 | 4 | declare global { 5 | interface Window { 6 | did?: DID 7 | } 8 | } 9 | 10 | let litCeramicIntegration = new Integration('https://ceramic-clay.3boxlabs.com', 'polygon') 11 | 12 | let streamID = 'kjzl6cwe1jw1479rnblkk5u43ivxkuo29i4efdx1e7hk94qrhjl0d4u0dyys1au' // test data 13 | 14 | const updateAlert = (status: string, message: string) => { 15 | const alert = document.getElementById('alerts') 16 | 17 | if (alert !== null) { 18 | alert.textContent = message 19 | alert.classList.add(`alert-${status}`) 20 | alert.classList.remove('hide') 21 | setTimeout(() => { 22 | alert.classList.add('hide') 23 | }, 5000) 24 | } 25 | } 26 | const updateStreamID = (resp: string | String) => { 27 | streamID = resp as string 28 | console.log('you now have this as your streamID', streamID) 29 | // @ts-ignore 30 | document.getElementById('stream').innerText = resp 31 | } 32 | 33 | document.addEventListener('DOMContentLoaded', function () { 34 | console.log('DOMContent.........') 35 | litCeramicIntegration.startLitClient(window) 36 | }) 37 | 38 | document.getElementById('readCeramic')?.addEventListener('click', () => { 39 | if (document.getElementById('stream') === null) { 40 | updateAlert('danger', `Error, please write to ceramic first so a stream can be read`) 41 | } else { 42 | // @ts-ignore 43 | console.log('this is the streamID youre sending: ', streamID) 44 | const response = litCeramicIntegration.readAndDecrypt(streamID).then( 45 | (value) => 46 | // @ts-ignore 47 | (document.getElementById('decryption').innerText = value) 48 | ) 49 | console.log(response) 50 | } 51 | }) 52 | 53 | // encrypt with Lit and write to ceramic 54 | 55 | document.getElementById('encryptLit')?.addEventListener('click', function () { 56 | console.log('chain in litCeramicIntegration: ', litCeramicIntegration.chain) 57 | // @ts-ignore 58 | const stringToEncrypt = document.getElementById('secret').value 59 | // User must posess at least 0.000001 ETH on eth 60 | const accessControlConditions = [ 61 | { 62 | contractAddress: '', 63 | standardContractType: '', 64 | chain: 'ethereum', 65 | method: 'eth_getBalance', 66 | parameters: [':userAddress', 'latest'], 67 | returnValueTest: { 68 | comparator: '>=', 69 | value: '1000000000000', 70 | }, 71 | }, 72 | ] 73 | const response = litCeramicIntegration 74 | .encryptAndWrite(stringToEncrypt, accessControlConditions) 75 | .then((value) => updateStreamID(value)) 76 | console.log(response) 77 | 78 | // const evmContractConditions = [ 79 | // { 80 | // contractAddress: '0xb71a679cfff330591d556c4b9f21c7739ca9590c', 81 | // functionName: 'members', 82 | // functionParams: [':userAddress'], 83 | // functionAbi: { 84 | // constant: true, 85 | // inputs: [ 86 | // { 87 | // name: '', 88 | // type: 'address', 89 | // }, 90 | // ], 91 | // name: 'members', 92 | // outputs: [ 93 | // { 94 | // name: 'delegateKey', 95 | // type: 'address', 96 | // }, 97 | // { 98 | // name: 'shares', 99 | // type: 'uint256', 100 | // }, 101 | // { 102 | // name: 'loot', 103 | // type: 'uint256', 104 | // }, 105 | // { 106 | // name: 'exists', 107 | // type: 'bool', 108 | // }, 109 | // { 110 | // name: 'highestIndexYesVote', 111 | // type: 'uint256', 112 | // }, 113 | // { 114 | // name: 'jailed', 115 | // type: 'uint256', 116 | // }, 117 | // ], 118 | // payable: false, 119 | // stateMutability: 'view', 120 | // type: 'function', 121 | // }, 122 | // chain: 'xdai', 123 | // returnValueTest: { 124 | // key: 'shares', 125 | // comparator: '>=', 126 | // value: '1', 127 | // }, 128 | // }, 129 | // ] 130 | 131 | // const response = litCeramicIntegration 132 | // .encryptAndWrite(stringToEncrypt, evmContractConditions, 'evmContractConditions') 133 | // .then((value) => updateStreamID(value)) 134 | // console.log(response) 135 | }) 136 | -------------------------------------------------------------------------------- /src/decs.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'lit-js-sdk' 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs 3 | "include": ["src", "types"], 4 | "compilerOptions": { 5 | "module": "esnext", 6 | "target": "es5", 7 | "lib": ["dom", "esnext"], 8 | "importHelpers": true, 9 | // match output dir to input dir. e.g. dist/index instead of dist/src/index 10 | "rootDir": "./src", 11 | // stricter type-checking for stronger correctness. Recommended by TS 12 | "strict": false, 13 | // linter checks for common issues 14 | "noImplicitReturns": true, 15 | "noFallthroughCasesInSwitch": true, 16 | // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative 17 | "noUnusedLocals": false, 18 | "noUnusedParameters": false, 19 | // use Node's module resolution algorithm, instead of the legacy TS one 20 | "moduleResolution": "node", 21 | // transpile JSX to React.createElement 22 | "jsx": "react", 23 | // interop between ESM and CJS modules. Recommended by TS 24 | "esModuleInterop": true, 25 | // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS 26 | "skipLibCheck": true, 27 | // error out if import and file system have a casing mismatch. Recommended by TS 28 | "forceConsistentCasingInFileNames": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /walkthrough.md: -------------------------------------------------------------------------------- 1 | # What's going on here? 2 | 3 | Welcome to the Lit Ceramic Integration web playground. This file will walk you through what's going on at a high level. The README is more technically constructive and deals with how to get things started, etc. There's also documentation in the docs file and in-line with the code. 4 | 5 | ### Intention of Project 6 | 7 | This project uses the Lit-Ceramic Integration as a demonstration. It is intended to show a Lit-encrypted asset (in this case a string typed into the textfield) being stored encrypted on the ceramic network. There's plenty of documentation about ceramic at their site, ceramic.network, and we'll focus here mostly on how to use the Lit-Ceramic Integration. And how it's working. 8 | 9 | ### Talk me through it. 10 | 11 | #### Encryption and Storage 12 | 13 | You have a string that you've typed into the textfield and you're ready to store it such that it can be accessed by anyone that reads the streamID of the ceramic stream you create, but can only be decrypted (and hence read intelligibly by those that have the LIT NFT that you encode it with). 14 | 15 | First the sting will need to be encrypted using the LIT-SDK. To do this one needs to log into metamask or equivalent and create a decentralized identity (prompted to do so automatically when you press Encrypt w/ Lit). Once that's complete you'll be asked to sign with you wallet to encrypt with the Lit protocol. 16 | 17 | Second the Lit-Ceramic Integration will work in the background using the above to encrypt and send the data to the ceramic network, and set you up a stream. It should be noted that the data is first encrypted and then encoded into base 64 for easier storage on the ceramic network. Of note, even after decoding the data is still encrypted until one uses Lit and the right key to decrypt. 18 | 19 | That's the end of the encryption flow. 20 | 21 | #### Retrieval and Decryption 22 | 23 | If you click the Read and then Decrypt w/ Lit button you'll be taken through the Retrieval process. Assuming you use the same wallet and use the same Decentralized Identity (often refered to as `did` for short) you can request that the web playground use the streamID of the data you just encrypted and stored and retreive it then decode and decrypt it. 24 | 25 | So first it uses the streamID that was stored locally (and displayed on the website below the textfield) to ask the ceramic network to give it the data that we stored previously. It will come back as what ceramic calls a TileDocument, which is in the form of a JSON object that has two values, for the encrypted zip file blob and the symmetric key. Using our 26 | --------------------------------------------------------------------------------