Skip to content

Commit

Permalink
feat: update stamp info page to get data from src101
Browse files Browse the repository at this point in the history
  • Loading branch information
itttm127 authored and reinamora137 committed Jan 18, 2025
1 parent 830a5e3 commit 0bb7c01
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 10 deletions.
4 changes: 2 additions & 2 deletions globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,15 +366,15 @@ export interface SRC101Balance {
owner: string;
}

interface Src101Detail {
export interface Src101Detail {
tx_hash: string;
block_index: number;
p: string;
op: string;
tick: string | null;
tick_hash: string | null;
name: string | null;
tokenid: string | null;
tokenid: string[] | null;
tokenid_utf8: string | null;
description: string | null;
wla: string | null;
Expand Down
54 changes: 47 additions & 7 deletions islands/stamp/details/StampInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import {
formatBTCAmount,
formatDate,
} from "$lib/utils/formatUtils.ts";
import { getStampImageSrc } from "$lib/utils/imageUtils.ts";
import { StampRow } from "$globals";
import { getSRC101Data, getStampImageSrc } from "$lib/utils/imageUtils.ts";
import { Src101Detail, StampRow } from "$globals";
import { StampSearchClient } from "$islands/stamp/StampSearch.tsx";
import { StampListingsOpen } from "$components/stampDetails/StampListingsOpen.tsx";
import type { Dispenser } from "$components/stampDetails/StampListingsOpen.tsx";
import { calculateTransactionSize } from "$lib/utils/identifierUtils.ts";

interface StampInfoProps {
stamp: StampRow;
Expand Down Expand Up @@ -210,6 +211,9 @@ export function StampInfo({ stamp, lowestPriceDispenser }: StampInfoProps) {
const jsonData = stamp.stamp_base64;
const blob = new Blob([jsonData], { type: "application/json" });
setFileSize(blob.size);
} else if (isSrc101Stamp()) {
const res = await calculateTransactionSize(stamp.tx_hash);
setFileSize(res);
} else if (stamp.stamp_mimetype?.startsWith("image/")) {
// Handle images
const src = await getStampImageSrc(stamp);
Expand Down Expand Up @@ -465,6 +469,7 @@ export function StampInfo({ stamp, lowestPriceDispenser }: StampInfoProps) {
updateScale();
}, [stamp.cpid, stamp.stamp, htmlStampTitle]);

const [src101, setSrc101] = useState<Src101Detail>({});
const [showListings, setShowListings] = useState(false);
const [dispensers, setDispensers] = useState<any[]>([]);
const [isLoadingDispensers, setIsLoadingDispensers] = useState(false);
Expand Down Expand Up @@ -501,9 +506,20 @@ export function StampInfo({ stamp, lowestPriceDispenser }: StampInfoProps) {
}
};

const fetchSRC101 = async () => {
try {
const res = await getSRC101Data(stamp as StampRow);
setSrc101(res);
} catch (error) {
console.log("Fetch SRC101 Error====>", error.message);
setSrc101({});
}
};

// Fetch dispensers when expanded
useEffect(() => {
fetchDispensers(1);
fetchSRC101();
}, []);

// Add state for selected dispenser
Expand Down Expand Up @@ -648,6 +664,10 @@ export function StampInfo({ stamp, lowestPriceDispenser }: StampInfoProps) {
return stamp.ident === "SRC-20";
};

const isSrc101Stamp = () => {
return stamp.ident === "SRC-101";
};

// Effect to handle document title updates
useEffect(() => {
document.title = `Bitcoin Stamp #${stamp.stamp} - stampchain.io`;
Expand Down Expand Up @@ -680,7 +700,13 @@ export function StampInfo({ stamp, lowestPriceDispenser }: StampInfoProps) {
marginBottom: `${-0.26 * (1 / scale - 1)}em`,
}}
>
{isSrc20Stamp()
{isSrc101Stamp() && src101
? (
<span className="font-light">
{src101?.tokenid?.length && atob(src101?.tokenid[0])}
</span>
)
: isSrc20Stamp()
? (
<>
<span className="font-light">#</span>
Expand Down Expand Up @@ -825,26 +851,40 @@ export function StampInfo({ stamp, lowestPriceDispenser }: StampInfoProps) {
<div className={`${dataColumn} flex-1 items-start`}>
<p className={dataLabelSm}>TYPE</p>
<p className={dataValueSm}>
{isSrc20Stamp() ? "SRC-20" : fileExtension}
{isSrc20Stamp()
? "SRC-20"
: isSrc101Stamp()
? "SRC-101"
: fileExtension}
</p>
</div>
<div className={`${dataColumn} flex-1 items-center`}>
<p className={dataLabelSm}>
{isSrc20Stamp()
{(isSrc20Stamp() || isSrc101Stamp())
? "TRANSACTION"
: isMediaFile
? "DURATION"
: "DIMENSIONS"}
</p>
<p className={dataValueSm}>
{isSrc20Stamp()
? JSON.parse(atob(stamp.stamp_base64))?.op === "DEPLOY"
? stamp.stamp_base64 &&
JSON.parse(atob(stamp.stamp_base64))?.op === "DEPLOY"
? "DEPLOY"
: JSON.parse(atob(stamp.stamp_base64))?.op === "MINT"
: stamp.stamp_base64 &&
JSON.parse(atob(stamp.stamp_base64))?.op === "MINT"
? "MINT"
: "TRANSFER"
: isMediaFile
? (mediaDuration ? formatDuration(mediaDuration) : "-")
: isSrc101Stamp()
? stamp.stamp_base64 &&
JSON.parse(atob(stamp.stamp_base64))?.op === "DEPLOY"
? "SALE"
: stamp.stamp_base64 &&
JSON.parse(atob(stamp.stamp_base64))?.op === "MINT"
? "REGISTER"
: "TRANSFER"
: getDimensionsDisplay(imageDimensions)}
</p>
</div>
Expand Down
35 changes: 35 additions & 0 deletions lib/utils/identifierUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,38 @@ export function getIdentifierType(
if (isCpid(value)) return "cpid";
return "invalid";
}

export async function calculateTransactionSize(
txHash: string,
): Promise<number> {
const API_URL = `https://blockstream.info/api/tx/${txHash}`;

try {
// Fetch transaction details from Blockstream API
const response = await fetch(API_URL);
if (!response.ok) {
throw new Error(
`Failed to fetch transaction details: ${response.statusText}`,
);
}

const txData = await response.json();

// Extract inputs and outputs
const inputs = txData.vin.length; // Number of inputs
const outputs = txData.vout.length; // Number of outputs

// Calculate the base transaction size
const inputSize = inputs * 148; // Each input is approx. 148 bytes
const outputSize = outputs * 34; // Each output is approx. 34 bytes
const overhead = 10; // Transaction overhead (version, locktime, etc.)

// Total size
const totalSize = inputSize + outputSize + overhead;

return totalSize;
} catch (error) {
console.error("Error calculating transaction size:", error);
throw error;
}
}
10 changes: 10 additions & 0 deletions lib/utils/imageUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ export const getStampImageSrc = async (stamp: StampRow): Promise<string> => {
}
};

export const getSRC101Data = async (stamp: StampRow) => {
if (stamp.ident !== "SRC-101") {
return {};
}

const res = await fetch(stamp.stamp_url);
const jsonData = await res.json();
return jsonData;
};

export const getMimeType = (extension: string): string => {
const normalizedExt = extension.toLowerCase().trim();
return mimeTypes[normalizedExt] || "application/octet-stream";
Expand Down
2 changes: 1 addition & 1 deletion server/services/src101/utilityService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { unicodeEscapeToEmoji } from "$lib/utils/emojiUtils.ts";
import { Src101Detail, TXError } from "$globals";
import { TXError } from "$globals";
import { crypto } from "@std/crypto";
import { isValidBitcoinAddress } from "$lib/utils/utxoUtils.ts";
import { SRC101QueryService } from "./queryService.ts";
Expand Down

0 comments on commit 0bb7c01

Please sign in to comment.