diff --git a/README.md b/README.md index bb0348e..966b8df 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,37 @@ # Obsidian Sample Plugin -This is a sample plugin for Obsidian (https://obsidian.md). +This is a [desci nodes](https://desci.com/), [lilypad](https://docs.lilypadnetwork.org/lilypad-v1-testnet/overview), and [ipfs helia](https://github.com/ipfs/helia) plugin for Obsidian (https://obsidian.md). -This project uses Typescript to provide type checking and documentation. -The repo depends on the latest plugin API (obsidian.d.ts) in Typescript Definition format, which contains TSDoc comments describing what it does. +Pull Desci nodes, run edge compute jobs by calling smart contracts, and fetch from ipfs all from the obsidian canvas. + +Targeting enabling a composition pipeline for scientists that builds into their existing tools and is easy to use **Note:** The Obsidian API is still in early alpha and is subject to change at any time! +### Config +- Private Key - a private key for an ethereum address that has lil ETH on the lalechuza testnet +- Delegate Kubo - speed up pulling from ipfs by delegating content routing through a kubo node one runs separately in a terminal -This sample plugin demonstrates some of the basic functionality the plugin API can do. -- Adds a ribbon icon, which shows a Notice when clicked. -- Adds a command "Open Sample Modal" which opens a Modal. -- Adds a plugin setting tab to the settings page. -- Registers a global click event and output 'click' to the console. -- Registers a global interval which logs 'setInterval' to the console. - -## First time developing plugins? - -Quick starting guide for new plugin devs: - -- Check if [someone already developed a plugin for what you want](https://obsidian.md/plugins)! There might be an existing plugin similar enough that you can partner up with. -- Make a copy of this repo as a template with the "Use this template" button (login to GitHub if you don't see it). -- Clone your repo to a local development folder. For convenience, you can place this folder in your `.obsidian/plugins/your-plugin-name` folder. -- Install NodeJS, then run `npm i` in the command line under your repo folder. -- Run `npm run dev` to compile your plugin from `main.ts` to `main.js`. -- Make changes to `main.ts` (or create new `.ts` files). Those changes should be automatically compiled into `main.js`. -- Reload Obsidian to load the new version of your plugin. -- Enable plugin in settings window. -- For updates to the Obsidian API run `npm update` in the command line under your repo folder. - -## Releasing new releases - -- Update your `manifest.json` with your new version number, such as `1.0.1`, and the minimum Obsidian version required for your latest release. -- Update your `versions.json` file with `"new-plugin-version": "minimum-obsidian-version"` so older versions of Obsidian can download an older version of your plugin that's compatible. -- Create new GitHub release using your new version number as the "Tag version". Use the exact version number, don't include a prefix `v`. See here for an example: https://github.com/obsidianmd/obsidian-sample-plugin/releases -- Upload the files `manifest.json`, `main.js`, `styles.css` as binary attachments. Note: The manifest.json file must be in two places, first the root path of your repository and also in the release. -- Publish the release. - -> You can simplify the version bump process by running `npm version patch`, `npm version minor` or `npm version major` after updating `minAppVersion` manually in `manifest.json`. -> The command will bump version in `manifest.json` and `package.json`, and add the entry for the new version to `versions.json` - -## Adding your plugin to the community plugin list - -- Check https://github.com/obsidianmd/obsidian-releases/blob/master/plugin-review.md -- Publish an initial version. -- Make sure you have a `README.md` file in the root of your repo. -- Make a pull request at https://github.com/obsidianmd/obsidian-releases to add your plugin. +### Commands +In a canvas, select a node and run hit Ctrl-P to search for +- Desci - pull a desci node from beta.dpid.org +- runSDXL - run stable diffusion by executing a transation through lilypad +- ipfsCAT - pull the content from a CID from ipfs ## How to use -- Clone this repo. +- Clone this repo. into the .obsidian/plugins folder of your vault - Make sure your NodeJS is at least v16 (`node --version`). - `npm i` or `yarn` to install dependencies. - `npm run dev` to start compilation in watch mode. -## Manually installing the plugin - -- Copy over `main.js`, `styles.css`, `manifest.json` to your vault `VaultFolder/.obsidian/plugins/your-plugin-id/`. - -## Improve code quality with eslint (optional) -- [ESLint](https://eslint.org/) is a tool that analyzes your code to quickly find problems. You can run ESLint against your plugin to find common bugs and ways to improve your code. -- To use eslint with this project, make sure to install eslint from terminal: - - `npm install -g eslint` -- To use eslint to analyze this project use this command: - - `eslint main.ts` - - eslint will then create a report with suggestions for code improvement by file and line number. -- If your source code is in a folder, such as `src`, you can use eslint with this command to analyze all files in that folder: - - `eslint .\src\` - -## Funding URL - -You can include funding URLs where people who use your plugin can financially support it. - -The simple way is to set the `fundingUrl` field to your link in your `manifest.json` file: - ```json { - "fundingUrl": "https://buymeacoffee.com" -} -``` - -If you have multiple URLs, you can also do: - -```json -{ - "fundingUrl": { - "Buy Me a Coffee": "https://buymeacoffee.com", - "GitHub Sponsor": "https://github.com/sponsors", - "Patreon": "https://www.patreon.com/" - } + "fundingUrl": "joe-mcgee.radicle.eth" } ``` ## API Documentation See https://github.com/obsidianmd/obsidian-api +See https://docs.lilypadnetwork.org/lilypad-v1-testnet/overview +See https://docs.desci.com/learn/open-state-repository/pid diff --git a/kubo.ts b/kubo.ts index ef2fd12..c5c9c1c 100644 --- a/kubo.ts +++ b/kubo.ts @@ -1,25 +1,72 @@ import { createLibp2p, type Libp2p } from 'libp2p' import { delegatedPeerRouting } from '@libp2p/delegated-peer-routing' +import { delegatedContentRouting } from '@libp2p/delegated-content-routing' +import { mplex } from '@libp2p/mplex' +import { webRTC, webRTCDirect } from '@libp2p/webrtc' +import { webSockets } from '@libp2p/websockets' +import { webTransport } from '@libp2p/webtransport' import { create as kuboClient } from 'kubo-rpc-client' - +import { circuitRelayTransport } from 'libp2p/circuit-relay' +import { MemoryBlockstore } from 'blockstore-core' +import { MemoryDatastore } from 'datastore-core' +import { noise } from '@chainsafe/libp2p-noise' +import { yamux } from '@chainsafe/libp2p-yamux' +import { autoNATService } from 'libp2p/autonat' +import { identifyService, type IdentifyService } from 'libp2p/identify' // default is to use ipfs.io export const client = kuboClient({ // use default api settings protocol: 'http', port: 5001, - host: '127.0.0.1' + host: '127.0.0.1', + headers: { + 'Access-Control-Allow-Origin': "*", + 'Access-Control-Allow-Methods': 'GET, HEAD, OPTIONS', + "Authorization": 'Bearer whatever' + } }) -export const node = async (): Promise}>> => { - const node = await createLibp2p({ +export const node = async (): Promise<{ + node: Libp2p<{ identify: IdentifyService; autoNAT: unknown; }>; + blockstore: MemoryBlockstore; + datastore: MemoryDatastore; +}> => { + const blockstore = new MemoryBlockstore() + const datastore = new MemoryDatastore() + const node = await createLibp2p({ + start: true, // TODO: libp2p bug with stop/start - https://github.com/libp2p/js-libp2p/issues/1787 peerRouters: [ - delegatedPeerRouting(client) - ] + delegatedPeerRouting(client) + ], + contentRouters: [ + delegatedContentRouting(client) + ], + datastore, + transports: [ + webRTC(), + webRTCDirect(), + webTransport(), + webSockets(), + circuitRelayTransport({ + discoverRelays: 1 + }) + ], + connectionEncryption: [ + noise() + ], + streamMuxers: [ + yamux(), + mplex() + ], + services: { + identify: identifyService(), + autoNAT: autoNATService() + } //.. other config - }) - return node - const peerInfo = await node.peerRouting.findPeer('peerid') - console.log('peerInfo', peerInfo) + }) + return { node, blockstore, datastore } + //const peerInfo = await node.peerRouting.findPeer('peerid') + //console.log('peerInfo', peerInfo) } \ No newline at end of file diff --git a/main.tsx b/main.tsx index e16b909..e266805 100644 --- a/main.tsx +++ b/main.tsx @@ -21,6 +21,24 @@ import { CID } from 'multiformats' import { delegatedContentRouting } from '@libp2p/delegated-content-routing' import { type create as createKuboClient } from 'kubo-rpc-client' + +(async function heliaAuto() { + const instance = await createHelia() + const testfs = await unixfs(instance) + const testDecoder = new TextDecoder() + let content = '' + + let Cid = CID.parse(String('QmQb8JqfusoZ9opKJSrToabwCq2Vjv1JJyUPRYG6FJVg1P')) + for await (const buf of testfs.cat(Cid)) { + console.log('buffer', buf) + content += testDecoder.decode(buf, { + stream: true + }) + } + console.log('content', content) +})(); + + interface ChainConfig { name: string; rpcUrl: string; @@ -67,6 +85,23 @@ export default class ObsidianLilypad extends Plugin { } else { console.log('no private key detected, web3 not enabled') } + try { + if(this.settings.delegateKubo) { + const instance = await initHelia(client) + console.log('helia delegate kubo') + this.fs = unixfs(instance) + this.helia = instance + } else { + console.log('starting helia without kubo') + this.helia = await createHelia({}) + this.fs = unixfs(this.helia) + } + this.decoder = new TextDecoder() + + } catch (e) { + this.logDebug(`helia init error: ${e}`) + } + console.log('passed helia') this.addCommand({ id: 'runCowsay', name: 'execute the cowsay program through a smart contract', @@ -95,21 +130,6 @@ export default class ObsidianLilypad extends Plugin { this.cat() } }); - try { - if(this.settings.delegateKubo) { - this.helia = await initHelia(client) - console.log('helia delegate kubo') - this.fs = unixfs(this.helia) - } else { - this.helia = await createHelia() - this.fs = unixfs(this.helia) - } - this.decoder = new TextDecoder() - - } catch (e) { - this.logDebug(`helia init error: ${e}`) - } - console.log('passed helia') // This creates an icon in the left ribbon. const ribbonIconEl = this.addRibbonIcon('dice', 'Obsidian Lilypad', (evt: MouseEvent) => { @@ -325,9 +345,9 @@ export default class ObsidianLilypad extends Plugin { let Cid = CID.parse(String(nodeText)) console.log('Cid', Cid) console.log('Cid', Cid.toString()) - console.log(this.fs.cat(CID.parse(String(nodeText)))) - for await (const buf of this.fs.cat(CID.parse(String(nodeText)))) { - console.log(buf) + console.log(this.fs.cat(Cid)) + for await (const buf of this.fs.cat(Cid)) { + console.log('buffer', buf) content += this.decoder.decode(buf, { stream: true })