-
Add Metadata (optional)
-
- {
- let key = "";
- let value = "";
-
- const initialKeys = [];
- if (!metadata?.some((m) => m.key === "name")) {
- key = "name";
- value = selectedFile?.name || "";
- initialKeys.push({ key, value, idx: metadata?.length || 0 });
- }
-
- const data = (metadata || []).concat(initialKeys || []);
- setMetadata(
- data.concat([
- {
- key: "",
- value: "",
- idx: data.length,
- },
- ])
- );
- }}
- >
-
-
-
-
- ),
- [selectedFile, metadata]
- );
+ return (
+
+
+
+
+ {(selectedFile || selectedCollection) && (
+
+ )}
- const metaForm = useMemo(() => {
- // Form to add metadata to the image
- // each metadata is a key value pair of strings
- // and we need an add button to add more metadata
+ {!selectedFile && (
+
+
+ Choose a file to inscribe
+
+
+ )}
- return (
-
- {metaHead}
- {metadata?.map((m) => metaRow(m))}
-
- );
- }, [metaHead, metaRow, metadata]);
+ {selectedFile && (
+ <>
+
+ {selectedFile.name}
+
+ {formatBytes(selectedFile.size)} Bytes
+
- return (
-
-
- {!selectedFile && }
- {selectedFile ? selectedFile.name : "Choose a file to inscribe"}
-
- {selectedFile && (
-
- {formatBytes(selectedFile.size)} Bytes
-
- )}
-
- {preview &&
}
+ {preview &&
}
- {selectedFile && preview && (
-
- {metaForm}
- {isImage ? (
- artifact
- ) : (
-
- FILE
-
- )}
-
+ {preview &&
}
+ >
)}
-
- Inscribe {isImage ? "Image" : "File"}
-
+
);
};
-export default InscribeImage;
-
-
-export const knownImageTypes = [
- "image/gif",
- "image/jpeg",
- "image/png",
- "image/webp",
- "image/svg+xml",
- "image/bmp",
- "image/tiff",
- "image/x-icon",
- "image/vnd.microsoft.icon",
- "image/vnd.wap.wbmp",
- "image/heic",
- "image/heif",
- "image/avif",
- "image/apng",
- "image/jxl",
- "image/jpg",
- "image/jfif",
- "image/pjpeg",
- "image/pjp",
-];
-export const knownVideoTypes = ["video/mp4", "video/webm", "video/ogg"];
-
-// TODO: Add more direct support for audio and video
-export const knownAudioTypes = ["audio/mpeg", "audio/ogg", "audio/wav", "application/vnd.apple.mpegurl"];
\ No newline at end of file
+export default InscribeImage;
\ No newline at end of file
diff --git a/src/components/pages/inscribe/index.tsx b/src/components/pages/inscribe/index.tsx
index 761a939a..9c59ee54 100644
--- a/src/components/pages/inscribe/index.tsx
+++ b/src/components/pages/inscribe/index.tsx
@@ -1,11 +1,15 @@
"use client";
+import SAFU from "@/components/Wallet/safu";
import Inscribe from "@/components/pages/inscribe/inscribe";
-import { payPk, utxos } from "@/signals/wallet";
+import { encryptedBackup, payPk, utxos } from "@/signals/wallet";
import { useSignals } from "@preact/signals-react/runtime";
import { useRouter, useSearchParams } from "next/navigation";
import type React from "react";
+import { FaSpinner } from "react-icons/fa6";
import type { InscriptionTab } from "./tabs";
+import { computed } from "@preact/signals-react";
+import { ordAddress } from "@/signals/wallet/address";
const InscribePage: React.FC = () => {
useSignals();
@@ -13,13 +17,29 @@ const InscribePage: React.FC = () => {
const router = useRouter();
const tab = params.get("tab") as InscriptionTab;
const generated = params.get("generated") === "true";
+
+
+ const locked = computed(() => !ordAddress.value && !!encryptedBackup);
+
+ if (locked.value) {
+ return
;
+ }
+
+ if (!ordAddress.value) {
+ return (
+
+
+
+ );
+ }
+
return (
<>
{payPk.value && utxos.value &&
}
{(!payPk.value || !utxos.value) && (
// biome-ignore lint/a11y/useKeyWithClickEvents:
- router.push("./wallet")}
>
diff --git a/src/components/pages/inscribe/inscribe.tsx b/src/components/pages/inscribe/inscribe.tsx
index 5a2eb69b..acbc79fd 100644
--- a/src/components/pages/inscribe/inscribe.tsx
+++ b/src/components/pages/inscribe/inscribe.tsx
@@ -6,11 +6,12 @@ import type React from "react";
import { useCallback, useMemo } from "react";
import InscribeBsv20 from "./bsv20";
import InscribeBsv21 from "./bsv21";
-import InscribeCollection from "./collection";
import InscribeHtml from "./html";
import InscribeImage from "./image";
import InscriptionTabs, { InscriptionTab } from "./tabs";
import InscribeText from "./text";
+import { pendingTxs } from "@/signals/wallet";
+import InscribeCollection from "./collection";
type InscribeProps = {
className?: string;
@@ -29,8 +30,15 @@ const Inscribe: React.FC
= ({ className, tab, generated }) => {
}, [tab]);
const inscribedCallback = useCallback(() => {
- router.push("/preview");
- }, [router]);
+ if (pendingTxs.value) {
+ const tx = pendingTxs.value[0];
+ console.log("Inscribed", { tx });
+ debugger;
+ router.push("/preview");
+ } else {
+ console.error("pendingTxs.value is null");
+ }
+ }, [pendingTxs.value, router]);
return (
void;
+}
+
+const InscribeButton: React.FC
= ({
+ selectedFile,
+ inscribeStatus,
+ selectedCollection,
+ metadata,
+ inscribedCallback,
+}) => {
+ const mapData = useMemo(() => {
+ const md = metadata?.reduce((acc, curr) => {
+ acc[curr.key] = curr.value as string;
+ return acc;
+ }, {} as { [key: string]: string });
+ if (md) {
+ md.app = "1sat.market";
+ md.type = "ord";
+ md.name = "Name Goes Here";
+ if (selectedCollection) {
+ md.subType = "collectionItem";
+ md.subTypeData = JSON.stringify({
+ collectionId: selectedCollection,
+ });
+ }
+ return md;
+ }
+ // eslint-disable-next-line react-hooks-signals/exhaustive-deps-signals
+ }, [metadata, selectedCollection]);
+
+ const clickInscribe = useCallback(async () => {
+ if (!selectedFile || !payPk.value || !ordPk.value || !ordAddress.value || !fundingAddress.value) {
+ toast.error("Missing required fields", toastErrorProps);
+ return;
+ }
+
+ const utxos = await getUtxos(fundingAddress.value);
+ if (!utxos) {
+ console.error("no utxo");
+ return;
+ }
+
+ // metadata
+ const m = metadata && Object.keys(metadata).length > 0 ? mapData : undefined;
+ let file: File | undefined;
+ if (selectedFile.type === "") {
+ const newType = mime.getType(selectedFile.name);
+ if (newType !== null) {
+ file = new File([selectedFile], selectedFile.name, { type: newType });
+ }
+ }
+ if (!file) {
+ file = selectedFile;
+ }
+ const pendingTx = await inscribeFile(utxos, file, m as PreMAP);
+ if (pendingTx) {
+ pendingTxs.value = [pendingTx];
+ inscribedCallback();
+ }
+ }, [selectedFile, payPk.value, ordPk.value, ordAddress.value, fundingAddress.value, metadata, mapData, inscribedCallback]);
+
+ const submitDisabled = useMemo(() => {
+ return !selectedFile || inscribeStatus === FetchStatus.Loading;
+ }, [selectedFile, inscribeStatus]);
+
+ return (
+
+ {selectedCollection ? "Mint Collection Item" : "Inscribe Image"}
+
+ );
+};
+
+export default InscribeButton;
\ No newline at end of file
diff --git a/src/components/pages/inscribe/metaForm.tsx b/src/components/pages/inscribe/metaForm.tsx
new file mode 100644
index 00000000..eb9e9199
--- /dev/null
+++ b/src/components/pages/inscribe/metaForm.tsx
@@ -0,0 +1,149 @@
+// metaForm.tsx
+
+import { FaPlus, FaQuestionCircle } from "react-icons/fa";
+import { IoMdClose } from "react-icons/io";
+import { removeBtnClass } from "./collection";
+import type { MetaMap } from "./image";
+
+interface MetaFormProps {
+ metadata: MetaMap[] | undefined;
+ setMetadata: (metadata: MetaMap[]) => void;
+ selectedCollection: string | undefined;
+ selectedFile: File | null;
+}
+
+const MetaForm: React.FC = ({ metadata, setMetadata, selectedCollection, selectedFile }) => {
+ const removeMetaRow = (idx: number) => {
+ setMetadata((metadata || []).filter((m) => m.idx !== idx));
+ };
+
+ const metaRow = (meta: MetaMap) => {
+ return (
+
+ {
+ // update metadata MetaMap
+ // where meta.idx === idx
+ e.preventDefault();
+ setMetadata(
+ (metadata || []).map((m) => {
+ if (m.idx === meta.idx) {
+ return {
+ ...m,
+ // exclude whitespace, special characters, or any invalid key characters
+ key: e.target.value.replaceAll(/[^a-zA-Z0-9]/g, ""),
+ };
+ }
+ return m;
+ })
+ );
+ }}
+ />
+ {
+ // update metadata MetaMap
+ // where meta.idx === idx
+ e.preventDefault();
+ setMetadata(
+ (metadata || []).map((m) => {
+ if (m.idx === meta.idx) {
+ return {
+ ...m,
+ value: e.target.value,
+ };
+ }
+ return m;
+ })
+ );
+ }}
+ />
+ {meta.idx > 2 && meta.key !== "subTypeData" && meta.key !== "subType" && meta.key !== "collectionId" && (
+ removeMetaRow(meta.idx)}>
+
+
+ )}
+
+ );
+ };
+
+ const metaHead = (
+
+
{!selectedCollection ? "Add Metadata (optional)" : "Metadata"}
+
+ {
+ const initialKeys = [
+ { key: "app", value: "1sat.market", idx: 0 },
+ { key: "type", value: "ord", idx: 1 },
+ { key: "name", value: selectedFile?.name || "", idx: 2 },
+ ];
+ const data = (metadata || []).concat(initialKeys);
+ setMetadata(
+ data.concat([
+ {
+ key: "",
+ value: "",
+ idx: data.length,
+ },
+ ])
+ );
+ }}
+ >
+
+
+
+
+ );
+
+ return (
+
+ {metaHead}
+
+ {metadata?.map((m) => metaRow(m))}
+
+ );
+};
+
+export default MetaForm;
\ No newline at end of file
diff --git a/src/components/pages/inscribe/styles.ts b/src/components/pages/inscribe/styles.ts
new file mode 100644
index 00000000..01e10c53
--- /dev/null
+++ b/src/components/pages/inscribe/styles.ts
@@ -0,0 +1,12 @@
+import styled from "styled-components";
+
+export const Input = styled.input`
+ padding: 0.5rem;
+ border-radius: 0.25rem;
+ margin: 0.5rem 0 0.5rem 0;
+`;
+
+export const Label = styled.label`
+ display: flex;
+ flex-direction: column;
+`;
diff --git a/src/components/pages/inscribe/tabs/index.tsx b/src/components/pages/inscribe/tabs/index.tsx
index d5a405d8..e8d1e07a 100644
--- a/src/components/pages/inscribe/tabs/index.tsx
+++ b/src/components/pages/inscribe/tabs/index.tsx
@@ -1,10 +1,10 @@
import Link from "next/link";
-import React from "react";
+import type React from "react";
interface Props {
currentTab: InscriptionTab | undefined;
showIndicator?: boolean;
onClickSelected?: (
- e: React.MouseEvent
+ e: React.MouseEvent
) => void;
}
@@ -26,61 +26,64 @@ const InscriptionTabs: React.FC = ({
onClickSelected,
}) => {
return (
-
-
+
+
+ {/* biome-ignore lint/a11y/useKeyWithClickEvents:
*/}
+ onClick={(e) =>
currentTab === InscriptionTab.Image && onClickSelected
? onClickSelected(e)
- : () => {}
+ : () => { }
}
>
Image
-
+
+ {/* biome-ignore lint/a11y/useKeyWithClickEvents: */}
+ onClick={(e) =>
currentTab === InscriptionTab.Text && onClickSelected
? onClickSelected(e)
- : () => {}
+ : () => { }
}
>
Text
-
+
+ {/* biome-ignore lint/a11y/useKeyWithClickEvents: */}
+ onClick={(e) =>
currentTab === InscriptionTab.HTML && onClickSelected
? onClickSelected(e)
- : () => {}
+ : () => { }
}
>
HTML
-
+
+ {/* biome-ignore lint/a11y/useKeyWithClickEvents: */}
+ className="whitespace-nowrap"
+ onClick={(e) =>
currentTab === InscriptionTab.BSV20 && onClickSelected
? onClickSelected(e)
- : () => {}
+ : () => { }
}
>
BSV-20
-
+
+ {/* biome-ignore lint/a11y/useKeyWithClickEvents: */}
+ className="whitespace-nowrap"
+ onClick={(e) =>
currentTab === InscriptionTab.BSV21 && onClickSelected
? onClickSelected(e)
- : () => {}
+ : () => { }
}
>
BSV-21
@@ -110,6 +113,19 @@ const InscriptionTabs: React.FC
= ({
>
Collection
*/}
+
+
+ {/* biome-ignore lint/a11y/useKeyWithClickEvents: */}
+
+ currentTab === InscriptionTab.Collection && onClickSelected
+ ? onClickSelected(e)
+ : () => { }
+ }
+ >
+ Collection
+
+
{/* {
+ const [selectedFile, setSelectedFile] = useState
(null);
+ const [preview, setPreview] = useState(null);
+ const [isImage, setIsImage] = useState(false);
+
+ useEffect(() => {
+ // if an imageUrl is provided, load it and set the preview
+ if (generated && generatedImage.value && !preview) {
+ const decoded = Buffer.from(generatedImage.value.data, "base64");
+ const arrayBuffer = decoded.buffer.slice(
+ decoded.byteOffset,
+ decoded.byteOffset + decoded.byteLength
+ ) as ArrayBuffer;
+ setIsImage(true);
+
+ const file = new File([arrayBuffer], "image.png", { type: "image/png" });
+ setSelectedFile(file);
+ const contentType = file.type || "image/png";
+ setPreview(`data:${contentType};base64,${generatedImage.value.data}`);
+ }
+ }, [generated, generatedImage.value, preview, setIsImage]);
+
+ const handleFileChange = useCallback((event: FileEvent) => {
+ const file = event.target.files[0] as File;
+
+ if (knownImageTypes.includes(file.type)) {
+ setIsImage(true);
+ } else if (knownVideoTypes.includes(file.type)) {
+ setIsImage(false);
+ } else if (knownAudioTypes.includes(file.type)) {
+ setIsImage(false);
+ } else {
+ setIsImage(false);
+ }
+
+ setSelectedFile(file);
+ if (file) {
+ const reader = new FileReader();
+ reader.onloadend = () => {
+ setPreview(reader.result);
+ };
+ reader.readAsDataURL(file);
+ } else {
+ setPreview(null);
+ }
+ }, []);
+
+ return { selectedFile, setSelectedFile, preview, isImage, handleFileChange };
+};
+
+export default useFileHandler;
\ No newline at end of file
diff --git a/src/components/pages/listings/tabs.tsx b/src/components/pages/listings/tabs.tsx
index d604f1ab..260f2371 100644
--- a/src/components/pages/listings/tabs.tsx
+++ b/src/components/pages/listings/tabs.tsx
@@ -8,9 +8,8 @@ const ListingsTabs = ({ selectedTab }: { selectedTab: AssetType }) => {
Ordinals
@@ -19,31 +18,18 @@ const ListingsTabs = ({ selectedTab }: { selectedTab: AssetType }) => {
BSV20
-
- LRC20
-
-
BSV21
diff --git a/src/components/pages/preview/index.tsx b/src/components/pages/preview/index.tsx
index 7b5c0d9b..373465de 100644
--- a/src/components/pages/preview/index.tsx
+++ b/src/components/pages/preview/index.tsx
@@ -8,6 +8,7 @@ import { formatBytes } from "@/utils/bytes";
import * as http from "@/utils/httpClient";
import { Transaction } from "@bsv/sdk";
import { useSignal, useSignals } from "@preact/signals-react/runtime";
+import { stringifyMetaData } from "js-1sat-ord";
import { head } from "lodash";
import { Loader2Icon } from "lucide-react";
import { useRouter } from "next/navigation";
@@ -89,16 +90,16 @@ const PreviewPage = () => {
}, [ordUtxos.value, pendingTx.value, pendingTxs.value, router, utxos.value]);
const change = useMemo(() => {
- if (pendingTx.value?.payChange) {
- console.log({change: pendingTx.value.payChange.satoshis})
- return pendingTx.value.payChange.satoshis
- }
- if (!pendingTx.value?.rawTx) {
+ if (pendingTx.value?.payChange) {
+ console.log({ change: pendingTx.value.payChange.satoshis });
+ return pendingTx.value.payChange.satoshis;
+ }
+ if (!pendingTx.value?.rawTx) {
return 0;
}
- const tx = Transaction.fromHex(pendingTx.value.rawTx)
- const changeOut = tx.outputs.find((o) => o.change)
- console.log({changeOut, pendingTx: pendingTx.value})
+ const tx = Transaction.fromHex(pendingTx.value.rawTx);
+ const changeOut = tx.outputs.find((o) => o.change);
+ console.log({ changeOut, pendingTx: pendingTx.value });
return changeOut?.satoshis || 0;
}, [pendingTx.value]);
@@ -114,10 +115,59 @@ const PreviewPage = () => {
for (const out of tx.outputs) {
totalOut += out.satoshis || 0;
}
- const cost = totalOut - change
+ const cost = totalOut - change;
return (cost / usdRate.value).toFixed(2);
}, [change, pendingTx.value, usdRate.value]);
+ const RenderMetadata = ({ data, depth = 0, hideArrayIndices = false }: any) => {
+ if (typeof data !== "object" || data === null) {
+ return {String(data)}
;
+ }
+
+ return Object.entries(data).map(([key, value]) => {
+ // Skip rendering if it's an array index and we're hiding indices
+ if (hideArrayIndices && !Number.isNaN(Number(key))) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
0 ? "ml-4" : ""}`}>
+ {key}
+
+ {!Array.isArray(value) && typeof value !== "object" && (
+
+ )}
+
+ {(Array.isArray(value) || typeof value === "object") && (
+
+
+
+ )}
+
+ );
+ });
+ };
+
return (
<>
@@ -143,7 +193,11 @@ Preview`}
Size
-
{pendingTx.value?.rawTx.length ? formatBytes(pendingTx.value?.rawTx.length / 2) : ""}
+
+ {pendingTx.value?.rawTx.length
+ ? formatBytes(pendingTx.value?.rawTx.length / 2)
+ : ""}
+
{(pendingTx.value?.price || 0) > 0 && (
@@ -180,20 +234,12 @@ Preview`}
Metadata
- {Object.keys(pendingTx.value?.metadata).map((k) => {
- const v =
- pendingTx.value?.metadata?.[k];
- return (
-
- );
- })}
+
>
)}
+
{pendingTx.value?.marketFee ? (
<>
Market
diff --git a/src/constants.ts b/src/constants.ts
index 5ec87943..8e23c74b 100644
--- a/src/constants.ts
+++ b/src/constants.ts
@@ -108,3 +108,31 @@ export const OLD_PAY_PK_KEY = "1satfk";
export const OLD_ORD_PK_KEY = "1satok";
export const NUMBER_OF_ITEMS_PER_PAGE = 50;
+
+
+export const knownImageTypes = [
+ "image/gif",
+ "image/jpeg",
+ "image/png",
+ "image/webp",
+ "image/svg+xml",
+ "image/bmp",
+ "image/tiff",
+ "image/x-icon",
+ "image/vnd.microsoft.icon",
+ "image/vnd.wap.wbmp",
+ "image/heic",
+ "image/heif",
+ "image/avif",
+ "image/apng",
+ "image/jxl",
+ "image/jpg",
+ "image/jfif",
+ "image/pjpeg",
+ "image/pjp",
+];
+
+export const knownVideoTypes = ["video/mp4", "video/webm", "video/ogg"];
+
+// TODO: Add more direct support for audio and video
+export const knownAudioTypes = ["audio/mpeg", "audio/ogg", "audio/wav", "application/vnd.apple.mpegurl"];
diff --git a/src/types/preview.ts b/src/types/preview.ts
index 4e957002..dd0b8279 100644
--- a/src/types/preview.ts
+++ b/src/types/preview.ts
@@ -1,5 +1,6 @@
-import type { MAP } from "js-1sat-ord";
-import type { NftUtxo, TokenUtxo, Utxo } from "js-1sat-ord";
+import type { MAP, PreMAP } from "js-1sat-ord";
+import type { TokenUtxo, Utxo } from "js-1sat-ord";
+
export type PendingTransaction = {
rawTx: string;
size: number;
@@ -14,6 +15,6 @@ export type PendingTransaction = {
price?: number;
marketFee?: number;
iterations?: number;
- metadata?: MAP;
+ metadata?: PreMAP;
returnTo?: string;
};
diff --git a/src/utils/address.ts b/src/utils/address.ts
index 8cb130a8..a67e171f 100644
--- a/src/utils/address.ts
+++ b/src/utils/address.ts
@@ -3,7 +3,7 @@ import { WocUtxo, WocUtxoResults } from "@/types/common";
import type { OrdUtxo } from "@/types/ordinals";
import { uniq } from "lodash";
import * as http from "./httpClient";
-import { fetchNftUtxos, fetchPayUtxos, type Utxo } from "js-1sat-ord";
+import { type CollectionSubTypeData, fetchNftUtxos, fetchPayUtxos, type Utxo } from "js-1sat-ord";
import { PrivateKey } from "@bsv/sdk";
export const addressFromWif = (payPk: string) => {
@@ -102,19 +102,133 @@ export const getUtxos = async (address: string): Promise
=> {
// }
};
+
+// // TODO: Implement this
+// export const getCollectionUtxos = async (address: string | null) => {
+// // dummy OrdUtxo
+// const dummy = {
+// outpoint: "abc123",
+// data: {
+// map: {
+// name: "Unnamed Collection",
+// },
+// },
+// } as unknown as OrdUtxo
+// if (!address) {
+// return [dummy]
+// // throw new Error("No address provided");
+// }
+// const q = {
+// map: {
+// subType: "collection",
+// },
+// };
+// const response = await fetch(`${API_HOST}/api/txos/address/${address}/unspent`, {
+// method: "POST",
+// headers: {
+// "Content-Type": "application/json",
+// },
+// body: JSON.stringify(q),
+// });
+// if (!response.ok) {
+// return [dummy]
+// // throw new Error("Failed to fetch collection UTXOs");
+// }
+
+// return ((await response.json()) || []).concat([dummy]);
+// };
+
+
+export const getCollectionUtxos = async (address: string | null): Promise => {
+ // Dummy data for testing
+ const dummyCollections: OrdUtxo[] = [
+ {
+ outpoint: "abc123",
+ data: {
+ map: {
+ app: "1sat.market",
+ type: "ord",
+ subType: "collection",
+ name: "Test Collection 1",
+ subTypeData: JSON.stringify({
+ description: "This is a test collection",
+ quantity: 100,
+ rarityLabels: [
+ { label: "Common", percentage: "0.50" },
+ { label: "Rare", percentage: "0.30" },
+ { label: "Epic", percentage: "0.15" },
+ { label: "Legendary", percentage: "0.05" },
+ ],
+ traits: {
+ Color: {
+ values: ["Red", "Blue", "Green"],
+ occurancePercentages: ["0.33", "0.33", "0.34"],
+ },
+ Size: {
+ values: ["Small", "Medium", "Large"],
+ occurancePercentages: ["0.25", "0.50", "0.25"],
+ },
+ Shape: {
+ values: ["Circle", "Square", "Triangle"],
+ occurancePercentages: ["0.40", "0.40", "0.20"],
+ },
+ },
+ } as CollectionSubTypeData),
+ },
+ },
+ },
+ {
+ outpoint: "def456",
+ data: {
+ map: {
+ app: "1sat.market",
+ type: "ord",
+ subType: "collection",
+ name: "Test Collection 2",
+ subTypeData: JSON.stringify({
+ description: "Another test collection",
+ quantity: 50,
+ rarityLabels: [
+ { label: "Normal", percentage: "0.70" },
+ { label: "Uncommon", percentage: "0.20" },
+ { label: "Super Rare", percentage: "0.10" },
+ ],
+ traits: {
+ Element: {
+ values: ["Fire", "Water", "Earth", "Air"],
+ occurancePercentages: ["0.25", "0.25", "0.25", "0.25"],
+ },
+ Power: {
+ values: ["Low", "Medium", "High"],
+ occurancePercentages: ["0.40", "0.40", "0.20"],
+ },
+ },
+ } as CollectionSubTypeData),
+ },
+ },
+ },
+ ] as unknown as OrdUtxo[];
+
+ // Simulating an API call delay
+ // await new Promise(resolve => setTimeout(resolve, 500));
+
+ return dummyCollections;
+};
+
+
export const getOutpoints = async (ids: string[], script: boolean) => {
- const url = `${API_HOST}/api/txos/outpoints?script=${script}`;
- console.log("almost", url, "with", ids);
- const uniqueIds = uniq(ids);
- console.log("hitting", url, "with", uniqueIds);
-
- const res = await fetch(url, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(uniqueIds),
- });
- const json = (await res.json()) as OrdUtxo[];
- return json;
+ const url = `${API_HOST}/api/txos/outpoints?script=${script}`;
+ console.log("almost", url, "with", ids);
+ const uniqueIds = uniq(ids);
+ console.log("hitting", url, "with", uniqueIds);
+
+ const res = await fetch(url, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(uniqueIds),
+ });
+ const json = (await res.json()) as OrdUtxo[];
+ return json;
};
diff --git a/src/utils/assetType.ts b/src/utils/assetType.ts
index 2134f07d..cf3b7d69 100644
--- a/src/utils/assetType.ts
+++ b/src/utils/assetType.ts
@@ -2,13 +2,12 @@ import type { WalletTab } from "@/components/Wallet/tabs";
import { AssetType } from "@/constants";
export function getCapitalizedAssetType(assetType: AssetType | WalletTab) {
- const types: (AssetType | WalletTab)[] = [
- AssetType.BSV20,
- AssetType.BSV21,
- AssetType.LRC20,
- ];
- if (types.includes(assetType)) {
- return assetType.toUpperCase();
- }
- return assetType.charAt(0).toUpperCase() + assetType.slice(1);
+ const types: (AssetType | WalletTab)[] = [
+ AssetType.BSV20,
+ AssetType.BSV21,
+ ];
+ if (types.includes(assetType)) {
+ return assetType.toUpperCase();
+ }
+ return assetType.charAt(0).toUpperCase() + assetType.slice(1);
}
diff --git a/src/utils/inscribe.ts b/src/utils/inscribe.ts
index 8e6ca20d..963ff7bf 100644
--- a/src/utils/inscribe.ts
+++ b/src/utils/inscribe.ts
@@ -14,6 +14,7 @@ import {
type Payment,
type RemoteSigner,
type Utxo,
+ type LocalSigner,
} from "js-1sat-ord";
import toast from "react-hot-toast";
import { readFileAsBase64 } from "./file";
@@ -28,6 +29,7 @@ export const handleInscribing = async (
utxos: Utxo[],
metaData?: PreMAP, // MAP,
additionalPayments: Payment[] = [],
+ idWif?: string,
) => {
const paymentPk = PrivateKey.fromWif(payPk);
@@ -40,11 +42,21 @@ export const handleInscribing = async (
// const idKey = PrivateKey.from_wif(
// "L1tFiewYRivZciv146HnCPBWzV35BR65dsJWZBYkQsKJ8UhXLz6q"
// );
+ let signer: LocalSigner | undefined;
+ if (idWif) {
+ const idKey = PrivateKey.fromWif(idWif);
+ console.log("Inscribing with", { metaData });
+ signer = {
+ idKey // optional id key
+ // keyHost: "http://localhost:21000",
+ } as LocalSigner; // RemoteSigner;
+ }
+
console.log("Inscribing with", { metaData });
- const signer = {
- // idKey // optional id key
- keyHost: "http://localhost:21000",
- } as RemoteSigner;
+ // const signer = {
+ // // idKey // optional id key
+ // keyHost: "http://localhost:21000",
+ // } as RemoteSigner;
const destinations: Destination[] = [
{
@@ -53,7 +65,6 @@ export const handleInscribing = async (
},
];
-
// [fundingUtxo],
// ordAddress,
// paymentPk,
@@ -70,6 +81,7 @@ export const handleInscribing = async (
paymentPk,
metaData,
additionalPayments,
+ signer,
};
const { spentOutpoints, tx, payChange } = await createOrdinals(config);
return { spentOutpoints, tx, payChange};
@@ -122,6 +134,7 @@ export const handleBulkInscribingWithData = async (
) => {
const paymentPk = PrivateKey.fromWif(payPk);
+ // TODO: implement sigma signing
const signer = {
keyHost: "http://localhost:21000",
} as RemoteSigner;