Commented all files in /src/pages/account
This commit is contained in:
parent
f78ed88cb1
commit
dddbe04a2d
22
src/main.ts
22
src/main.ts
@ -1,20 +1,20 @@
|
|||||||
import { SignatureComponent } from './pages/signature/signature-component';
|
import { SignatureComponent } from './pages/signature/signature-component';
|
||||||
import { SignatureElement } from './pages/signature/signature';
|
import { SignatureElement } from './pages/signature/signature';
|
||||||
/*import { ChatComponent } from './pages/chat/chat-component';
|
// import { ChatComponent } from './pages/chat/chat-component';
|
||||||
import { ChatElement } from './pages/chat/chat';*/
|
// import { ChatElement } from './pages/chat/chat';
|
||||||
import { AccountComponent } from './pages/account/account-component';
|
// import { AccountComponent } from './pages/account/account-component';
|
||||||
import { AccountElement } from './pages/account/account';
|
// import { AccountElement } from './pages/account/account';
|
||||||
|
|
||||||
export { SignatureComponent, SignatureElement, AccountComponent, AccountElement };
|
export { SignatureComponent, SignatureElement };
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface HTMLElementTagNameMap {
|
interface HTMLElementTagNameMap {
|
||||||
'signature-component': SignatureComponent;
|
'signature-component': SignatureComponent;
|
||||||
'signature-element': SignatureElement;
|
'signature-element': SignatureElement;
|
||||||
/*'chat-component': ChatComponent;
|
// 'chat-component': ChatComponent;
|
||||||
'chat-element': ChatElement;*/
|
// 'chat-element': ChatElement;
|
||||||
'account-component': AccountComponent;
|
// 'account-component': AccountComponent;
|
||||||
'account-element': AccountElement;
|
// 'account-element': AccountElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,6 +25,6 @@ if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB) {
|
|||||||
customElements.define('signature-element', SignatureElement);
|
customElements.define('signature-element', SignatureElement);
|
||||||
/*customElements.define('chat-component', ChatComponent);
|
/*customElements.define('chat-component', ChatComponent);
|
||||||
customElements.define('chat-element', ChatElement);*/
|
customElements.define('chat-element', ChatElement);*/
|
||||||
customElements.define('account-component', AccountComponent);
|
// customElements.define('account-component', AccountComponent);
|
||||||
customElements.define('account-element', AccountElement);
|
// customElements.define('account-element', AccountElement);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,62 +1,62 @@
|
|||||||
import { AccountElement } from './account';
|
// import { AccountElement } from './account';
|
||||||
import accountCss from '../../../public/style/account.css?raw';
|
// import accountCss from '../../../style/account.css?raw';
|
||||||
import Services from '../../services/service.js';
|
// import Services from '../../services/service.js';
|
||||||
|
|
||||||
class AccountComponent extends HTMLElement {
|
// class AccountComponent extends HTMLElement {
|
||||||
_callback: any;
|
// _callback: any;
|
||||||
accountElement: AccountElement | null = null;
|
// accountElement: AccountElement | null = null;
|
||||||
|
|
||||||
constructor() {
|
// constructor() {
|
||||||
super();
|
// super();
|
||||||
console.log('INIT');
|
// console.log('INIT');
|
||||||
this.attachShadow({ mode: 'open' });
|
// this.attachShadow({ mode: 'open' });
|
||||||
|
|
||||||
this.accountElement = this.shadowRoot?.querySelector('account-element') || null;
|
// this.accountElement = this.shadowRoot?.querySelector('account-element') || null;
|
||||||
}
|
// }
|
||||||
|
|
||||||
connectedCallback() {
|
// connectedCallback() {
|
||||||
console.log('CALLBACKs');
|
// console.log('CALLBACKs');
|
||||||
this.render();
|
// this.render();
|
||||||
this.fetchData();
|
// this.fetchData();
|
||||||
|
|
||||||
if (!customElements.get('account-element')) {
|
// if (!customElements.get('account-element')) {
|
||||||
customElements.define('account-element', AccountElement);
|
// customElements.define('account-element', AccountElement);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
async fetchData() {
|
// async fetchData() {
|
||||||
if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB === false) {
|
// if ((import.meta as any).env.VITE_IS_INDEPENDANT_LIB === false) {
|
||||||
const data = await (window as any).myService?.getProcesses();
|
// const data = await (window as any).myService?.getProcesses();
|
||||||
} else {
|
// } else {
|
||||||
const service = await Services.getInstance();
|
// const service = await Services.getInstance();
|
||||||
const data = await service.getProcesses();
|
// const data = await service.getProcesses();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
set callback(fn) {
|
// set callback(fn) {
|
||||||
if (typeof fn === 'function') {
|
// if (typeof fn === 'function') {
|
||||||
this._callback = fn;
|
// this._callback = fn;
|
||||||
} else {
|
// } else {
|
||||||
console.error('Callback is not a function');
|
// console.error('Callback is not a function');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
get callback() {
|
// get callback() {
|
||||||
return this._callback;
|
// return this._callback;
|
||||||
}
|
// }
|
||||||
|
|
||||||
render() {
|
// render() {
|
||||||
if (this.shadowRoot && !this.shadowRoot.querySelector('account-element')) {
|
// if (this.shadowRoot && !this.shadowRoot.querySelector('account-element')) {
|
||||||
const style = document.createElement('style');
|
// const style = document.createElement('style');
|
||||||
style.textContent = accountCss;
|
// style.textContent = accountCss;
|
||||||
|
|
||||||
const accountElement = document.createElement('account-element');
|
// const accountElement = document.createElement('account-element');
|
||||||
|
|
||||||
this.shadowRoot.appendChild(style);
|
// this.shadowRoot.appendChild(style);
|
||||||
this.shadowRoot.appendChild(accountElement);
|
// this.shadowRoot.appendChild(accountElement);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
export { AccountComponent };
|
// export { AccountComponent };
|
||||||
customElements.define('account-component', AccountComponent);
|
// customElements.define('account-component', AccountComponent);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<!DOCTYPE html>
|
<!-- <!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Account</title>
|
<title>Account</title>
|
||||||
@ -7,4 +7,4 @@
|
|||||||
<account-component></account-component>
|
<account-component></account-component>
|
||||||
<script type="module" src="./account.ts"></script>
|
<script type="module" src="./account.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html> -->
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,321 +1,321 @@
|
|||||||
import { ProcessState } from '../../../pkg/sdk_client';
|
// import { ProcessState } from '../../../pkg/sdk_client';
|
||||||
import Services from '../../services/service';
|
// import Services from '../../services/service';
|
||||||
|
|
||||||
interface State {
|
// interface State {
|
||||||
file: File | null;
|
// file: File | null;
|
||||||
fileHash: string | null;
|
// fileHash: string | null;
|
||||||
certificate: ProcessState | null;
|
// certificate: ProcessState | null;
|
||||||
commitmentHashes: string[];
|
// commitmentHashes: string[];
|
||||||
}
|
// }
|
||||||
|
|
||||||
export interface Vin {
|
// export interface Vin {
|
||||||
txid: string; // The txid of the previous transaction (being spent)
|
// txid: string; // The txid of the previous transaction (being spent)
|
||||||
vout: number; // The output index in the previous tx
|
// vout: number; // The output index in the previous tx
|
||||||
prevout: {
|
// prevout: {
|
||||||
scriptpubkey: string;
|
// scriptpubkey: string;
|
||||||
scriptpubkey_asm: string;
|
// scriptpubkey_asm: string;
|
||||||
scriptpubkey_type: string;
|
// scriptpubkey_type: string;
|
||||||
scriptpubkey_address: string;
|
// scriptpubkey_address: string;
|
||||||
value: number;
|
// value: number;
|
||||||
};
|
// };
|
||||||
scriptsig: string;
|
// scriptsig: string;
|
||||||
scriptsig_asm: string;
|
// scriptsig_asm: string;
|
||||||
witness: string[];
|
// witness: string[];
|
||||||
is_coinbase: boolean;
|
// is_coinbase: boolean;
|
||||||
sequence: number;
|
// sequence: number;
|
||||||
}
|
// }
|
||||||
|
|
||||||
export interface TransactionInfo {
|
// export interface TransactionInfo {
|
||||||
txid: string;
|
// txid: string;
|
||||||
version: number;
|
// version: number;
|
||||||
locktime: number;
|
// locktime: number;
|
||||||
vin: Vin[];
|
// vin: Vin[];
|
||||||
vout: any[];
|
// vout: any[];
|
||||||
size: number;
|
// size: number;
|
||||||
weight: number;
|
// weight: number;
|
||||||
fee: number;
|
// fee: number;
|
||||||
status: {
|
// status: {
|
||||||
confirmed: boolean;
|
// confirmed: boolean;
|
||||||
block_height: number;
|
// block_height: number;
|
||||||
block_hash: string;
|
// block_hash: string;
|
||||||
block_time: number;
|
// block_time: number;
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|
||||||
export function getDocumentValidation(container: HTMLElement) {
|
// export function getDocumentValidation(container: HTMLElement) {
|
||||||
const state: State = {
|
// const state: State = {
|
||||||
file: null,
|
// file: null,
|
||||||
fileHash: null,
|
// fileHash: null,
|
||||||
certificate: null,
|
// certificate: null,
|
||||||
commitmentHashes: []
|
// commitmentHashes: []
|
||||||
}
|
// }
|
||||||
|
|
||||||
container.innerHTML = '';
|
// container.innerHTML = '';
|
||||||
container.style.cssText = `
|
// container.style.cssText = `
|
||||||
display: flex;
|
// display: flex;
|
||||||
flex-direction: column;
|
// flex-direction: column;
|
||||||
justify-content: center;
|
// justify-content: center;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
min-height: 100vh;
|
// min-height: 100vh;
|
||||||
gap: 2rem;
|
// gap: 2rem;
|
||||||
`;
|
// `;
|
||||||
|
|
||||||
function createDropButton(
|
// function createDropButton(
|
||||||
label: string,
|
// label: string,
|
||||||
onDrop: (file: File, updateVisuals: (file: File) => void) => void,
|
// onDrop: (file: File, updateVisuals: (file: File) => void) => void,
|
||||||
accept: string = '*/*'
|
// accept: string = '*/*'
|
||||||
): HTMLElement {
|
// ): HTMLElement {
|
||||||
const wrapper = document.createElement('div');
|
// const wrapper = document.createElement('div');
|
||||||
wrapper.style.cssText = `
|
// wrapper.style.cssText = `
|
||||||
width: 200px;
|
// width: 200px;
|
||||||
height: 100px;
|
// height: 100px;
|
||||||
border: 2px dashed #888;
|
// border: 2px dashed #888;
|
||||||
border-radius: 8px;
|
// border-radius: 8px;
|
||||||
display: flex;
|
// display: flex;
|
||||||
flex-direction: column;
|
// flex-direction: column;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
justify-content: center;
|
// justify-content: center;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
background: #f8f8f8;
|
// background: #f8f8f8;
|
||||||
text-align: center;
|
// text-align: center;
|
||||||
padding: 0.5rem;
|
// padding: 0.5rem;
|
||||||
box-sizing: border-box;
|
// box-sizing: border-box;
|
||||||
`;
|
// `;
|
||||||
|
|
||||||
const title = document.createElement('div');
|
// const title = document.createElement('div');
|
||||||
title.textContent = label;
|
// title.textContent = label;
|
||||||
|
|
||||||
const filename = document.createElement('div');
|
// const filename = document.createElement('div');
|
||||||
filename.style.cssText = `
|
// filename.style.cssText = `
|
||||||
font-size: 0.85rem;
|
// font-size: 0.85rem;
|
||||||
margin-top: 0.5rem;
|
// margin-top: 0.5rem;
|
||||||
color: #444;
|
// color: #444;
|
||||||
word-break: break-word;
|
// word-break: break-word;
|
||||||
text-align: center;
|
// text-align: center;
|
||||||
`;
|
// `;
|
||||||
|
|
||||||
wrapper.appendChild(title);
|
// wrapper.appendChild(title);
|
||||||
wrapper.appendChild(filename);
|
// wrapper.appendChild(filename);
|
||||||
|
|
||||||
const updateVisuals = (file: File) => {
|
// const updateVisuals = (file: File) => {
|
||||||
wrapper.style.borderColor = 'green';
|
// wrapper.style.borderColor = 'green';
|
||||||
wrapper.style.background = '#e6ffed';
|
// wrapper.style.background = '#e6ffed';
|
||||||
filename.textContent = file.name;
|
// filename.textContent = file.name;
|
||||||
};
|
// };
|
||||||
|
|
||||||
// === Hidden file input ===
|
// // === Hidden file input ===
|
||||||
const fileInput = document.createElement('input');
|
// const fileInput = document.createElement('input');
|
||||||
fileInput.type = 'file';
|
// fileInput.type = 'file';
|
||||||
fileInput.accept = accept;
|
// fileInput.accept = accept;
|
||||||
fileInput.style.display = 'none';
|
// fileInput.style.display = 'none';
|
||||||
document.body.appendChild(fileInput);
|
// document.body.appendChild(fileInput);
|
||||||
|
|
||||||
fileInput.onchange = () => {
|
// fileInput.onchange = () => {
|
||||||
const file = fileInput.files?.[0];
|
// const file = fileInput.files?.[0];
|
||||||
if (file) {
|
// if (file) {
|
||||||
onDrop(file, updateVisuals);
|
// onDrop(file, updateVisuals);
|
||||||
fileInput.value = ''; // reset so same file can be re-selected
|
// fileInput.value = ''; // reset so same file can be re-selected
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
// === Handle drag-and-drop ===
|
// // === Handle drag-and-drop ===
|
||||||
wrapper.ondragover = e => {
|
// wrapper.ondragover = e => {
|
||||||
e.preventDefault();
|
// e.preventDefault();
|
||||||
wrapper.style.background = '#e0e0e0';
|
// wrapper.style.background = '#e0e0e0';
|
||||||
};
|
// };
|
||||||
|
|
||||||
wrapper.ondragleave = () => {
|
// wrapper.ondragleave = () => {
|
||||||
wrapper.style.background = '#f8f8f8';
|
// wrapper.style.background = '#f8f8f8';
|
||||||
};
|
// };
|
||||||
|
|
||||||
wrapper.ondrop = e => {
|
// wrapper.ondrop = e => {
|
||||||
e.preventDefault();
|
// e.preventDefault();
|
||||||
wrapper.style.background = '#f8f8f8';
|
// wrapper.style.background = '#f8f8f8';
|
||||||
|
|
||||||
const file = e.dataTransfer?.files?.[0];
|
// const file = e.dataTransfer?.files?.[0];
|
||||||
if (file) {
|
// if (file) {
|
||||||
onDrop(file, updateVisuals);
|
// onDrop(file, updateVisuals);
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
// === Handle click to open file manager ===
|
// // === Handle click to open file manager ===
|
||||||
wrapper.onclick = () => {
|
// wrapper.onclick = () => {
|
||||||
fileInput.click();
|
// fileInput.click();
|
||||||
};
|
// };
|
||||||
|
|
||||||
return wrapper;
|
// return wrapper;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const fileDropButton = createDropButton('Drop file', async (file, updateVisuals) => {
|
// const fileDropButton = createDropButton('Drop file', async (file, updateVisuals) => {
|
||||||
try {
|
// try {
|
||||||
state.file = file;
|
// state.file = file;
|
||||||
updateVisuals(file);
|
// updateVisuals(file);
|
||||||
console.log('Loaded file:', state.file);
|
// console.log('Loaded file:', state.file);
|
||||||
checkReady();
|
// checkReady();
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
alert('Failed to drop the file.');
|
// alert('Failed to drop the file.');
|
||||||
console.error(err);
|
// console.error(err);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
const certDropButton = createDropButton('Drop certificate', async (file, updateVisuals) => {
|
// const certDropButton = createDropButton('Drop certificate', async (file, updateVisuals) => {
|
||||||
try {
|
// try {
|
||||||
const text = await file.text();
|
// const text = await file.text();
|
||||||
const json = JSON.parse(text);
|
// const json = JSON.parse(text);
|
||||||
if (
|
// if (
|
||||||
typeof json === 'object' &&
|
// typeof json === 'object' &&
|
||||||
json !== null &&
|
// json !== null &&
|
||||||
typeof json.pcd_commitment === 'object' &&
|
// typeof json.pcd_commitment === 'object' &&
|
||||||
typeof json.state_id === 'string'
|
// typeof json.state_id === 'string'
|
||||||
) {
|
// ) {
|
||||||
state.certificate = json as ProcessState;
|
// state.certificate = json as ProcessState;
|
||||||
|
|
||||||
state.commitmentHashes = Object.values(json.pcd_commitment).map((h: string) =>
|
// state.commitmentHashes = Object.values(json.pcd_commitment).map((h: string) =>
|
||||||
h.toLowerCase()
|
// h.toLowerCase()
|
||||||
);
|
// );
|
||||||
|
|
||||||
updateVisuals(file);
|
// updateVisuals(file);
|
||||||
console.log('Loaded certificate, extracted hashes:', state.commitmentHashes);
|
// console.log('Loaded certificate, extracted hashes:', state.commitmentHashes);
|
||||||
checkReady();
|
// checkReady();
|
||||||
} else {
|
// } else {
|
||||||
alert('Invalid certificate structure.');
|
// alert('Invalid certificate structure.');
|
||||||
}
|
// }
|
||||||
} catch (err) {
|
// } catch (err) {
|
||||||
alert('Failed to parse certificate JSON.');
|
// alert('Failed to parse certificate JSON.');
|
||||||
console.error(err);
|
// console.error(err);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
|
|
||||||
const buttonRow = document.createElement('div');
|
// const buttonRow = document.createElement('div');
|
||||||
buttonRow.style.display = 'flex';
|
// buttonRow.style.display = 'flex';
|
||||||
buttonRow.style.gap = '2rem';
|
// buttonRow.style.gap = '2rem';
|
||||||
buttonRow.appendChild(fileDropButton);
|
// buttonRow.appendChild(fileDropButton);
|
||||||
buttonRow.appendChild(certDropButton);
|
// buttonRow.appendChild(certDropButton);
|
||||||
|
|
||||||
container.appendChild(buttonRow);
|
// container.appendChild(buttonRow);
|
||||||
|
|
||||||
async function checkReady() {
|
// async function checkReady() {
|
||||||
if (state.file && state.certificate && state.commitmentHashes.length > 0) {
|
// if (state.file && state.certificate && state.commitmentHashes.length > 0) {
|
||||||
// We take the commited_in and all pcd_commitment keys to reconstruct all the possible hash
|
// // We take the commited_in and all pcd_commitment keys to reconstruct all the possible hash
|
||||||
const fileBlob = {
|
// const fileBlob = {
|
||||||
type: state.file.type,
|
// type: state.file.type,
|
||||||
data: new Uint8Array(await state.file.arrayBuffer())
|
// data: new Uint8Array(await state.file.arrayBuffer())
|
||||||
};
|
// };
|
||||||
const service = await Services.getInstance();
|
// const service = await Services.getInstance();
|
||||||
const commitedIn = state.certificate.commited_in;
|
// const commitedIn = state.certificate.commited_in;
|
||||||
if (!commitedIn) return;
|
// if (!commitedIn) return;
|
||||||
const [prevTxid, prevTxVout] = commitedIn.split(':');
|
// const [prevTxid, prevTxVout] = commitedIn.split(':');
|
||||||
const processId = state.certificate.process_id;
|
// const processId = state.certificate.process_id;
|
||||||
const stateId = state.certificate.state_id;
|
// const stateId = state.certificate.state_id;
|
||||||
const process = await service.getProcess(processId);
|
// const process = await service.getProcess(processId);
|
||||||
if (!process) return;
|
// if (!process) return;
|
||||||
|
|
||||||
// Get the transaction that comes right after the commited_in
|
// // Get the transaction that comes right after the commited_in
|
||||||
const nextState = service.getNextStateAfterId(process, stateId);
|
// const nextState = service.getNextStateAfterId(process, stateId);
|
||||||
|
|
||||||
if (!nextState) {
|
// if (!nextState) {
|
||||||
alert(`❌ Validation failed: No next state, is the state you're trying to validate commited?`);
|
// alert(`❌ Validation failed: No next state, is the state you're trying to validate commited?`);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
const [outspentTxId, _] = nextState.commited_in.split(':');
|
// const [outspentTxId, _] = nextState.commited_in.split(':');
|
||||||
console.log(outspentTxId);
|
// console.log(outspentTxId);
|
||||||
|
|
||||||
// Check that the commitment transaction exists, and that it commits to the state id
|
// // Check that the commitment transaction exists, and that it commits to the state id
|
||||||
|
|
||||||
const txInfo = await fetchTransaction(outspentTxId);
|
// const txInfo = await fetchTransaction(outspentTxId);
|
||||||
if (!txInfo) {
|
// if (!txInfo) {
|
||||||
console.error(`Validation error: Can't fetch new state commitment transaction`);
|
// console.error(`Validation error: Can't fetch new state commitment transaction`);
|
||||||
alert(`❌ Validation failed: invalid or non existent commited_in for state ${stateId}.`);
|
// alert(`❌ Validation failed: invalid or non existent commited_in for state ${stateId}.`);
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// We must check that this transaction indeed spend the commited_in we have in the certificate
|
// // We must check that this transaction indeed spend the commited_in we have in the certificate
|
||||||
let found = false;
|
// let found = false;
|
||||||
for (const vin of txInfo.vin) {
|
// for (const vin of txInfo.vin) {
|
||||||
if (vin.txid === prevTxid) {
|
// if (vin.txid === prevTxid) {
|
||||||
found = true;
|
// found = true;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!found) {
|
// if (!found) {
|
||||||
console.error(`Validation error: new state doesn't spend previous state commitment transaction`);
|
// console.error(`Validation error: new state doesn't spend previous state commitment transaction`);
|
||||||
alert('❌ Validation failed: Unconsistent commitment transactions history.');
|
// alert('❌ Validation failed: Unconsistent commitment transactions history.');
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// set found back to false for next check
|
// // set found back to false for next check
|
||||||
found = false;
|
// found = false;
|
||||||
|
|
||||||
// is the state_id commited in the transaction?
|
// // is the state_id commited in the transaction?
|
||||||
for (const vout of txInfo.vout) {
|
// for (const vout of txInfo.vout) {
|
||||||
console.log(vout);
|
// console.log(vout);
|
||||||
if (vout.scriptpubkey_type && vout.scriptpubkey_type === 'op_return') {
|
// if (vout.scriptpubkey_type && vout.scriptpubkey_type === 'op_return') {
|
||||||
found = true;
|
// found = true;
|
||||||
} else {
|
// } else {
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (vout.scriptpubkey_asm) {
|
// if (vout.scriptpubkey_asm) {
|
||||||
const hash = extractHexFromScriptAsm(vout.scriptpubkey_asm);
|
// const hash = extractHexFromScriptAsm(vout.scriptpubkey_asm);
|
||||||
if (hash) {
|
// if (hash) {
|
||||||
if (hash !== stateId) {
|
// if (hash !== stateId) {
|
||||||
console.error(`Validation error: expected stateId ${stateId}, got ${hash}`);
|
// console.error(`Validation error: expected stateId ${stateId}, got ${hash}`);
|
||||||
alert('❌ Validation failed: Transaction does not commit to that state.');
|
// alert('❌ Validation failed: Transaction does not commit to that state.');
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!found) {
|
// if (!found) {
|
||||||
alert('❌ Validation failed: Transaction does not contain data.');
|
// alert('❌ Validation failed: Transaction does not contain data.');
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// set found back to false for next check
|
// // set found back to false for next check
|
||||||
found = false;
|
// found = false;
|
||||||
|
|
||||||
for (const label of Object.keys(state.certificate.pcd_commitment)) {
|
// for (const label of Object.keys(state.certificate.pcd_commitment)) {
|
||||||
// Compute the hash for this label
|
// // Compute the hash for this label
|
||||||
console.log(`Computing hash with label ${label}`)
|
// console.log(`Computing hash with label ${label}`)
|
||||||
const fileHex = service.getHashForFile(commitedIn, label, fileBlob);
|
// const fileHex = service.getHashForFile(commitedIn, label, fileBlob);
|
||||||
console.log(`Found hash ${fileHex}`);
|
// console.log(`Found hash ${fileHex}`);
|
||||||
found = state.commitmentHashes.includes(fileHex);
|
// found = state.commitmentHashes.includes(fileHex);
|
||||||
if (found) break;
|
// if (found) break;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (found) {
|
// if (found) {
|
||||||
alert('✅ Validation successful: file hash found in pcd_commitment.');
|
// alert('✅ Validation successful: file hash found in pcd_commitment.');
|
||||||
} else {
|
// } else {
|
||||||
alert('❌ Validation failed: file hash NOT found in pcd_commitment.');
|
// alert('❌ Validation failed: file hash NOT found in pcd_commitment.');
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
async function fetchTransaction(txid: string): Promise<TransactionInfo> {
|
// async function fetchTransaction(txid: string): Promise<TransactionInfo> {
|
||||||
const url = `https://mempool.4nkweb.com/api/tx/${txid}`;
|
// const url = `https://mempool.4nkweb.com/api/tx/${txid}`;
|
||||||
|
|
||||||
const response = await fetch(url);
|
// const response = await fetch(url);
|
||||||
if (!response.ok) {
|
// if (!response.ok) {
|
||||||
throw new Error(`Failed to fetch outspend status: ${response.statusText}`);
|
// throw new Error(`Failed to fetch outspend status: ${response.statusText}`);
|
||||||
}
|
// }
|
||||||
|
|
||||||
const outspend: TransactionInfo = await response.json();
|
// const outspend: TransactionInfo = await response.json();
|
||||||
return outspend;
|
// return outspend;
|
||||||
}
|
// }
|
||||||
|
|
||||||
function extractHexFromScriptAsm(scriptAsm: string): string | null {
|
// function extractHexFromScriptAsm(scriptAsm: string): string | null {
|
||||||
const parts = scriptAsm.trim().split(/\s+/);
|
// const parts = scriptAsm.trim().split(/\s+/);
|
||||||
const last = parts[parts.length - 1];
|
// const last = parts[parts.length - 1];
|
||||||
|
|
||||||
// Basic validation: must be 64-char hex (32 bytes)
|
// // Basic validation: must be 64-char hex (32 bytes)
|
||||||
if (/^[0-9a-fA-F]{64}$/.test(last)) {
|
// if (/^[0-9a-fA-F]{64}$/.test(last)) {
|
||||||
return last.toLowerCase();
|
// return last.toLowerCase();
|
||||||
}
|
// }
|
||||||
|
|
||||||
return null;
|
// return null;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -1,196 +1,196 @@
|
|||||||
import { ValidationRule, RoleDefinition } from '../../../pkg/sdk_client';
|
// import { ValidationRule, RoleDefinition } from '../../../pkg/sdk_client';
|
||||||
import { showValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
|
// import { showValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
|
||||||
|
|
||||||
export function createKeyValueSection(title: string, id: string, isRoleSection = false) {
|
// export function createKeyValueSection(title: string, id: string, isRoleSection = false) {
|
||||||
const section = document.createElement('div');
|
// const section = document.createElement('div');
|
||||||
section.id = id;
|
// section.id = id;
|
||||||
section.style.cssText = 'margin-bottom: 2rem; background: #fff; padding: 1rem; border-radius: 0.5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1);';
|
// section.style.cssText = 'margin-bottom: 2rem; background: #fff; padding: 1rem; border-radius: 0.5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1);';
|
||||||
|
|
||||||
const titleEl = document.createElement('h2');
|
// const titleEl = document.createElement('h2');
|
||||||
titleEl.textContent = title;
|
// titleEl.textContent = title;
|
||||||
titleEl.style.cssText = 'font-size: 1.25rem; font-weight: bold; margin-bottom: 1rem;';
|
// titleEl.style.cssText = 'font-size: 1.25rem; font-weight: bold; margin-bottom: 1rem;';
|
||||||
section.appendChild(titleEl);
|
// section.appendChild(titleEl);
|
||||||
|
|
||||||
const rowContainer = document.createElement('div');
|
// const rowContainer = document.createElement('div');
|
||||||
section.appendChild(rowContainer);
|
// section.appendChild(rowContainer);
|
||||||
|
|
||||||
const addBtn = document.createElement('button');
|
// const addBtn = document.createElement('button');
|
||||||
addBtn.textContent = '+ Add Row';
|
// addBtn.textContent = '+ Add Row';
|
||||||
addBtn.style.cssText = `
|
// addBtn.style.cssText = `
|
||||||
margin-top: 1rem;
|
// margin-top: 1rem;
|
||||||
padding: 0.5rem 1rem;
|
// padding: 0.5rem 1rem;
|
||||||
border: 1px solid #888;
|
// border: 1px solid #888;
|
||||||
border-radius: 0.375rem;
|
// border-radius: 0.375rem;
|
||||||
background-color: #f9f9f9;
|
// background-color: #f9f9f9;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
`;
|
// `;
|
||||||
section.appendChild(addBtn);
|
// section.appendChild(addBtn);
|
||||||
|
|
||||||
const roleRowStates: {
|
// const roleRowStates: {
|
||||||
roleNameInput: HTMLInputElement;
|
// roleNameInput: HTMLInputElement;
|
||||||
membersInput: HTMLInputElement;
|
// membersInput: HTMLInputElement;
|
||||||
storagesInput: HTMLInputElement;
|
// storagesInput: HTMLInputElement;
|
||||||
validationRules: ValidationRule[];
|
// validationRules: ValidationRule[];
|
||||||
}[] = [];
|
// }[] = [];
|
||||||
type fileBlob = {
|
// type fileBlob = {
|
||||||
type: string,
|
// type: string,
|
||||||
data: Uint8Array
|
// data: Uint8Array
|
||||||
};
|
// };
|
||||||
const nonRoleRowStates: {
|
// const nonRoleRowStates: {
|
||||||
keyInput: HTMLInputElement,
|
// keyInput: HTMLInputElement,
|
||||||
valueInput: HTMLInputElement,
|
// valueInput: HTMLInputElement,
|
||||||
fileInput: HTMLInputElement,
|
// fileInput: HTMLInputElement,
|
||||||
fileBlob: fileBlob | null
|
// fileBlob: fileBlob | null
|
||||||
}[] = [];
|
// }[] = [];
|
||||||
|
|
||||||
const inputStyle = 'flex: 1; height: 2.5rem; padding: 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem;';
|
// const inputStyle = 'flex: 1; height: 2.5rem; padding: 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem;';
|
||||||
|
|
||||||
const createRow = () => {
|
// const createRow = () => {
|
||||||
const row = document.createElement('div');
|
// const row = document.createElement('div');
|
||||||
row.style.cssText = 'display: flex; gap: 1rem; margin-bottom: 0.5rem; align-items: center;';
|
// row.style.cssText = 'display: flex; gap: 1rem; margin-bottom: 0.5rem; align-items: center;';
|
||||||
|
|
||||||
const deleteBtn = document.createElement('button');
|
// const deleteBtn = document.createElement('button');
|
||||||
deleteBtn.textContent = '🗑️';
|
// deleteBtn.textContent = '🗑️';
|
||||||
deleteBtn.style.cssText = 'background: none; border: none; font-size: 1.2rem; cursor: pointer;';
|
// deleteBtn.style.cssText = 'background: none; border: none; font-size: 1.2rem; cursor: pointer;';
|
||||||
deleteBtn.onclick = () => {
|
// deleteBtn.onclick = () => {
|
||||||
row.remove();
|
// row.remove();
|
||||||
updateDeleteButtons();
|
// updateDeleteButtons();
|
||||||
};
|
// };
|
||||||
|
|
||||||
if (isRoleSection) {
|
// if (isRoleSection) {
|
||||||
const roleName = document.createElement('input');
|
// const roleName = document.createElement('input');
|
||||||
const members = document.createElement('input');
|
// const members = document.createElement('input');
|
||||||
const storages = document.createElement('input');
|
// const storages = document.createElement('input');
|
||||||
|
|
||||||
roleName.placeholder = 'Role name';
|
// roleName.placeholder = 'Role name';
|
||||||
members.placeholder = 'members';
|
// members.placeholder = 'members';
|
||||||
storages.placeholder = 'storages';
|
// storages.placeholder = 'storages';
|
||||||
[roleName, members, storages].forEach(input => {
|
// [roleName, members, storages].forEach(input => {
|
||||||
input.type = 'text';
|
// input.type = 'text';
|
||||||
input.style.cssText = inputStyle;
|
// input.style.cssText = inputStyle;
|
||||||
});
|
// });
|
||||||
|
|
||||||
const ruleButton = document.createElement('button');
|
// const ruleButton = document.createElement('button');
|
||||||
ruleButton.textContent = 'Add Validation Rule';
|
// ruleButton.textContent = 'Add Validation Rule';
|
||||||
ruleButton.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
|
// ruleButton.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
|
||||||
|
|
||||||
const rules: ValidationRule[] = [];
|
// const rules: ValidationRule[] = [];
|
||||||
ruleButton.onclick = () => {
|
// ruleButton.onclick = () => {
|
||||||
showValidationRuleModal(rule => {
|
// showValidationRuleModal(rule => {
|
||||||
rules.push(rule);
|
// rules.push(rule);
|
||||||
ruleButton.textContent = `Rules (${rules.length})`;
|
// ruleButton.textContent = `Rules (${rules.length})`;
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
row.appendChild(roleName);
|
// row.appendChild(roleName);
|
||||||
row.appendChild(members);
|
// row.appendChild(members);
|
||||||
row.appendChild(storages);
|
// row.appendChild(storages);
|
||||||
row.appendChild(ruleButton);
|
// row.appendChild(ruleButton);
|
||||||
row.appendChild(deleteBtn);
|
// row.appendChild(deleteBtn);
|
||||||
|
|
||||||
roleRowStates.push({ roleNameInput: roleName, membersInput: members, storagesInput: storages, validationRules: rules });
|
// roleRowStates.push({ roleNameInput: roleName, membersInput: members, storagesInput: storages, validationRules: rules });
|
||||||
} else {
|
// } else {
|
||||||
const fileInput = document.createElement('input');
|
// const fileInput = document.createElement('input');
|
||||||
fileInput.type = 'file';
|
// fileInput.type = 'file';
|
||||||
fileInput.style.display = 'none';
|
// fileInput.style.display = 'none';
|
||||||
fileInput.onchange = async () => {
|
// fileInput.onchange = async () => {
|
||||||
const file = fileInput.files?.[0];
|
// const file = fileInput.files?.[0];
|
||||||
if (!file) return;
|
// if (!file) return;
|
||||||
|
|
||||||
const buffer = await file.arrayBuffer();
|
// const buffer = await file.arrayBuffer();
|
||||||
const uint8 = new Uint8Array(buffer);
|
// const uint8 = new Uint8Array(buffer);
|
||||||
|
|
||||||
rowState.fileBlob = {
|
// rowState.fileBlob = {
|
||||||
type: file.type,
|
// type: file.type,
|
||||||
data: uint8,
|
// data: uint8,
|
||||||
};
|
// };
|
||||||
|
|
||||||
valueInput.value = `📄 ${file.name}`;
|
// valueInput.value = `📄 ${file.name}`;
|
||||||
valueInput.disabled = true;
|
// valueInput.disabled = true;
|
||||||
attachBtn.textContent = `📎 ${file.name}`;
|
// attachBtn.textContent = `📎 ${file.name}`;
|
||||||
};
|
// };
|
||||||
|
|
||||||
const attachBtn = document.createElement('button');
|
// const attachBtn = document.createElement('button');
|
||||||
attachBtn.textContent = '📎 Attach';
|
// attachBtn.textContent = '📎 Attach';
|
||||||
attachBtn.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
|
// attachBtn.style.cssText = 'padding: 0.3rem 0.75rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
|
||||||
attachBtn.onclick = () => fileInput.click();
|
// attachBtn.onclick = () => fileInput.click();
|
||||||
|
|
||||||
const keyInput = document.createElement('input');
|
// const keyInput = document.createElement('input');
|
||||||
const valueInput = document.createElement('input');
|
// const valueInput = document.createElement('input');
|
||||||
|
|
||||||
const rowState = {
|
// const rowState = {
|
||||||
keyInput,
|
// keyInput,
|
||||||
valueInput,
|
// valueInput,
|
||||||
fileInput,
|
// fileInput,
|
||||||
fileBlob: null as fileBlob | null
|
// fileBlob: null as fileBlob | null
|
||||||
};
|
// };
|
||||||
nonRoleRowStates.push(rowState);
|
// nonRoleRowStates.push(rowState);
|
||||||
|
|
||||||
keyInput.placeholder = 'Key';
|
// keyInput.placeholder = 'Key';
|
||||||
valueInput.placeholder = 'Value';
|
// valueInput.placeholder = 'Value';
|
||||||
[keyInput, valueInput].forEach(input => {
|
// [keyInput, valueInput].forEach(input => {
|
||||||
input.type = 'text';
|
// input.type = 'text';
|
||||||
input.style.cssText = inputStyle;
|
// input.style.cssText = inputStyle;
|
||||||
});
|
// });
|
||||||
|
|
||||||
row.appendChild(keyInput);
|
// row.appendChild(keyInput);
|
||||||
row.appendChild(valueInput);
|
// row.appendChild(valueInput);
|
||||||
|
|
||||||
row.appendChild(attachBtn);
|
// row.appendChild(attachBtn);
|
||||||
row.appendChild(fileInput);
|
// row.appendChild(fileInput);
|
||||||
|
|
||||||
row.appendChild(deleteBtn);
|
// row.appendChild(deleteBtn);
|
||||||
}
|
// }
|
||||||
|
|
||||||
rowContainer.appendChild(row);
|
// rowContainer.appendChild(row);
|
||||||
updateDeleteButtons();
|
// updateDeleteButtons();
|
||||||
};
|
// };
|
||||||
|
|
||||||
const updateDeleteButtons = () => {
|
// const updateDeleteButtons = () => {
|
||||||
const rows = Array.from(rowContainer.children);
|
// const rows = Array.from(rowContainer.children);
|
||||||
rows.forEach(row => {
|
// rows.forEach(row => {
|
||||||
const btn = row.querySelector('button:last-child') as HTMLButtonElement;
|
// const btn = row.querySelector('button:last-child') as HTMLButtonElement;
|
||||||
if (rows.length === 1) {
|
// if (rows.length === 1) {
|
||||||
btn.disabled = true;
|
// btn.disabled = true;
|
||||||
btn.style.visibility = 'hidden';
|
// btn.style.visibility = 'hidden';
|
||||||
} else {
|
// } else {
|
||||||
btn.disabled = false;
|
// btn.disabled = false;
|
||||||
btn.style.visibility = 'visible';
|
// btn.style.visibility = 'visible';
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
|
|
||||||
createRow();
|
// createRow();
|
||||||
addBtn.addEventListener('click', createRow);
|
// addBtn.addEventListener('click', createRow);
|
||||||
|
|
||||||
return {
|
// return {
|
||||||
element: section,
|
// element: section,
|
||||||
getData: () => {
|
// getData: () => {
|
||||||
if (isRoleSection) {
|
// if (isRoleSection) {
|
||||||
const data: Record<string, RoleDefinition> = {};
|
// const data: Record<string, RoleDefinition> = {};
|
||||||
for (const row of roleRowStates) {
|
// for (const row of roleRowStates) {
|
||||||
const key = row.roleNameInput.value.trim();
|
// const key = row.roleNameInput.value.trim();
|
||||||
if (!key) continue;
|
// if (!key) continue;
|
||||||
data[key] = {
|
// data[key] = {
|
||||||
members: row.membersInput.value.split(',').map(x => x.trim()).filter(Boolean),
|
// members: row.membersInput.value.split(',').map(x => x.trim()).filter(Boolean),
|
||||||
storages: row.storagesInput.value.split(',').map(x => x.trim()).filter(Boolean),
|
// storages: row.storagesInput.value.split(',').map(x => x.trim()).filter(Boolean),
|
||||||
validation_rules: row.validationRules
|
// validation_rules: row.validationRules
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
return data;
|
// return data;
|
||||||
} else {
|
// } else {
|
||||||
const data: Record<string, string | fileBlob> = {};
|
// const data: Record<string, string | fileBlob> = {};
|
||||||
for (const row of nonRoleRowStates) {
|
// for (const row of nonRoleRowStates) {
|
||||||
const key = row.keyInput.value.trim();
|
// const key = row.keyInput.value.trim();
|
||||||
if (!key) continue;
|
// if (!key) continue;
|
||||||
if (row.fileBlob) {
|
// if (row.fileBlob) {
|
||||||
data[key] = row.fileBlob;
|
// data[key] = row.fileBlob;
|
||||||
} else {
|
// } else {
|
||||||
data[key] = row.valueInput.value.trim();
|
// data[key] = row.valueInput.value.trim();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return data;
|
// return data;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -1,91 +1,91 @@
|
|||||||
import { createKeyValueSection } from './key-value-section';
|
// import { createKeyValueSection } from './key-value-section';
|
||||||
import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
|
// import { loadValidationRuleModal } from '../../components/validation-rule-modal/validation-rule-modal';
|
||||||
import Services from '../../services/service';
|
// import Services from '../../services/service';
|
||||||
import { RoleDefinition } from '../../../pkg/sdk_client';
|
// import { RoleDefinition } from '../../../pkg/sdk_client';
|
||||||
|
|
||||||
export async function getProcessCreation(container: HTMLElement) {
|
// export async function getProcessCreation(container: HTMLElement) {
|
||||||
await loadValidationRuleModal();
|
// await loadValidationRuleModal();
|
||||||
|
|
||||||
container.style.display = 'block';
|
// container.style.display = 'block';
|
||||||
container.innerHTML = `<div class="parameter-header">Process Creation</div>`;
|
// container.innerHTML = `<div class="parameter-header">Process Creation</div>`;
|
||||||
const privateSec = createKeyValueSection('Private Data', 'private-section');
|
// const privateSec = createKeyValueSection('Private Data', 'private-section');
|
||||||
const publicSec = createKeyValueSection('Public Data', 'public-section');
|
// const publicSec = createKeyValueSection('Public Data', 'public-section');
|
||||||
const rolesSec = createKeyValueSection('Roles', 'roles-section', true);
|
// const rolesSec = createKeyValueSection('Roles', 'roles-section', true);
|
||||||
|
|
||||||
container.appendChild(privateSec.element);
|
// container.appendChild(privateSec.element);
|
||||||
container.appendChild(publicSec.element);
|
// container.appendChild(publicSec.element);
|
||||||
container.appendChild(rolesSec.element);
|
// container.appendChild(rolesSec.element);
|
||||||
|
|
||||||
const btn = document.createElement('button');
|
// const btn = document.createElement('button');
|
||||||
btn.textContent = 'Create Process';
|
// btn.textContent = 'Create Process';
|
||||||
btn.style.cssText = `
|
// btn.style.cssText = `
|
||||||
display: block;
|
// display: block;
|
||||||
margin: 2rem auto 0;
|
// margin: 2rem auto 0;
|
||||||
padding: 0.75rem 2rem;
|
// padding: 0.75rem 2rem;
|
||||||
font-size: 1rem;
|
// font-size: 1rem;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
background-color: #4f46e5;
|
// background-color: #4f46e5;
|
||||||
color: white;
|
// color: white;
|
||||||
border: none;
|
// border: none;
|
||||||
border-radius: 0.5rem;
|
// border-radius: 0.5rem;
|
||||||
cursor: pointer;
|
// cursor: pointer;
|
||||||
`;
|
// `;
|
||||||
|
|
||||||
btn.onclick = async () => {
|
// btn.onclick = async () => {
|
||||||
const privateData = privateSec.getData();
|
// const privateData = privateSec.getData();
|
||||||
const publicData = publicSec.getData();
|
// const publicData = publicSec.getData();
|
||||||
const roles = rolesSec.getData() as Record<string, RoleDefinition>;
|
// const roles = rolesSec.getData() as Record<string, RoleDefinition>;
|
||||||
|
|
||||||
console.log('Private:', privateData);
|
// console.log('Private:', privateData);
|
||||||
console.log('Public:', publicData);
|
// console.log('Public:', publicData);
|
||||||
console.log('Roles:', roles);
|
// console.log('Roles:', roles);
|
||||||
|
|
||||||
const service = await Services.getInstance();
|
// const service = await Services.getInstance();
|
||||||
|
|
||||||
const createProcessResult = await service.createProcess(privateData, publicData, roles);
|
// const createProcessResult = await service.createProcess(privateData, publicData, roles);
|
||||||
const processId = createProcessResult.updated_process!.process_id;
|
// const processId = createProcessResult.updated_process!.process_id;
|
||||||
const stateId = createProcessResult.updated_process!.current_process.states[0].state_id;
|
// const stateId = createProcessResult.updated_process!.current_process.states[0].state_id;
|
||||||
await service.handleApiReturn(createProcessResult);
|
// await service.handleApiReturn(createProcessResult);
|
||||||
|
|
||||||
// Now we want to validate the update and register the first state of our new process
|
// // Now we want to validate the update and register the first state of our new process
|
||||||
const updateProcessResult = await service.createPrdUpdate(processId, stateId);
|
// const updateProcessResult = await service.createPrdUpdate(processId, stateId);
|
||||||
await service.handleApiReturn(createProcessResult);
|
// await service.handleApiReturn(createProcessResult);
|
||||||
|
|
||||||
const approveChangeResult = await service.approveChange(processId, stateId);
|
// const approveChangeResult = await service.approveChange(processId, stateId);
|
||||||
await service.handleApiReturn(approveChangeResult);
|
// await service.handleApiReturn(approveChangeResult);
|
||||||
if (approveChangeResult) {
|
// if (approveChangeResult) {
|
||||||
const process = await service.getProcess(processId);
|
// const process = await service.getProcess(processId);
|
||||||
let newState = service.getStateFromId(process, stateId);
|
// let newState = service.getStateFromId(process, stateId);
|
||||||
if (!newState) return;
|
// if (!newState) return;
|
||||||
for (const label of Object.keys(newState.keys)) {
|
// for (const label of Object.keys(newState.keys)) {
|
||||||
const hash = newState.pcd_commitment[label];
|
// const hash = newState.pcd_commitment[label];
|
||||||
const encryptedData = await service.getBlobFromDb(hash);
|
// const encryptedData = await service.getBlobFromDb(hash);
|
||||||
const filename = `${label}-${hash.slice(0,8)}.bin`;
|
// const filename = `${label}-${hash.slice(0,8)}.bin`;
|
||||||
|
|
||||||
const blob = new Blob([encryptedData], { type: "application/octet-stream" });
|
// const blob = new Blob([encryptedData], { type: "application/octet-stream" });
|
||||||
const link = document.createElement("a");
|
// const link = document.createElement("a");
|
||||||
link.href = URL.createObjectURL(blob);
|
// link.href = URL.createObjectURL(blob);
|
||||||
link.download = filename;
|
// link.download = filename;
|
||||||
link.click();
|
// link.click();
|
||||||
|
|
||||||
setTimeout(() => URL.revokeObjectURL(link.href), 1000);
|
// setTimeout(() => URL.revokeObjectURL(link.href), 1000);
|
||||||
}
|
// }
|
||||||
|
|
||||||
await service.generateProcessPdf(processId, newState);
|
// await service.generateProcessPdf(processId, newState);
|
||||||
|
|
||||||
// Add processId to the state we export
|
// // Add processId to the state we export
|
||||||
newState['process_id'] = processId;
|
// newState['process_id'] = processId;
|
||||||
const blob = new Blob([JSON.stringify(newState, null, 2)], { type: 'application/json' });
|
// const blob = new Blob([JSON.stringify(newState, null, 2)], { type: 'application/json' });
|
||||||
const url = URL.createObjectURL(blob);
|
// const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
const a = document.createElement('a');
|
// const a = document.createElement('a');
|
||||||
a.href = url;
|
// a.href = url;
|
||||||
a.download = `process_${processId}_${stateId}.json`;
|
// a.download = `process_${processId}_${stateId}.json`;
|
||||||
a.click();
|
// a.click();
|
||||||
|
|
||||||
URL.revokeObjectURL(url); // Clean up
|
// URL.revokeObjectURL(url); // Clean up
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
|
|
||||||
container.appendChild(btn);
|
// container.appendChild(btn);
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -1,66 +1,66 @@
|
|||||||
export function createProcessTab(container: HTMLElement, processes: { name: string, publicData: Record<string, any> }[]): HTMLElement {
|
// export function createProcessTab(container: HTMLElement, processes: { name: string, publicData: Record<string, any> }[]): HTMLElement {
|
||||||
container.id = 'process-tab';
|
// container.id = 'process-tab';
|
||||||
container.style.display = 'block';
|
// container.style.display = 'block';
|
||||||
container.style.cssText = 'padding: 1.5rem;';
|
// container.style.cssText = 'padding: 1.5rem;';
|
||||||
|
|
||||||
const title = document.createElement('h2');
|
// const title = document.createElement('h2');
|
||||||
title.textContent = 'Processes';
|
// title.textContent = 'Processes';
|
||||||
title.style.cssText = 'font-size: 1.5rem; font-weight: bold; margin-bottom: 1rem;';
|
// title.style.cssText = 'font-size: 1.5rem; font-weight: bold; margin-bottom: 1rem;';
|
||||||
container.appendChild(title);
|
// container.appendChild(title);
|
||||||
|
|
||||||
processes.forEach(proc => {
|
// processes.forEach(proc => {
|
||||||
const card = document.createElement('div');
|
// const card = document.createElement('div');
|
||||||
card.style.cssText = 'margin-bottom: 1rem; padding: 1rem; border: 1px solid #ddd; border-radius: 0.5rem; background: #fff;';
|
// card.style.cssText = 'margin-bottom: 1rem; padding: 1rem; border: 1px solid #ddd; border-radius: 0.5rem; background: #fff;';
|
||||||
|
|
||||||
const nameEl = document.createElement('h3');
|
// const nameEl = document.createElement('h3');
|
||||||
nameEl.textContent = proc.name;
|
// nameEl.textContent = proc.name;
|
||||||
nameEl.style.cssText = 'font-size: 1.2rem; font-weight: bold; margin-bottom: 0.5rem;';
|
// nameEl.style.cssText = 'font-size: 1.2rem; font-weight: bold; margin-bottom: 0.5rem;';
|
||||||
card.appendChild(nameEl);
|
// card.appendChild(nameEl);
|
||||||
|
|
||||||
const dataList = document.createElement('div');
|
// const dataList = document.createElement('div');
|
||||||
for (const [key, value] of Object.entries(proc.publicData)) {
|
// for (const [key, value] of Object.entries(proc.publicData)) {
|
||||||
const item = document.createElement('div');
|
// const item = document.createElement('div');
|
||||||
item.style.cssText = 'margin-bottom: 0.5rem;';
|
// item.style.cssText = 'margin-bottom: 0.5rem;';
|
||||||
|
|
||||||
const label = document.createElement('strong');
|
// const label = document.createElement('strong');
|
||||||
label.textContent = key + ': ';
|
// label.textContent = key + ': ';
|
||||||
item.appendChild(label);
|
// item.appendChild(label);
|
||||||
|
|
||||||
// Let's trim the quotes
|
// // Let's trim the quotes
|
||||||
const trimmed = value.replace(/^'|'$/g, '');
|
// const trimmed = value.replace(/^'|'$/g, '');
|
||||||
let parsed;
|
// let parsed;
|
||||||
try {
|
// try {
|
||||||
parsed = JSON.parse(trimmed);
|
// parsed = JSON.parse(trimmed);
|
||||||
} catch (_) {
|
// } catch (_) {
|
||||||
parsed = trimmed;
|
// parsed = trimmed;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (parsed && typeof parsed === 'object') {
|
// if (parsed && typeof parsed === 'object') {
|
||||||
const saveBtn = document.createElement('button');
|
// const saveBtn = document.createElement('button');
|
||||||
saveBtn.textContent = '💾 Save as JSON';
|
// saveBtn.textContent = '💾 Save as JSON';
|
||||||
saveBtn.style.cssText = 'margin-left: 0.5rem; padding: 0.25rem 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
|
// saveBtn.style.cssText = 'margin-left: 0.5rem; padding: 0.25rem 0.5rem; border: 1px solid #ccc; border-radius: 0.375rem; background: #f0f0f0; cursor: pointer;';
|
||||||
saveBtn.onclick = () => {
|
// saveBtn.onclick = () => {
|
||||||
const blob = new Blob([JSON.stringify(parsed, null, 2)], { type: 'application/json' });
|
// const blob = new Blob([JSON.stringify(parsed, null, 2)], { type: 'application/json' });
|
||||||
const url = URL.createObjectURL(blob);
|
// const url = URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
// const a = document.createElement('a');
|
||||||
a.href = url;
|
// a.href = url;
|
||||||
a.download = `${proc.name}_${key}.json`;
|
// a.download = `${proc.name}_${key}.json`;
|
||||||
a.click();
|
// a.click();
|
||||||
URL.revokeObjectURL(url);
|
// URL.revokeObjectURL(url);
|
||||||
};
|
// };
|
||||||
item.appendChild(saveBtn);
|
// item.appendChild(saveBtn);
|
||||||
} else {
|
// } else {
|
||||||
const span = document.createElement('span');
|
// const span = document.createElement('span');
|
||||||
span.textContent = String(parsed);
|
// span.textContent = String(parsed);
|
||||||
item.appendChild(span);
|
// item.appendChild(span);
|
||||||
}
|
// }
|
||||||
|
|
||||||
dataList.appendChild(item);
|
// dataList.appendChild(item);
|
||||||
}
|
// }
|
||||||
|
|
||||||
card.appendChild(dataList);
|
// card.appendChild(dataList);
|
||||||
container.appendChild(card);
|
// container.appendChild(card);
|
||||||
});
|
// });
|
||||||
|
|
||||||
return container;
|
// return container;
|
||||||
}
|
// }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user