aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-11-26 14:53:20 -0800
committerAdam Soltys <[email protected]>2026-02-11 15:33:08 -0800
commit68e7fe9655f94efc573f3aab7acf60d03c4162a0 (patch)
tree48f35ea51823ac1cd0d74afc453628f5e128bf71 /src/lib
parent5f1c31b6618f0b895fb98c8f2a841989625eaf16 (diff)
downloadcoinos-ui-68e7fe9655f94efc573f3aab7acf60d03c4162a0.tar.gz
coinos-ui-68e7fe9655f94efc573f3aab7acf60d03c4162a0.zip
ark balance
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ark.ts116
1 files changed, 106 insertions, 10 deletions
diff --git a/src/lib/ark.ts b/src/lib/ark.ts
index 2dec57d9..7649a6bf 100644
--- a/src/lib/ark.ts
+++ b/src/lib/ark.ts
@@ -1,20 +1,116 @@
import { persistLocal } from "$lib/store";
+import { get } from "svelte/store";
import { SingleKey, Wallet } from "@arkade-os/sdk";
+import { bytesToHex, randomBytes } from "@noble/hashes/utils";
+import { nip19 } from "nostr-tools";
+import { hex } from "@scure/base";
-const prefix = "ark";
-export const mnemonic = persistLocal(`${prefix}mnemonic`, "");
-export const password = persistLocal(`${prefix}password`, "");
-export const arkkey = persistLocal(`${prefix}key`, "");
+export const arkServerUrl = "http://localhost:7070";
+export const arkkey = persistLocal("arkkey", "");
-export const getWallet = async () => {
- // const identity = SingleKey.fromHex(get(arkkey));
+export const generateKey = (): string => {
+ const privateKey = bytesToHex(randomBytes(32));
+ arkkey.set(privateKey);
+ return privateKey;
+};
- const identity = SingleKey.fromHex(
- "ce66c68f8875c0c98a502c666303dc183a21600130013c06f9d1edf60207abf2",
- );
+export const getKey = (): string => {
+ let key = get(arkkey);
+ if (!key) {
+ key = generateKey();
+ }
+ return key;
+};
+
+export const hasKey = (): boolean => {
+ return !!get(arkkey);
+};
+
+export const clearKey = (): void => {
+ arkkey.set("");
+};
+
+export const keyToNsec = (key?: string): string => {
+ const k = key || getKey();
+ return nip19.nsecEncode(hex.decode(k));
+};
+
+export const nsecToKey = (nsec: string): string => {
+ const { type, data } = nip19.decode(nsec);
+ if (type !== "nsec") throw new Error("Invalid nsec format");
+ return bytesToHex(data);
+};
+
+export const restoreFromNsec = (nsec: string): string => {
+ const key = nsecToKey(nsec);
+ arkkey.set(key);
+ return key;
+};
+
+export const getWallet = async () => {
+ const key = getKey();
+ const identity = SingleKey.fromHex(key);
return Wallet.create({
identity,
- arkServerUrl: "https://arkade.computer",
+ arkServerUrl,
});
};
+
+export const getAddress = async (): Promise<string> => {
+ const wallet = await getWallet();
+ return wallet.getAddress();
+};
+
+export const getBalance = async (): Promise<{ available: number; pending: number }> => {
+ const wallet = await getWallet();
+ return wallet.getBalance();
+};
+
+export const syncArkAddress = async (
+ currentAddress: string | undefined,
+ updateFn: (arkAddress: string) => Promise<void>
+): Promise<string> => {
+ const address = await getAddress();
+ if (address !== currentAddress) {
+ await updateFn(address);
+ }
+ return address;
+};
+
+export const sendArk = async (address: string, amount: number): Promise<string> => {
+ const wallet = await getWallet();
+ const vtxos = await wallet.getVtxos();
+
+ // Sort by expiry (spend oldest first)
+ const sorted = vtxos.sort(
+ (a, b) => (a.virtualStatus.batchExpiry ?? 0) - (b.virtualStatus.batchExpiry ?? 0)
+ );
+
+ // Select inputs
+ const inputs = [];
+ let selectedAmount = 0;
+ for (const vtxo of sorted) {
+ if (selectedAmount >= amount) break;
+ inputs.push(vtxo);
+ selectedAmount += vtxo.value;
+ }
+
+ if (selectedAmount < amount) {
+ throw new Error(`Insufficient funds: have ${selectedAmount}, need ${amount}`);
+ }
+
+ // Build outputs
+ const outputs: { address: string; amount: bigint }[] = [
+ { address, amount: BigInt(amount) }
+ ];
+
+ // Add change output if needed
+ const change = selectedAmount - amount;
+ if (change > 0) {
+ const changeAddress = await wallet.getAddress();
+ outputs.push({ address: changeAddress, amount: BigInt(change) });
+ }
+
+ return wallet.settle({ inputs, outputs });
+};