bitgit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +126 -0
- package/package.json +54 -0
- package/src/bsv/broadcast.ts +56 -0
- package/src/bsv/script.ts +103 -0
- package/src/bsv/tx.ts +90 -0
- package/src/bsv/utxo.ts +90 -0
- package/src/cli.ts +101 -0
- package/src/commands/init.ts +125 -0
- package/src/commands/push.ts +267 -0
- package/src/commands/register.ts +151 -0
- package/src/commands/status.ts +148 -0
- package/src/config.ts +101 -0
- package/src/db.ts +34 -0
package/src/config.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* .bit.yaml config parser
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { readFileSync, existsSync } from 'fs';
|
|
6
|
+
import { resolve } from 'path';
|
|
7
|
+
import { parse as parseYaml } from 'yaml';
|
|
8
|
+
|
|
9
|
+
export interface BitConfig {
|
|
10
|
+
project: {
|
|
11
|
+
name: string;
|
|
12
|
+
domain?: string;
|
|
13
|
+
token?: string;
|
|
14
|
+
};
|
|
15
|
+
wallet: {
|
|
16
|
+
key_env?: string;
|
|
17
|
+
key_file?: string;
|
|
18
|
+
};
|
|
19
|
+
content: {
|
|
20
|
+
type: 'blog' | 'repo' | 'domain' | 'custom';
|
|
21
|
+
source: string;
|
|
22
|
+
format: 'op_return' | 'bitcoin_schema';
|
|
23
|
+
protocol: string;
|
|
24
|
+
};
|
|
25
|
+
db?: {
|
|
26
|
+
supabase_url_env: string;
|
|
27
|
+
supabase_key_env: string;
|
|
28
|
+
version_table?: string;
|
|
29
|
+
};
|
|
30
|
+
dns_dex?: {
|
|
31
|
+
token_symbol?: string;
|
|
32
|
+
verification_code?: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const CONFIG_FILENAME = '.bit.yaml';
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Find and load .bit.yaml from cwd or parent directories.
|
|
40
|
+
*/
|
|
41
|
+
export function loadConfig(cwd = process.cwd()): BitConfig {
|
|
42
|
+
let dir = resolve(cwd);
|
|
43
|
+
|
|
44
|
+
while (true) {
|
|
45
|
+
const configPath = resolve(dir, CONFIG_FILENAME);
|
|
46
|
+
if (existsSync(configPath)) {
|
|
47
|
+
const raw = readFileSync(configPath, 'utf8');
|
|
48
|
+
return parseYaml(raw) as BitConfig;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const parent = resolve(dir, '..');
|
|
52
|
+
if (parent === dir) break; // reached filesystem root
|
|
53
|
+
dir = parent;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
throw new Error(
|
|
57
|
+
`No ${CONFIG_FILENAME} found. Run \`bit init\` to create one.`,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the WIF private key from config.
|
|
63
|
+
* Checks env var name from config, then falls back to common names.
|
|
64
|
+
*/
|
|
65
|
+
export function resolvePrivateKey(config: BitConfig): string {
|
|
66
|
+
// From config wallet.key_env
|
|
67
|
+
if (config.wallet.key_env) {
|
|
68
|
+
const wif = process.env[config.wallet.key_env];
|
|
69
|
+
if (wif) return wif;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// From config wallet.key_file
|
|
73
|
+
if (config.wallet.key_file) {
|
|
74
|
+
const keyPath = config.wallet.key_file.replace('~', process.env.HOME || '');
|
|
75
|
+
if (existsSync(keyPath)) {
|
|
76
|
+
return readFileSync(keyPath, 'utf8').trim();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Fallback chain
|
|
81
|
+
const fallbacks = [
|
|
82
|
+
'BOASE_TREASURY_PRIVATE_KEY',
|
|
83
|
+
'MONEYBUTTON_BSV_ORDINALS_PRIVATE_KEY',
|
|
84
|
+
'BSV_PRIVATE_KEY',
|
|
85
|
+
];
|
|
86
|
+
for (const envName of fallbacks) {
|
|
87
|
+
const wif = process.env[envName];
|
|
88
|
+
if (wif) return wif;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
throw new Error(
|
|
92
|
+
'No private key found. Set wallet.key_env in .bit.yaml or BOASE_TREASURY_PRIVATE_KEY env var.',
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get the config file path for a directory (even if it doesn't exist yet).
|
|
98
|
+
*/
|
|
99
|
+
export function configPath(cwd = process.cwd()): string {
|
|
100
|
+
return resolve(cwd, CONFIG_FILENAME);
|
|
101
|
+
}
|
package/src/db.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supabase admin client (shared Hetzner instance)
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { createClient, type SupabaseClient } from '@supabase/supabase-js';
|
|
6
|
+
import type { BitConfig } from './config.js';
|
|
7
|
+
|
|
8
|
+
let _client: SupabaseClient | null = null;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Get or create a Supabase admin client.
|
|
12
|
+
* Uses env vars from config, or falls back to common names.
|
|
13
|
+
*/
|
|
14
|
+
export function getDb(config?: BitConfig): SupabaseClient {
|
|
15
|
+
if (_client) return _client;
|
|
16
|
+
|
|
17
|
+
const urlEnv = config?.db?.supabase_url_env || 'NEXT_PUBLIC_SUPABASE_URL';
|
|
18
|
+
const keyEnv = config?.db?.supabase_key_env || 'SUPABASE_SERVICE_ROLE_KEY';
|
|
19
|
+
|
|
20
|
+
const url = process.env[urlEnv];
|
|
21
|
+
const key = process.env[keyEnv];
|
|
22
|
+
|
|
23
|
+
if (!url || !key) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Supabase not configured. Set ${urlEnv} and ${keyEnv} in your environment.`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
_client = createClient(url, key, {
|
|
30
|
+
auth: { autoRefreshToken: false, persistSession: false },
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
return _client;
|
|
34
|
+
}
|