This commit is contained in:
Taylor Hulsmans 2023-09-04 17:12:29 +02:00
parent 3757c26313
commit 1dd6e863f7
19 changed files with 16083 additions and 45 deletions

5
.gitignore vendored
View file

@ -20,3 +20,8 @@ data.json
# Exclude macOS Finder (System Explorer) View States
.DS_Store
.env
hardhat/artifacts
hardhat/cache

View file

@ -0,0 +1,4 @@
import { createContext } from "react";
import { App } from "obsidian";
export const AppContext = createContext<App | undefined>(undefined);

View file

@ -0,0 +1,7 @@
import { useContext } from "react";
import { AppContext } from "../context/context";
import { App } from "obsidian";
export const useApp = (): App | undefined => {
return useContext(AppContext);
};

View file

@ -0,0 +1,8 @@
import { useApp } from 'components/hooks/useApp';
export const ReactView = () => {
const { vault } = useApp();
console.log('hello react')
return (<h4>vault name: {vault.getName()}</h4>);
};

View file

@ -15,7 +15,7 @@ const context = await esbuild.context({
banner: {
js: banner,
},
entryPoints: ["main.ts"],
entryPoints: ["main.tsx"],
bundle: true,
external: [
"obsidian",

13
hardhat/README.md Normal file
View file

@ -0,0 +1,13 @@
# Sample Hardhat Project
This project demonstrates a basic Hardhat use case. It comes with a sample contract, a test for that contract, and a script that deploys that contract.
Try running some of the following tasks:
```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat run scripts/deploy.js
```

View file

@ -0,0 +1,73 @@
// SPDX-License-Identifier: GPLv3
pragma solidity 0.8.19;
interface ModicumContract {
function runModuleWithDefaultMediators(string calldata name, string calldata params) external payable returns (uint256);
}
// Payment is 2 lilETH for all jobs currently
// got to testnet.lilypadnetwork.org to fund your wallet
contract ExampleClient {
address public _contractAddress;
ModicumContract remoteContractInstance;
uint256 public lilypadFee = 2;
struct Result {
uint256 jobID;
string cid;
string httpString;
}
Result[] public results;
event ReceivedJobResults(uint256 jobID, string cid);
// The Modicum contract address is found here: https://github.com/bacalhau-project/lilypad-modicum/blob/main/latest.txt
// Current: 0x422F325AA109A3038BDCb7B03Dd0331A4aC2cD1a
constructor (address contractAddress) {
require(contractAddress != address(0), "NaiveExamplesClient: contract cannot be zero address");
_contractAddress = contractAddress;
remoteContractInstance = ModicumContract(contractAddress);
}
function setLilypadFee(uint256 _fee) public {
lilypadFee = _fee;
}
function runCowsay(string memory sayWhat) public payable returns (uint256) {
require(msg.value == lilypadFee * 1 ether, string(abi.encodePacked("Payment of 2 Ether is required")));
return runModule("cowsay:v0.0.1", sayWhat);
}
function runStablediffusion(string memory prompt) public payable returns (uint256) {
require(msg.value == lilypadFee * 1 ether, string(abi.encodePacked("Payment of 2 Ether is required")));
return runModule("stable_diffusion:v0.0.1", prompt);
}
function runSDXL(string memory prompt) public payable returns (uint256) {
require(msg.value == lilypadFee * 1 ether, string(abi.encodePacked("Payment of 2 Ether is required")));
return runModule("sdxl:v0.9-lilypad1", prompt);
}
function runModule(string memory name, string memory params) public payable returns (uint256) {
require(msg.value == lilypadFee * 1 ether, string(abi.encodePacked("Payment of 2 Ether is required")));
return remoteContractInstance.runModuleWithDefaultMediators{value: msg.value}(name, params);
}
// Implemented Modicum interface. This saves results to a results array
function receiveJobResults(uint256 _jobID, string calldata _cid) public {
Result memory jobResult = Result({
jobID: _jobID,
cid: _cid,
httpString: string(abi.encodePacked("https://ipfs.io/ipfs/", _cid))
});
results.push(jobResult);
emit ReceivedJobResults(_jobID, _cid);
}
function fetchAllResults() public view returns (Result[] memory) {
return results;
}
}

24
hardhat/hardhat.config.js Normal file
View file

@ -0,0 +1,24 @@
require('dotenv').config()
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.19",
//defaultNetwork: 'lilypad',
networks: {
hardhat: {
forking: {
url: "http://testnet.lilypadnetwork.org:8545"
},
accounts: {
mnemonic: process.env.MNEMONIC
}
},
lilypad: {
url: "http://testnet.lilypadnetwork.org:8545",
accounts: {
mnemonic: process.env.MNEMONIC
}
}
},
};

9639
hardhat/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

10
hardhat/package.json Normal file
View file

@ -0,0 +1,10 @@
{
"name": "hardhat-project",
"devDependencies": {
"@nomicfoundation/hardhat-toolbox": "^3.0.0",
"hardhat": "^2.17.2"
},
"dependencies": {
"dotenv": "^16.3.1"
}
}

32
hardhat/scripts/deploy.js Normal file
View file

@ -0,0 +1,32 @@
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// You can also run a script with `npx hardhat run <script>`. If you do that, Hardhat
// will compile your contracts, add the Hardhat Runtime Environment's members to the
// global scope, and execute the script.
const hre = require("hardhat");
async function main() {
//const currentTimestampInSeconds = Math.round(Date.now() / 1000);
//const unlockTime = currentTimestampInSeconds + 60;
const lockedAmount = hre.ethers.parseEther("0.001");
const exampleClient = await hre.ethers.deployContract(
"ExampleClient", ['0x422F325AA109A3038BDCb7B03Dd0331A4aC2cD1a']
);
await exampleClient.waitForDeployment();
console.log(await exampleClient.getAddress())
return await exampleClient.getAddress()
}
// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
exports.main = main

View file

@ -0,0 +1,17 @@
const hre = require('hardhat')
const clientLilypadAddr = "0x59f1F1e6ca5C3ddB64E8dbBEa12f31D9236d7e64"
async function main() {
const exampleClient = await hre.ethers.getContractAt("ExampleClient", clientLilypadAddr)
const cowsay = await exampleClient.runCowsay('hello cowsay from hardhat', {
value: hre.ethers.parseUnits('2', 'ether')
})
console.log(cowsay)
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

View file

@ -0,0 +1,15 @@
const hre = require('hardhat')
const clientLilypadAddr = "0x59f1F1e6ca5C3ddB64E8dbBEa12f31D9236d7e64"
async function main() {
const exampleClient = await hre.ethers.getContractAt("ExampleClient", clientLilypadAddr)
const cowsay = await exampleClient.fetchAllResults()
console.log(cowsay)
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

View file

@ -0,0 +1,25 @@
const hre = require('hardhat')
const {main} = require('../scripts/deploy')
describe("Example Client", async () => {
let accounts;
let exampleClient;
before(async () => {
accounts = await hre.ethers.getSigners()
const exampleClientAddr = await main()
console.log('exampleaddr', exampleClientAddr)
exampleClient = await hre.ethers.getContractAt("ExampleClient", exampleClientAddr)
})
it("can talk to the modicum through lilypad fork", async () => {
const test = await exampleClient.runCowsay('hello Cowsay', {
value: hre.ethers.parseUnits('2', 'ether')
})
console.log('test', test)
})
})

View file

@ -1,23 +1,30 @@
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, ItemView, WorkspaceLeaf } from 'obsidian';
import { ReactView } from './components/views/ReactView'
import { createContext, StrictMode, useContext } from "react";
import { createRoot, Root } from 'react-dom/client'
import { AppContext } from 'components/context/context';
const VIEW_TYPE_EXAMPLE = "example-view";
// Remember to rename these classes and interfaces!
interface MyPluginSettings {
interface ObsidianLilypadSettings {
mySetting: string;
}
const DEFAULT_SETTINGS: MyPluginSettings = {
const DEFAULT_SETTINGS: ObsidianLilypadSettings = {
mySetting: 'default'
}
export default class MyPlugin extends Plugin {
settings: MyPluginSettings;
export default class ObsidianLilypad extends Plugin {
settings: ObsidianLilypadSettings;
async onload() {
await this.loadSettings();
// This creates an icon in the left ribbon.
const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
const ribbonIconEl = this.addRibbonIcon('dice', 'Obsidian Lilypad', (evt: MouseEvent) => {
// Called when the user clicks the icon.
new Notice('This is a notice!');
});
@ -66,7 +73,7 @@ export default class MyPlugin extends Plugin {
});
// This adds a settings tab so the user can configure various aspects of the plugin
this.addSettingTab(new SampleSettingTab(this.app, this));
this.addSettingTab(new ObsidianLilypadSettingTab(this.app, this));
// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
// Using this function will automatically remove the event listener when this plugin is disabled.
@ -97,34 +104,34 @@ class SampleModal extends Modal {
}
onOpen() {
const {contentEl} = this;
contentEl.setText('Woah!');
const { contentEl } = this;
contentEl.setText('Woah! hot reload');
}
onClose() {
const {contentEl} = this;
const { contentEl } = this;
contentEl.empty();
}
}
class SampleSettingTab extends PluginSettingTab {
plugin: MyPlugin;
class ObsidianLilypadSettingTab extends PluginSettingTab {
plugin: ObsidianLilypad;
constructor(app: App, plugin: MyPlugin) {
constructor(app: App, plugin: ObsidianLilypad) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
const {containerEl} = this;
const { containerEl } = this;
containerEl.empty();
new Setting(containerEl)
.setName('Setting #1')
.setName('Private Key')
.setDesc('It\'s a secret')
.addText(text => text
.setPlaceholder('Enter your secret')
.setPlaceholder('Enter your Ethereum Private Key')
.setValue(this.plugin.settings.mySetting)
.onChange(async (value) => {
this.plugin.settings.mySetting = value;
@ -132,3 +139,35 @@ class SampleSettingTab extends PluginSettingTab {
}));
}
}
class ExampleView extends ItemView {
root: Root | null = null;
constructor(leaf: WorkspaceLeaf) {
super(leaf);
}
getViewType() {
return VIEW_TYPE_EXAMPLE;
}
getDisplayText() {
return "Example view";
}
async onOpen() {
this.root = createRoot(this.containerEl.children[1]);
this.root.render(
<StrictMode>
<AppContext.Provider value={this.app}>
<ReactView />,
</AppContext.Provider>
</StrictMode>,
);
}
async onClose() {
this.root?.unmount();
}
}

View file

@ -1,9 +1,9 @@
{
"id": "sample-plugin",
"name": "Sample Plugin",
"id": "obsidian-lilypad",
"name": "Obisidian Lilypad",
"version": "1.0.0",
"minAppVersion": "0.15.0",
"description": "This is a sample plugin for Obsidian. This plugin demonstrates some of the capabilities of the Obsidian API.",
"description": "Run Edge Compute Jobs through blockchain smart contracts",
"author": "Obsidian",
"authorUrl": "https://obsidian.md",
"fundingUrl": "https://obsidian.md/pricing",

6117
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,24 +1,31 @@
{
"name": "obsidian-sample-plugin",
"version": "1.0.0",
"description": "This is a sample plugin for Obsidian (https://obsidian.md)",
"main": "main.js",
"scripts": {
"dev": "node esbuild.config.mjs",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"version": "node version-bump.mjs && git add manifest.json versions.json"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
}
"name": "obsidian-lilypad",
"version": "1.0.0",
"description": "Run Edge Compute jobs through blockchain smart contracts with lilypad",
"main": "main.tsx",
"scripts": {
"dev": "node esbuild.config.mjs",
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
"version": "node version-bump.mjs && git add manifest.json versions.json"
},
"keywords": [],
"author": "",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "5.29.0",
"@typescript-eslint/parser": "5.29.0",
"builtin-modules": "3.3.0",
"esbuild": "0.17.3",
"hardhat": "^2.17.2",
"obsidian": "latest",
"tslib": "2.4.0",
"typescript": "4.7.4"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}

View file

@ -1,5 +1,6 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"baseUrl": ".",
"inlineSourceMap": true,
"inlineSources": true,
@ -10,7 +11,7 @@
"moduleResolution": "node",
"importHelpers": true,
"isolatedModules": true,
"strictNullChecks": true,
"strictNullChecks": true,
"lib": [
"DOM",
"ES5",
@ -19,6 +20,8 @@
]
},
"include": [
"**/*.ts"
"**/*.ts",
"**/*.tsx",
"main.tsx"
]
}
}