@utexo/rgb-sdk 1.0.0-beta.8
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/LICENCE +201 -0
- package/Readme.md +480 -0
- package/cli/README.md +348 -0
- package/cli/commands/address.mjs +16 -0
- package/cli/commands/blindreceive.mjs +15 -0
- package/cli/commands/btcbalance.mjs +11 -0
- package/cli/commands/createlightninginvoice.mjs +14 -0
- package/cli/commands/createutxos.mjs +13 -0
- package/cli/commands/decodergbinvoice.mjs +9 -0
- package/cli/commands/generate_keys.mjs +35 -0
- package/cli/commands/getlightningreceiverequest.mjs +10 -0
- package/cli/commands/getlightningsendrequest.mjs +10 -0
- package/cli/commands/getonchainsendstatus.mjs +20 -0
- package/cli/commands/listassets.mjs +11 -0
- package/cli/commands/listtransfers.mjs +10 -0
- package/cli/commands/listunspents.mjs +10 -0
- package/cli/commands/onchainreceive.mjs +16 -0
- package/cli/commands/onchainsend.mjs +11 -0
- package/cli/commands/onchainsendbegin.mjs +9 -0
- package/cli/commands/onchainsendend.mjs +9 -0
- package/cli/commands/paylightninginvoice.mjs +11 -0
- package/cli/commands/paylightninginvoicebegin.mjs +10 -0
- package/cli/commands/paylightninginvoiceend.mjs +9 -0
- package/cli/commands/refresh.mjs +9 -0
- package/cli/commands/send.mjs +31 -0
- package/cli/commands/sign-psbt.mjs +12 -0
- package/cli/commands/signpsbt.mjs +10 -0
- package/cli/commands/witnessreceive.mjs +15 -0
- package/cli/data/stage2-receiver.example.json +11 -0
- package/cli/data/stage2-sender.example.json +11 -0
- package/cli/generate_keys.mjs +66 -0
- package/cli/run.mjs +308 -0
- package/cli/utils.mjs +220 -0
- package/dist/index.cjs +1282 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +163 -0
- package/dist/index.d.ts +163 -0
- package/dist/index.mjs +1018 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +124 -0
package/cli/utils.mjs
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared utilities for UTEXO test scripts
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { UTEXOWallet, createWalletManager } from '../dist/index.mjs';
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
|
|
15
|
+
/** Directory name for wallet config files (relative to cli) */
|
|
16
|
+
const WALLET_DATA_DIR = 'data';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Map wallet network (e.g. from generate_keys) to UTEXOWallet preset.
|
|
20
|
+
* UTEXOWallet only supports 'mainnet' | 'testnet'; regtest/signet/testnet4 map to 'testnet'.
|
|
21
|
+
* @param {string} network - Network from wallet config (mainnet, testnet, regtest, signet, testnet4)
|
|
22
|
+
* @returns {'mainnet'|'testnet'}
|
|
23
|
+
*/
|
|
24
|
+
export function getNetworkPreset(network) {
|
|
25
|
+
return network === 'mainnet' ? 'mainnet' : 'testnet';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get the directory path for wallet config files (cli/data)
|
|
30
|
+
*/
|
|
31
|
+
export function getWalletDir() {
|
|
32
|
+
return path.join(__dirname, WALLET_DATA_DIR);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get the full path to a wallet config file
|
|
37
|
+
* @param {string} walletName - Name of the wallet
|
|
38
|
+
* @returns {string} Full path to the wallet config file
|
|
39
|
+
*/
|
|
40
|
+
export function getWalletPath(walletName) {
|
|
41
|
+
const filename = `${walletName}.json`;
|
|
42
|
+
return path.join(getWalletDir(), filename);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Load wallet configuration from file
|
|
47
|
+
* @param {string} walletName - Name of the wallet
|
|
48
|
+
* @returns {object} Wallet configuration object
|
|
49
|
+
* @throws {Error} If wallet file doesn't exist or is invalid
|
|
50
|
+
*/
|
|
51
|
+
export function loadWalletConfig(walletName) {
|
|
52
|
+
const filepath = getWalletPath(walletName);
|
|
53
|
+
|
|
54
|
+
if (!fs.existsSync(filepath)) {
|
|
55
|
+
throw new Error(`Wallet config not found: ${filepath}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const configContent = fs.readFileSync(filepath, 'utf8');
|
|
59
|
+
return JSON.parse(configContent);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Save wallet configuration to file
|
|
64
|
+
* @param {string} walletName - Name of the wallet
|
|
65
|
+
* @param {object} config - Wallet configuration object
|
|
66
|
+
*/
|
|
67
|
+
export function saveWalletConfig(walletName, config) {
|
|
68
|
+
const dir = getWalletDir();
|
|
69
|
+
if (!fs.existsSync(dir)) {
|
|
70
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
const filepath = getWalletPath(walletName);
|
|
73
|
+
fs.writeFileSync(filepath, JSON.stringify(config, null, 2));
|
|
74
|
+
return filepath;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Check if wallet config exists
|
|
79
|
+
* @param {string} walletName - Name of the wallet
|
|
80
|
+
* @returns {boolean} True if wallet config exists
|
|
81
|
+
*/
|
|
82
|
+
export function walletExists(walletName) {
|
|
83
|
+
return fs.existsSync(getWalletPath(walletName));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Handle script errors with consistent formatting
|
|
88
|
+
* @param {Error} error - Error object
|
|
89
|
+
* @param {string} action - Action that failed (e.g., "generating keys", "getting address")
|
|
90
|
+
*/
|
|
91
|
+
export function handleError(error, action) {
|
|
92
|
+
console.error(`❌ Error ${action}:`, error.message);
|
|
93
|
+
if (error.stack) {
|
|
94
|
+
console.error(error.stack);
|
|
95
|
+
}
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Parse flag args (e.g. after command and wallet name) into an options object.
|
|
101
|
+
* Flags are --key value (next arg). Does not include wallet name.
|
|
102
|
+
* @param {string[]} flagArgs - Args to parse (e.g. process.argv.slice(2) for rest after wallet)
|
|
103
|
+
* @param {{ required?: string[], optional?: string[] }} spec - Flag names (without --). required = must be present.
|
|
104
|
+
* @param {{ usage?: string }} options - If usage is set and validation fails, print it and exit
|
|
105
|
+
* @returns {{ [k: string]: string }} Parsed options (e.g. { invoice: 'rgb:...', assetId: '...' })
|
|
106
|
+
*/
|
|
107
|
+
export function parseFlags(flagArgs, spec = {}, options = {}) {
|
|
108
|
+
const required = spec.required ?? [];
|
|
109
|
+
const optional = spec.optional ?? [];
|
|
110
|
+
const allNames = [...new Set([...required, ...optional])];
|
|
111
|
+
const result = {};
|
|
112
|
+
|
|
113
|
+
for (let i = 0; i < flagArgs.length; i++) {
|
|
114
|
+
const arg = flagArgs[i];
|
|
115
|
+
if (!arg.startsWith('--')) continue;
|
|
116
|
+
const name = arg.slice(2);
|
|
117
|
+
if (!allNames.includes(name)) continue;
|
|
118
|
+
const value = flagArgs[i + 1];
|
|
119
|
+
if (value === undefined || value.startsWith('--')) {
|
|
120
|
+
if (options.usage) {
|
|
121
|
+
console.error(options.usage);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
throw new Error(`Missing value for --${name}`);
|
|
125
|
+
}
|
|
126
|
+
result[name] = value;
|
|
127
|
+
i++;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
for (const name of required) {
|
|
131
|
+
if (result[name] === undefined || result[name] === '') {
|
|
132
|
+
if (options.usage) {
|
|
133
|
+
console.error(options.usage);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
throw new Error(`Missing required --${name}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Load wallet, create UTEXOWallet, initialize, call action, then dispose. Central error handling.
|
|
144
|
+
* @param {string} walletName - Name of the wallet (must exist in data/)
|
|
145
|
+
* @param {(wallet: UTEXOWallet, walletConfig: object) => Promise<void>} action - Async callback; receives initialized wallet and config
|
|
146
|
+
* @param {{ actionName?: string, quiet?: boolean }} options - actionName for errors; quiet=true skips loading/init logs
|
|
147
|
+
*/
|
|
148
|
+
export async function runWithWallet(walletName, action, options = {}) {
|
|
149
|
+
if (!walletName) {
|
|
150
|
+
console.error('❌ Missing wallet name');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
if (!walletExists(walletName)) {
|
|
154
|
+
console.error(`❌ Wallet config not found: ${walletName}.json`);
|
|
155
|
+
console.error(` Please generate keys first: npm run generate_keys -- ${walletName}`);
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const walletConfig = loadWalletConfig(walletName);
|
|
160
|
+
const wallet = new UTEXOWallet(walletConfig.mnemonic, {
|
|
161
|
+
network: getNetworkPreset(walletConfig.network),
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
try {
|
|
165
|
+
if (!options.quiet) {
|
|
166
|
+
console.log(`Loading wallet: ${walletConfig.walletName}`);
|
|
167
|
+
console.log(`Network: ${walletConfig.network}`);
|
|
168
|
+
console.log('Initializing wallet...');
|
|
169
|
+
}
|
|
170
|
+
await wallet.initialize();
|
|
171
|
+
await action(wallet, walletConfig);
|
|
172
|
+
} finally {
|
|
173
|
+
await wallet.dispose();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Load wallet config, create WalletManager (from stored generate_keys JSON), run action, then dispose.
|
|
179
|
+
* Same flow as runWithWallet but for standard RGB WalletManager instead of UTEXOWallet.
|
|
180
|
+
* @param {string} walletName - Name of the wallet (must exist in data/)
|
|
181
|
+
* @param {(wallet: import('../dist/index.mjs').WalletManager, walletConfig: object) => Promise<void>} action
|
|
182
|
+
* @param {{ actionName?: string, quiet?: boolean, indexerUrl?: string, transportEndpoint?: string, dataDir?: string }} options
|
|
183
|
+
*/
|
|
184
|
+
export async function runWithWalletManager(walletName, action, options = {}) {
|
|
185
|
+
if (!walletName) {
|
|
186
|
+
console.error('❌ Missing wallet name');
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
if (!walletExists(walletName)) {
|
|
190
|
+
console.error(`❌ Wallet config not found: ${walletName}.json`);
|
|
191
|
+
console.error(` Please generate keys first: node run.mjs generate_keys ${walletName} [network]`);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const walletConfig = loadWalletConfig(walletName);
|
|
196
|
+
const dataDir = options.dataDir ?? path.join(process.cwd(), '.rgb-wallet', String(walletConfig.network), walletConfig.masterFingerprint);
|
|
197
|
+
const wallet = createWalletManager({
|
|
198
|
+
xpubVan: walletConfig.accountXpubVanilla,
|
|
199
|
+
xpubCol: walletConfig.accountXpubColored,
|
|
200
|
+
masterFingerprint: walletConfig.masterFingerprint,
|
|
201
|
+
mnemonic: walletConfig.mnemonic,
|
|
202
|
+
network: walletConfig.network,
|
|
203
|
+
dataDir,
|
|
204
|
+
transportEndpoint: options.transportEndpoint ?? process.env.RGB_TRANSPORT_ENDPOINT,
|
|
205
|
+
indexerUrl: options.indexerUrl ?? process.env.RGB_INDEXER_URL,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
if (!options.quiet) {
|
|
210
|
+
console.log(`Loading wallet (WalletManager): ${walletConfig.walletName ?? walletName}`);
|
|
211
|
+
console.log(`Network: ${walletConfig.network}`);
|
|
212
|
+
}
|
|
213
|
+
if (options.indexerUrl ?? process.env.RGB_INDEXER_URL) {
|
|
214
|
+
await wallet.goOnline(options.indexerUrl ?? process.env.RGB_INDEXER_URL);
|
|
215
|
+
}
|
|
216
|
+
await action(wallet, walletConfig);
|
|
217
|
+
} finally {
|
|
218
|
+
await wallet.dispose();
|
|
219
|
+
}
|
|
220
|
+
}
|