Skip to content

Commit

Permalink
stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
CedarMist committed Oct 18, 2024
1 parent 323b0a1 commit 1881bad
Show file tree
Hide file tree
Showing 13 changed files with 3,989 additions and 81 deletions.
46 changes: 41 additions & 5 deletions packages/frontend/src/components/HelloWorld.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,55 @@
<script setup lang="ts">
import { ref } from 'vue'
import { ref, toValue } from 'vue'
const count = ref(0)
import { ethersBrowserProvider } from '../wallet';
import { useIExec } from '../iexec';
import { ProtectedData } from '@iexec/dataprotector';
const { dataProtectorCore, dataProtectorWallet } = useIExec();
const results = ref<ProtectedData[]>([]);
const isLoading = ref(false);
async function refreshData() {
isLoading.value = true;
try {
const browserOwner = (await toValue(ethersBrowserProvider)!.getSigner()).address;
//const dpw = toValue(dataProtectorWallet)!
const dpc = toValue(dataProtectorCore)!;
const blah = results.value = await dpc.getProtectedData({
owner: browserOwner
});
console.log(blah);
} finally {
isLoading.value = false;
}
}
refreshData();
</script>

<template>
<h1>Hello!</h1>

<p v-if="isLoading">Loading!...</p>

owner: {{ dataProtectorWallet?.address }}

<div class="card">
<button type="button" @click="count++">count is {{ count }}</button>
<div class="item" v-for="item in results">
Address: {{ item.address }}<br />
Schema: {{ item.schema }}<br />
Timestamp: {{ item.creationTimestamp }}<br />
Owner: {{ item.owner }}<br />
</div>

<button @click.prevent="refreshData">Refresh</button>
</div>
</template>

<style scoped>
.read-the-docs {
color: #888;
div.item {
border: 1px solid #333;
margin-bottom: 5px;
}
</style>
172 changes: 142 additions & 30 deletions packages/frontend/src/components/ProtectShit.vue
Original file line number Diff line number Diff line change
@@ -1,53 +1,117 @@
<script setup lang="ts">
import { useIExec } from '../iexec';
import { iExecDebug, useIExec } from '../iexec';
import { ethersBrowserProvider, iExecChain } from '../wallet';
import { derivedEthersWallet } from '../login';
import { computed, ref, toValue, useTemplateRef } from 'vue'
import { IExecDataProtectorCore, ProtectedDataWithSecretProps } from '@iexec/dataprotector';
const info = ref('');
const {dataProtectorCore} = useIExec();
import { computed, ref, toValue } from 'vue'
import { ProtectedDataWithSecretProps } from '@iexec/dataprotector';
import { ZeroAddress } from 'ethers';
import { getTaskRunnerContract } from '../taskresult';
import QuestionField from './QuestionField.vue'
import { evaluatePrompt } from '../llm';
const isWorking = ref(false);
const isSuccess = ref(false);
const isButtonDisabled = computed(() =>
dataProtectorCore.value === undefined || toValue(isWorking));
const infoInput = useTemplateRef('myInput');
const dpcStatusText = ref('');
const dpcErrorText = ref('');
const dpcResult = ref<ProtectedDataWithSecretProps>();
const { dataProtectorWallet, dataProtectorCore, dataProtectorSharing } = useIExec();
const question = [
['', 'prompt', 'I am medical AI, here are my questions'],
['Please fill out this health questions', 'info'],
['What is your age?', 'number'],
['How many cigarettes per day?', 'range', [0,100]],
['What is your sex?', 'select', ['male', 'female', 'other']],
['When did your symptoms first appear?', 'select', ['Today','This Week', 'This Month', 'This Year', 'Longer than 1 year']],
['Please describe your problem', 'string'],
['', 'prompt', 'Please provide a brief response']
] as const;
const isFormError = ref(false);
const formErrorFields = ref<string[]>([]);
//const qf = [];
//const qv:ReturnType<typeof ref<string>>[] = [];
const qv:string[] = [];
for( const _ in question ) {
qv.push('');
}
function validateQuestions() {
let isValid = true;
formErrorFields.value = [];
const errors = [];
for( const i in question ) {
const q = question[i];
const v = qv[i];
const qt = q[1];
if( qt === 'prompt' || qt === 'info' ) {
continue;
}
if( v.trim().length == 0 ) {
isValid = false;
errors.push(q[0]);
}
}
formErrorFields.value = errors;
isFormError.value = isValid === false;
return isValid;
}
function makePrompt() {
const lines = [];
for( const i in question ) {
const q = question[i];
const qt = q[1];
if( qt === 'info' ) {
continue;
}
if( qt == 'prompt' ) {
lines.push('');
lines.push(q[2]);
lines.push('');
continue;
}
const v = qv[i];
lines.push(` * ${q[0]}: ${v}`);
}
const llm_input = lines.join("\n");
console.log(llm_input);
return llm_input;
}
async function doProtectData () {
const i = toValue(info).trim();
if( ! i.length ) {
toValue(infoInput)?.focus();
if( ! validateQuestions() ) {
return;
};
}
const llm_input = makePrompt();
const ebp = toValue(ethersBrowserProvider);
if( ! ebp ) {
return;
throw new Error('No ethersBrowserProvider!');
}
const wallet = derivedEthersWallet("iExec.dataProtector");
const walletProvider = wallet.connect(ebp);
console.log('Wallet provider Address', walletProvider.address);
const dpc = new IExecDataProtectorCore(walletProvider);
//const dpc = toValue(dataProtectorCore);
const dpw = toValue(dataProtectorWallet);
if( ! dpw ) {
throw new Error('No dataProtectorWallet!');
}
console.log('Wallet provider Address', dpw.address);
const dpc = toValue(dataProtectorCore)
if( dpc ) {
console.log('Protecting data via', dpc);
dpcErrorText.value = '';
isWorking.value = true;
isSuccess.value = false;
const browserWalletAddress = (await ebp.getSigner()).address;
//const browserWalletAddress = (await ebp.getSigner()).address;
try {
const result = dpcResult.value = await dpc.protectData({
data: {
stuff: i
email: llm_input
},
onStatusUpdate: ({title, isDone}) => {
console.log('Data Protector', title, isDone);
Expand All @@ -56,31 +120,67 @@ async function doProtectData () {
});
console.log('Result is', result);
// Debug sconified figlet
const debugAppAddress = '0x05F88328fAe2Ac1271C68f2E65864692c3AD9B0A'
const prodAppAddress = '0xa13cdc6d540b72672eea5997f817942c7d7bafc3';
// Prod app?
const appAddress = iExecDebug ? debugAppAddress : prodAppAddress;
// Grant access to our user to submit it to the specific app
/*
dpc.grantAccess({
const grantAccessResult = await dpc.grantAccess({
protectedData: result.address,
authorizedApp: '0xB907E09DB4D5f512a64694D6160F4b9c446442b1',
authorizedUser: wallet.address,
authorizedApp: appAddress,
authorizedUser: ZeroAddress, // anybody can run this task
pricePerAccess: 0,
numberOfAccess: 1000000,
numberOfAccess: 100000000,
onStatusUpdate: ({title,isDone}) => {
console.log('Data Protector Share (2)', title, isDone);
dpcStatusText.value = title;
}
});
*/
console.log('grantAccessResult', grantAccessResult);
const protectedResult = await dpc.processProtectedData({
app: appAddress,
protectedData: result.address,
workerpool: iExecDebug ? 'debug-v8-bellecour.main.pools.iexec.eth' : '0x0e7bc972c99187c191a17f3cae4a2711a4188c3f',
onStatusUpdate: ({title,isDone}) => {
console.log('Data Protector Share (3)', title, isDone);
dpcStatusText.value = title;
}
});
console.log(protectedResult);
const contract = getTaskRunnerContract(dpw); // new Contract(taskResultContractAddr, taskResultABI, dpw);
const tx = await contract.associate(result.address, protectedResult.taskId);
const receipt = await tx.wait();
console.log('Receipt', receipt);
const x = await toValue(dataProtectorSharing)?.getResultFromCompletedTask({
taskId: protectedResult.taskId
})
if( x ) {
console.log('X is', x);
}
const fakeResult = await evaluatePrompt(llm_input)
console.log('fakeResult s', fakeResult);
// Finally transfer it to the browser owner
/*
dpcStatusText.value = 'Tansferring Ownership';
await dpc.transferOwnership({
protectedData: result.address,
newOwner: browserWalletAddress
});
*/
isSuccess.value = true;
}
catch( e:any ) {
dpcErrorText.value = `Error! ${e}`;;
dpcErrorText.value = `Error! ${e}`;
console.log(e);
}
finally {
isWorking.value = false;
Expand All @@ -95,11 +195,23 @@ async function doProtectData () {
<h1>Protect Yo Data</h1>

<div class="card">
<input type="text" ref="myInput" :disabled="toValue(isButtonDisabled)" name="Data Protector" v-model="info" />

<div v-for="(q, index) of question">
<QuestionField :ref="`q${index}`" v-model:model-value="qv[index]" :q="q"></QuestionField>
</div>

<div v-if="isFormError">
Form validation errors:
<ul>
<li v-for="x of formErrorFields">{{ x }}</li>
</ul>
</div>

<button type="button" :disabled="toValue(isButtonDisabled)" @click="doProtectData()">
Do Everything
</button>
<br />

<input type="text" :hidden="!isWorking" ref="dpcStatus" readonly v-model="dpcStatusText" />
<input type="text" :hidden="toValue(dpcErrorText).length == 0" ref="dpcError" readonly v-model="dpcErrorText" />
<div v-if="isSuccess">
Expand Down
63 changes: 63 additions & 0 deletions packages/frontend/src/components/QuestionField.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script setup lang="ts">
import { randomBytes } from '@noble/hashes/utils';
import { hexlify } from 'ethers';
//defineProps(['modelValue']);
const {q} = defineProps<{
q: Question,
modelValue: string,
disabled?: boolean
}>();
const emit = defineEmits<{
(e: 'update:modelValue', modelValue: string): void
}>();
function updateValue (value:string) {
emit('update:modelValue', value)
};
type InfoQ = readonly [string, 'info']
type PromptQ = readonly ['', 'prompt', string]; // Ignored
type NumberRangeQ = readonly [string, 'range', readonly [number,number]];
type SelectQ = readonly [string, 'select', readonly string[]];
type NumberQ = readonly [string, 'number'];
type StringQ = readonly [string, 'string'];
type Question = PromptQ | NumberRangeQ | SelectQ | StringQ | NumberQ | InfoQ;
if( q === undefined ) {
throw new Error('Unknown question type!');
}
const randomId = hexlify(randomBytes(8));
const [desc, qtype, ...extra] = q;
const range:number[] = [];
if( qtype == 'range' ) {
for( let i = q[2][0]; i <= q[2][1]; i++ ) {
range.push(i);
}
}
</script>

<template>
<label v-if="qtype!='info'" :for="randomId">{{ desc }}</label>
<div v-if="qtype=='number'">
<input :disabled="disabled" type="text" size="3" :id="randomId" :value="modelValue" @input="updateValue(($event.target as HTMLInputElement).value)" />
</div>
<div v-else-if="qtype=='range'">
<select :disabled="disabled" :id="randomId" @change="updateValue(($event.target as HTMLSelectElement).value)">
<option value=""></option>
<option v-for="x of range" :value="x">{{ x }}</option>
</select>
</div>
<div v-else-if="qtype=='select'">
<select :disabled="disabled" :id="randomId" @change="updateValue(($event.target as HTMLSelectElement).value)">
<option value=""></option>
<option v-for="x of extra[0]" :value="x">{{ x }}</option>
</select>
</div>
<div v-else-if="qtype=='string'" @input="updateValue(($event.target as HTMLInputElement).value)" >
<input :disabled="disabled" type="text" :value="modelValue" :id="randomId" />
</div>
<div v-else-if="qtype=='info'">
<p>{{ desc }}</p>
</div>
</template>
Loading

0 comments on commit 1881bad

Please sign in to comment.