Skip to content

Feat/viewer AdaPot, Gov state, epoch stake pages #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
scripts/scala/*.sc
/docs/node_modules/
/docs/.next
/docs/out
.idea
logs
applications/store-build/tmp
2 changes: 1 addition & 1 deletion applications/cli/config/download.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#Please specify either the version or the full url for the following components
node.version=10.1.4
node.version=10.2.1
ogmios.version=6.11.2
kupo.version=2.10.0
yaci.store.version=0.2.0-graal-preview1
Expand Down
4 changes: 2 additions & 2 deletions applications/cli/config/node.properties
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,5 @@
# So, the shiftStartTimeBehind flag should be "false" for non-development / multi-node networks.
#
#########################################################################################################
conwayHardForkAtEpoch=1
shiftStartTimeBehind=true
#conwayHardForkAtEpoch=1
#shiftStartTimeBehind=true
Original file line number Diff line number Diff line change
Expand Up @@ -411,15 +411,15 @@ private void updateSubmitApiFiles(Path destPath, long protocolMagic, int submitA
}

private void updateConfiguration(Path clusterFolder, ClusterInfo clusterInfo, Consumer<String> writer) throws IOException {
Path configurationPath = clusterFolder.resolve("templates").resolve("configuration.yaml");
Path configurationPath = clusterFolder.resolve("templates").resolve("configuration.json");
// if (clusterInfo.getEra() == null || clusterInfo.getEra() == Era.Babbage) {
// configurationPath = clusterFolder.resolve("configuration.yaml");
// } else if (clusterInfo.getEra() == Era.Conway) {
// writer.accept(success("Updating configuration.yaml for conway era"));
// configurationPath = clusterFolder.resolve("configuration.yaml.conway");
// }

Path destConfigPath = clusterFolder.resolve("node").resolve("configuration.yaml");
Path destConfigPath = clusterFolder.resolve("node").resolve("configuration.json");
boolean enableP2P = clusterInfo.isP2pEnabled();

var genesisConfigCopy = genesisConfig.copy();
Expand All @@ -438,7 +438,7 @@ private void updateConfiguration(Path clusterFolder, ClusterInfo clusterInfo, Co
throw new IOException(e);
}

writer.accept(success("Updated configuration.yaml"));
writer.accept(success("Updated configuration.json"));
}

public ClusterInfo getClusterInfo(String clusterName) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,17 @@
10,
43574283,
26308,
10
10,
9999999999999,
9999999999999,
9999999999999,
9999999999999,
9999999999999,
9999999999999,
9999999999999,
9999999999999,
9999999999999,
9999999999999
]
},
"executionPrices": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -e

${BIN_FOLDER}/cardano-node run \
--config configuration.yaml \
--config configuration.json \
--topology topology.json \
--database-path db \
--socket-path node.sock \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

set -e

${OGMIOS_BIN} --node-socket node/node.sock --node-config node/configuration.yaml --host 0.0.0.0 --port ${OGMIOS_PORT}
${OGMIOS_BIN} --node-socket node/node.sock --node-config node/configuration.json --host 0.0.0.0 --port ${OGMIOS_PORT}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{BIN_FOLDER}}/cardano-node run \
--config configuration.yaml \
--config configuration.json \
--topology topology.json \
--database-path db \
--socket-path node.sock \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{BIN_FOLDER}}/cardano-node run \
--config configuration.yaml \
--config configuration.json \
--topology topology.json \
--database-path db \
--socket-path node.sock \
Expand Down
43 changes: 37 additions & 6 deletions applications/viewer/src/components/AmountBadges.svelte
Original file line number Diff line number Diff line change
@@ -1,23 +1,54 @@
<script>
<script lang="ts">
import {lovelaceToAda} from "../util/ada_util.js";
import {CopyIcon} from "svelte-feather-icons";

export let amounts = []
interface Amount {
asset_name: string;
quantity: string;
}

export let amounts: Amount[] = [];

const colors = ['badge-neutral', 'badge-primary', 'badge-secondary', 'badge-accent', 'badge-ghost']
const colors = ['badge-neutral', 'badge-primary', 'badge-secondary', 'badge-accent', 'badge-ghost'];

function random_color() {
return colors[Math.floor(Math.random() * colors.length)];
}

function truncateAssetName(name: string, maxLength: number = 20): string {
if (name.length <= maxLength) return name;
return name.substring(0, maxLength) + '...';
}

async function copyToClipboard(text: string) {
try {
await navigator.clipboard.writeText(text);
} catch (err) {
console.error('Failed to copy text: ', err);
}
}
</script>

{#if amounts}
{#each amounts as amount}
{#if amount.asset_name === 'lovelace'}
<span class="badge badge-red">{lovelaceToAda(amount.quantity)} Ada</span>
{:else}
<span class="badge {random_color()}">
{amount.quantity} {amount.asset_name}
</span>
<div class="badge {random_color()} flex items-center gap-1">
<span>{amount.quantity}</span>
<div class="flex items-center gap-1">
<span class="tooltip" data-tip={amount.asset_name}>
{truncateAssetName(amount.asset_name)}
</span>
<button
class="text-gray-400 hover:text-gray-600"
on:click={() => copyToClipboard(amount.asset_name)}
title="Copy asset name"
>
<CopyIcon class="h-3 w-3"/>
</button>
</div>
</div>
{/if}
{/each}
{/if}
196 changes: 167 additions & 29 deletions applications/viewer/src/components/Contract.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script>
<script lang="ts">
import { onMount } from 'svelte';
export let contract;
export let index: number = 0;

let textareaprops = {
id: 'message',
Expand All @@ -9,7 +11,18 @@
placeholder: 'Leave a comment...',
};

function formatRedeemer(redeemer) {
let showToast = false;
let toastMessage = '';
let toastTimeout: number;

interface Redeemer {
tag: string;
index: number;
data?: string;
ex_units?: any;
}

function formatRedeemer(redeemer: Redeemer | string): string {
if (redeemer && typeof redeemer === 'object') {
const { tag, index, data, ex_units } = redeemer;
const formattedData = data ? `"${data}"` : '';
Expand All @@ -19,50 +32,175 @@
return JSON.stringify(redeemer);
}

async function copyToClipboard(text: string, message: string): Promise<void> {
try {
await navigator.clipboard.writeText(text);
showToast = true;
toastMessage = message;
// Clear any existing timeout
if (toastTimeout) {
clearTimeout(toastTimeout);
}
// Hide toast after 2 seconds
toastTimeout = setTimeout(() => {
showToast = false;
}, 2000);
} catch (err) {
console.error('Failed to copy text: ', err);
}
}

// Cleanup timeout on component destroy
onMount(() => {
return () => {
if (toastTimeout) {
clearTimeout(toastTimeout);
}
};
});
</script>

<div class="p-4 w-full">
<div class="flex flex-col mt-4 md:flex-row md:items-start">
<div class="md:w-32 md:mb-0 mb-6 flex-shrink-0">
<span class="font-semibold title-font text-gray-700">Contract</span>
<!-- Toast Notification -->
{#if showToast}
<div class="fixed top-4 right-4 bg-green-500 text-white px-4 py-2 rounded shadow-lg z-50 transition-opacity duration-300">
{toastMessage}
</div>
<div class="md:ml-2 break-words">
<div class="whitespace-normal md:whitespace-pre-line">{contract.script_hash}&nbsp;&nbsp;({contract.type})</div>
{/if}

<!-- Contract Section -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
<div class="flex flex-col">
<div class="text-sm font-medium text-gray-500 mb-2">Contract {index + 1}</div>
<div class="flex items-center gap-2">
<div class="text-sm text-gray-900 break-all">{contract.script_hash}</div>
<span class="text-sm text-gray-500">({contract.type})</span>
</div>
</div>
</div>
<div class="flex flex-col mt-4 md:flex-row md:items-center">
<div class="md:w-32 md:mb-0 mb-6 flex-shrink-0">
<span class="font-semibold title-font text-gray-700">Redeemer</span>

<!-- Redeemer Section -->
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
<div class="flex flex-col">
<div class="text-sm font-medium text-gray-500 mb-2">Redeemer</div>
{#if contract.redeemer && typeof contract.redeemer === 'object'}
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="flex flex-col">
<span class="text-xs text-gray-500">Tag</span>
<span class="text-sm text-gray-900">{contract.redeemer.tag}</span>
</div>
<div class="flex flex-col">
<span class="text-xs text-gray-500">Index</span>
<span class="text-sm text-gray-900">{contract.redeemer.index}</span>
</div>
{#if contract.redeemer.data}
<div class="flex flex-col">
<span class="text-xs text-gray-500">Data</span>
<span class="text-sm text-gray-900 break-all">{contract.redeemer.data}</span>
</div>
{/if}
{#if contract.redeemer.ex_units}
<div class="grid grid-cols-2 gap-4">
<div class="flex flex-col">
<span class="text-xs text-gray-500">Memory</span>
<span class="text-sm text-gray-900">{contract.redeemer.ex_units.mem.toLocaleString()}</span>
</div>
<div class="flex flex-col">
<span class="text-xs text-gray-500">Steps</span>
<span class="text-sm text-gray-900">{contract.redeemer.ex_units.steps.toLocaleString()}</span>
</div>
</div>
{/if}
</div>
{:else}
<div class="text-sm text-gray-900 break-all">{formatRedeemer(contract.redeemer)}</div>
{/if}
</div>
<span class="md:ml-2 break-all">{formatRedeemer(contract.redeemer)}</span>
</div>

<!-- Datum Hash Section -->
{#if contract.datum_hash}
<div class="flex flex-col mt-4 md:flex-row md:items-start">
<div class="md:w-32 md:mb-0 mb-6 flex-shrink-0">
<span class="font-semibold title-font text-gray-700">Datum Hash</span>
</div>
<div class="md:ml-2 break-words">
<div class="whitespace-normal md:whitespace-pre-line">{contract.datum_hash}</div>
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
<div class="flex flex-col">
<div class="text-sm font-medium text-gray-500 mb-2">Datum Hash</div>
<div class="flex items-start gap-2">
<div class="text-sm text-gray-900 break-all flex-grow">{contract.datum_hash}</div>
<button
class="text-gray-400 hover:text-gray-600 flex-shrink-0"
on:click={() => copyToClipboard(contract.datum_hash, 'Datum Hash copied to clipboard')}
title="Copy datum hash"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
</svg>
</button>
</div>
</div>
</div>
{/if}

<!-- Datum Section -->
{#if contract.datum}
<div class="flex flex-col mt-4 md:flex-row md:items-start">
<div class="md:w-32 md:mb-0 mb-6 flex-shrink-0">
<span class="font-semibold title-font text-gray-700">Datum</span>
</div>
<div class="md:ml-2 break-words">
<div class="whitespace-normal md:whitespace-pre-line">{contract.datum}</div>
<div class="bg-white rounded-lg shadow-sm p-4 mb-4">
<div class="flex flex-col">
<div class="text-sm font-medium text-gray-500 mb-2">Datum</div>
<div class="flex items-start gap-2">
<div class="text-sm text-gray-900 break-all flex-grow">{contract.datum}</div>
<button
class="text-gray-400 hover:text-gray-600 flex-shrink-0"
on:click={() => copyToClipboard(contract.datum, 'Datum copied to clipboard')}
title="Copy datum value"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
</svg>
</button>
</div>
</div>
</div>
{/if}
<div class="flex flex-col mt-4 md:flex-row md:items-center">
<div class="md:w-32 md:mb-0 mb-6 flex-shrink-0">
<span class="font-semibold title-font text-gray-700">Contract Body</span>
</div>
<div class="md:flex-grow">
<textarea {...textareaprops} value={contract.script_content} class="w-full h-max"></textarea>

<!-- Contract Body Section -->
<div class="bg-white rounded-lg shadow-sm p-4">
<div class="flex flex-col">
<div class="text-sm font-medium text-gray-500 mb-2">Contract Body</div>
<div class="flex items-start gap-2">
<textarea {...textareaprops} value={contract.script_content} class="w-full h-max font-mono text-sm"></textarea>
<button
class="text-gray-400 hover:text-gray-600 flex-shrink-0"
on:click={() => copyToClipboard(contract.script_content, 'Contract Body copied to clipboard')}
title="Copy contract body"
>
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3" />
</svg>
</button>
</div>
</div>
</div>
</div>

<style>
/* Add transition for smooth appearance/disappearance */
.fixed {
transition: opacity 0.3s ease-in-out;
z-index: 50;
}

/* Style for the textarea */
textarea {
font-family: monospace;
line-height: 1.5;
padding: 0.5rem;
border: 1px solid #e5e7eb;
border-radius: 0.375rem;
background-color: #f9fafb;
}

textarea:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 1px #3b82f6;
}
</style>

Loading
Loading