@kaleidorg/wallet-engine 1.0.0-beta.4 → 1.0.0-beta.42
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 +29 -10
- package/dist/adapters/ArkadeAdapter.d.ts +78 -14
- package/dist/adapters/ArkadeAdapter.d.ts.map +1 -1
- package/dist/adapters/ArkadeAdapter.js +653 -161
- package/dist/adapters/ArkadeAdapter.js.map +1 -1
- package/dist/adapters/IProtocolAdapter.d.ts +195 -18
- package/dist/adapters/IProtocolAdapter.d.ts.map +1 -1
- package/dist/adapters/IProtocolAdapter.js +6 -2
- package/dist/adapters/IProtocolAdapter.js.map +1 -1
- package/dist/adapters/RgbAdapter.d.ts +70 -27
- package/dist/adapters/RgbAdapter.d.ts.map +1 -1
- package/dist/adapters/RgbAdapter.js +464 -370
- package/dist/adapters/RgbAdapter.js.map +1 -1
- package/dist/adapters/SparkAdapter.d.ts +93 -15
- package/dist/adapters/SparkAdapter.d.ts.map +1 -1
- package/dist/adapters/SparkAdapter.js +833 -168
- package/dist/adapters/SparkAdapter.js.map +1 -1
- package/dist/adapters/arkade.d.ts +15 -0
- package/dist/adapters/arkade.d.ts.map +1 -0
- package/dist/adapters/arkade.js +15 -0
- package/dist/adapters/arkade.js.map +1 -0
- package/dist/adapters/flashnet.d.ts +15 -0
- package/dist/adapters/flashnet.d.ts.map +1 -0
- package/dist/adapters/flashnet.js +17 -0
- package/dist/adapters/flashnet.js.map +1 -0
- package/dist/adapters/native.d.ts +17 -0
- package/dist/adapters/native.d.ts.map +1 -0
- package/dist/adapters/native.js +17 -0
- package/dist/adapters/native.js.map +1 -0
- package/dist/adapters/rgb.d.ts +11 -0
- package/dist/adapters/rgb.d.ts.map +1 -0
- package/dist/adapters/rgb.js +11 -0
- package/dist/adapters/rgb.js.map +1 -0
- package/dist/adapters/spark.d.ts +12 -0
- package/dist/adapters/spark.d.ts.map +1 -0
- package/dist/adapters/spark.js +14 -0
- package/dist/adapters/spark.js.map +1 -0
- package/dist/adapters/wdk/ArkadeWdkAdapter.d.ts +53 -19
- package/dist/adapters/wdk/ArkadeWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/ArkadeWdkAdapter.js +366 -90
- package/dist/adapters/wdk/ArkadeWdkAdapter.js.map +1 -1
- package/dist/adapters/wdk/BaseWdkAdapter.d.ts +40 -0
- package/dist/adapters/wdk/BaseWdkAdapter.d.ts.map +1 -0
- package/dist/adapters/wdk/BaseWdkAdapter.js +71 -0
- package/dist/adapters/wdk/BaseWdkAdapter.js.map +1 -0
- package/dist/adapters/wdk/LiquidWdkAdapter.d.ts +6 -13
- package/dist/adapters/wdk/LiquidWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/LiquidWdkAdapter.js +14 -32
- package/dist/adapters/wdk/LiquidWdkAdapter.js.map +1 -1
- package/dist/adapters/wdk/RgbCore.d.ts +64 -0
- package/dist/adapters/wdk/RgbCore.d.ts.map +1 -0
- package/dist/adapters/wdk/RgbCore.js +111 -0
- package/dist/adapters/wdk/RgbCore.js.map +1 -0
- package/dist/adapters/wdk/RgbLibWasmAdapter.d.ts +277 -0
- package/dist/adapters/wdk/RgbLibWasmAdapter.d.ts.map +1 -0
- package/dist/adapters/wdk/RgbLibWasmAdapter.js +731 -0
- package/dist/adapters/wdk/RgbLibWasmAdapter.js.map +1 -0
- package/dist/adapters/wdk/RgbLibWdkAdapter.d.ts +104 -0
- package/dist/adapters/wdk/RgbLibWdkAdapter.d.ts.map +1 -0
- package/dist/adapters/wdk/RgbLibWdkAdapter.js +249 -0
- package/dist/adapters/wdk/RgbLibWdkAdapter.js.map +1 -0
- package/dist/adapters/wdk/RlnWdkAdapter.d.ts +27 -14
- package/dist/adapters/wdk/RlnWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/RlnWdkAdapter.js +124 -89
- package/dist/adapters/wdk/RlnWdkAdapter.js.map +1 -1
- package/dist/adapters/wdk/SparkWdkAdapter.d.ts +74 -41
- package/dist/adapters/wdk/SparkWdkAdapter.d.ts.map +1 -1
- package/dist/adapters/wdk/SparkWdkAdapter.js +706 -249
- package/dist/adapters/wdk/SparkWdkAdapter.js.map +1 -1
- package/dist/adapters/wdk/index.d.ts +17 -0
- package/dist/adapters/wdk/index.d.ts.map +1 -0
- package/dist/adapters/wdk/index.js +17 -0
- package/dist/adapters/wdk/index.js.map +1 -0
- package/dist/adapters/wdk/wasm-rgb.d.ts +15 -0
- package/dist/adapters/wdk/wasm-rgb.d.ts.map +1 -0
- package/dist/adapters/wdk/wasm-rgb.js +15 -0
- package/dist/adapters/wdk/wasm-rgb.js.map +1 -0
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/capabilities/index.d.ts.map +1 -1
- package/dist/capabilities/index.js +17 -2
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/operations.d.ts +22 -0
- package/dist/capabilities/operations.d.ts.map +1 -0
- package/dist/capabilities/operations.js +62 -0
- package/dist/capabilities/operations.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/disclosure/index.d.ts +1 -1
- package/dist/disclosure/index.js +1 -1
- package/dist/disclosure/index.js.map +1 -1
- package/dist/format.d.ts +11 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +10 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +21 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -32
- package/dist/index.js.map +1 -1
- package/dist/lib/arkade-client-manager.d.ts +64 -24
- package/dist/lib/arkade-client-manager.d.ts.map +1 -1
- package/dist/lib/arkade-client-manager.js +240 -65
- package/dist/lib/arkade-client-manager.js.map +1 -1
- package/dist/lib/arkade-converters.d.ts +39 -0
- package/dist/lib/arkade-converters.d.ts.map +1 -0
- package/dist/lib/arkade-converters.js +148 -0
- package/dist/lib/arkade-converters.js.map +1 -0
- package/dist/lib/arkade-helpers.d.ts +110 -0
- package/dist/lib/arkade-helpers.d.ts.map +1 -0
- package/dist/lib/arkade-helpers.js +227 -0
- package/dist/lib/arkade-helpers.js.map +1 -0
- package/dist/lib/arkade-swaps-client-manager.d.ts +55 -0
- package/dist/lib/arkade-swaps-client-manager.d.ts.map +1 -0
- package/dist/lib/arkade-swaps-client-manager.js +127 -0
- package/dist/lib/arkade-swaps-client-manager.js.map +1 -0
- package/dist/lib/arkade-vtxo-lifecycle.d.ts +116 -0
- package/dist/lib/arkade-vtxo-lifecycle.d.ts.map +1 -0
- package/dist/lib/arkade-vtxo-lifecycle.js +184 -0
- package/dist/lib/arkade-vtxo-lifecycle.js.map +1 -0
- package/dist/lib/flashnet-client-manager.d.ts +26 -9
- package/dist/lib/flashnet-client-manager.d.ts.map +1 -1
- package/dist/lib/flashnet-client-manager.js +97 -13
- package/dist/lib/flashnet-client-manager.js.map +1 -1
- package/dist/lib/kaleido-client-manager.d.ts +38 -3
- package/dist/lib/kaleido-client-manager.d.ts.map +1 -1
- package/dist/lib/kaleido-client-manager.js +79 -10
- package/dist/lib/kaleido-client-manager.js.map +1 -1
- package/dist/lib/ln-message-sign.d.ts +20 -0
- package/dist/lib/ln-message-sign.d.ts.map +1 -0
- package/dist/lib/ln-message-sign.js +90 -0
- package/dist/lib/ln-message-sign.js.map +1 -0
- package/dist/lib/log.d.ts +15 -0
- package/dist/lib/log.d.ts.map +1 -0
- package/dist/lib/log.js +16 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/orchestra-client.d.ts +149 -0
- package/dist/lib/orchestra-client.d.ts.map +1 -0
- package/dist/lib/orchestra-client.js +178 -0
- package/dist/lib/orchestra-client.js.map +1 -0
- package/dist/lib/psbt-signer.d.ts +60 -0
- package/dist/lib/psbt-signer.d.ts.map +1 -0
- package/dist/lib/psbt-signer.js +161 -0
- package/dist/lib/psbt-signer.js.map +1 -0
- package/dist/lib/rgb-converters.d.ts +62 -0
- package/dist/lib/rgb-converters.d.ts.map +1 -0
- package/dist/lib/rgb-converters.js +179 -0
- package/dist/lib/rgb-converters.js.map +1 -0
- package/dist/lib/rgb-fee-policy.d.ts +41 -0
- package/dist/lib/rgb-fee-policy.d.ts.map +1 -0
- package/dist/lib/rgb-fee-policy.js +52 -0
- package/dist/lib/rgb-fee-policy.js.map +1 -0
- package/dist/lib/rgb-helpers.d.ts +54 -0
- package/dist/lib/rgb-helpers.d.ts.map +1 -0
- package/dist/lib/rgb-helpers.js +89 -0
- package/dist/lib/rgb-helpers.js.map +1 -0
- package/dist/lib/spark-activity.d.ts +5 -0
- package/dist/lib/spark-activity.d.ts.map +1 -0
- package/dist/lib/spark-activity.js +11 -0
- package/dist/lib/spark-activity.js.map +1 -0
- package/dist/lib/spark-balance-cache.d.ts +58 -0
- package/dist/lib/spark-balance-cache.d.ts.map +1 -0
- package/dist/lib/spark-balance-cache.js +86 -0
- package/dist/lib/spark-balance-cache.js.map +1 -0
- package/dist/lib/spark-client-manager.d.ts +64 -10
- package/dist/lib/spark-client-manager.d.ts.map +1 -1
- package/dist/lib/spark-client-manager.js +191 -35
- package/dist/lib/spark-client-manager.js.map +1 -1
- package/dist/lib/spark-converters.d.ts +64 -0
- package/dist/lib/spark-converters.d.ts.map +1 -0
- package/dist/lib/spark-converters.js +242 -0
- package/dist/lib/spark-converters.js.map +1 -0
- package/dist/lib/spark-helpers.d.ts +72 -0
- package/dist/lib/spark-helpers.d.ts.map +1 -0
- package/dist/lib/spark-helpers.js +151 -0
- package/dist/lib/spark-helpers.js.map +1 -0
- package/dist/lib/spark-sent-token-records.d.ts +43 -0
- package/dist/lib/spark-sent-token-records.d.ts.map +1 -0
- package/dist/lib/spark-sent-token-records.js +105 -0
- package/dist/lib/spark-sent-token-records.js.map +1 -0
- package/dist/lib/wallet-seed.d.ts +31 -0
- package/dist/lib/wallet-seed.d.ts.map +1 -0
- package/dist/lib/wallet-seed.js +58 -0
- package/dist/lib/wallet-seed.js.map +1 -0
- package/dist/lib/zbase32.d.ts +3 -0
- package/dist/lib/zbase32.d.ts.map +1 -0
- package/dist/lib/zbase32.js +64 -0
- package/dist/lib/zbase32.js.map +1 -0
- package/dist/manager/ProtocolManager.d.ts +54 -3
- package/dist/manager/ProtocolManager.d.ts.map +1 -1
- package/dist/manager/ProtocolManager.js +118 -41
- package/dist/manager/ProtocolManager.js.map +1 -1
- package/dist/ports/index.d.ts +20 -0
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +23 -1
- package/dist/ports/index.js.map +1 -1
- package/dist/receive/unifiedReceive.d.ts +12 -0
- package/dist/receive/unifiedReceive.d.ts.map +1 -1
- package/dist/receive/unifiedReceive.js +35 -4
- package/dist/receive/unifiedReceive.js.map +1 -1
- package/dist/registry/createWdkRegistry.d.ts +10 -2
- package/dist/registry/createWdkRegistry.d.ts.map +1 -1
- package/dist/registry/createWdkRegistry.js +14 -7
- package/dist/registry/createWdkRegistry.js.map +1 -1
- package/dist/router/destination.d.ts +2 -2
- package/dist/router/destination.d.ts.map +1 -1
- package/dist/router/destination.js +34 -11
- package/dist/router/destination.js.map +1 -1
- package/dist/router/index.d.ts +39 -3
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +113 -4
- package/dist/router/index.js.map +1 -1
- package/dist/router/preference.d.ts +53 -0
- package/dist/router/preference.d.ts.map +1 -0
- package/dist/router/preference.js +81 -0
- package/dist/router/preference.js.map +1 -0
- package/dist/swap/KaleidoswapSwap.d.ts +1 -1
- package/dist/swap/KaleidoswapSwap.d.ts.map +1 -1
- package/dist/swap/KaleidoswapSwap.js +37 -20
- package/dist/swap/KaleidoswapSwap.js.map +1 -1
- package/dist/swap/index.d.ts +8 -0
- package/dist/swap/index.d.ts.map +1 -0
- package/dist/swap/index.js +8 -0
- package/dist/swap/index.js.map +1 -0
- package/dist/types/arkade.d.ts +1 -1
- package/dist/types/base.d.ts +35 -25
- package/dist/types/base.d.ts.map +1 -1
- package/dist/types/base.js +28 -2
- package/dist/types/base.js.map +1 -1
- package/dist/types/cross-l2.d.ts +1 -1
- package/dist/types/flashnet.d.ts +20 -0
- package/dist/types/flashnet.d.ts.map +1 -1
- package/dist/types/flashnet.js +34 -6
- package/dist/types/flashnet.js.map +1 -1
- package/dist/types/rgb.d.ts +18 -4
- package/dist/types/rgb.d.ts.map +1 -1
- package/dist/types/spark.d.ts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +2 -2
- package/dist/utils.js.map +1 -1
- package/package.json +68 -14
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* RGB Protocol Adapter
|
|
3
|
-
* Uses
|
|
4
|
-
|
|
3
|
+
* Uses Kaleido SDK to implement the protocol adapter interface
|
|
4
|
+
*/
|
|
5
|
+
import { log } from "../lib/log.js";
|
|
6
|
+
import { kaleidoClientManager } from "../lib/kaleido-client-manager.js";
|
|
7
|
+
import { KaleidoError, APIError, NetworkError, NodeNotConfiguredError, QuoteExpiredError, InsufficientBalanceError as SdkInsufficientBalanceError, Layer as SdkLayer, } from "kaleido-sdk";
|
|
8
|
+
import { ProtocolError, ConnectionError, InsufficientBalanceError, } from "../types/base.js";
|
|
9
|
+
import { PROTOCOL_OPERATIONS } from "../capabilities/operations.js";
|
|
10
|
+
import { resolveRgbFeeRatePolicy } from "../lib/rgb-fee-policy.js";
|
|
11
|
+
import { mapPaymentStatus, mapSwapStatus } from "../lib/rgb-helpers.js";
|
|
12
|
+
import { convertBtcBalance, convertNodeAssetToUnified, convertPaymentToTransaction, convertSdkBalance, convertSwapToTransaction, convertTransferToTransaction, } from "../lib/rgb-converters.js";
|
|
13
|
+
/**
|
|
14
|
+
* RGB Protocol Adapter Implementation using Kaleido SDK
|
|
5
15
|
*/
|
|
6
|
-
import { kaleidoClientManager } from '../lib/kaleido-client-manager';
|
|
7
|
-
import { KaleidoError, APIError, NetworkError, NodeNotConfiguredError, QuoteExpiredError, InsufficientBalanceError as SdkInsufficientBalanceError, Layer as SdkLayer, } from 'kaleido-sdk';
|
|
8
|
-
import { ProtocolError, ConnectionError, InsufficientBalanceError, } from '../types/base';
|
|
9
16
|
export class RgbAdapter {
|
|
10
17
|
constructor() {
|
|
11
|
-
this.protocolName =
|
|
12
|
-
this.supportedLayers = [
|
|
13
|
-
this.version =
|
|
18
|
+
this.protocolName = "RGB_LN";
|
|
19
|
+
this.supportedLayers = ["RGB_L1", "RGB_LN", "BTC_L1", "BTC_LN"];
|
|
20
|
+
this.version = "1.0.0";
|
|
21
|
+
this.capabilities = PROTOCOL_OPERATIONS.RGB_LN;
|
|
14
22
|
this.connected = false;
|
|
15
23
|
this.config = null;
|
|
16
24
|
this.swapAccessTokens = new Map();
|
|
@@ -20,66 +28,99 @@ export class RgbAdapter {
|
|
|
20
28
|
// ========================================================================
|
|
21
29
|
async connect(config) {
|
|
22
30
|
const rgbConfig = config;
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
const transport = rgbConfig.transport ?? "http";
|
|
32
|
+
// For HTTP a node URL is required; for NWC the connection string is. Maker
|
|
33
|
+
// is optional in both cases.
|
|
34
|
+
if (transport === "nwc") {
|
|
35
|
+
if (!rgbConfig.nwcUri) {
|
|
36
|
+
throw new ConnectionError("NWC connection string is required", "RGB_LN");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (!rgbConfig.nodeUrl) {
|
|
40
|
+
throw new ConnectionError("Node URL is required", "RGB_LN");
|
|
25
41
|
}
|
|
42
|
+
log.info(`[RgbAdapter] connect() — transport=${transport} ${transport === "nwc" ? "nwc=(string)" : `nodeUrl=${rgbConfig.nodeUrl}`} makerUrl=${rgbConfig.makerUrl || "(none)"} hasApiKey=${!!rgbConfig.apiKey}`);
|
|
26
43
|
try {
|
|
44
|
+
// Initialize Kaleido SDK client (maker URL is optional, transport-independent)
|
|
27
45
|
kaleidoClientManager.initialize({
|
|
28
|
-
baseUrl: rgbConfig.makerUrl ||
|
|
46
|
+
baseUrl: rgbConfig.makerUrl || "",
|
|
29
47
|
nodeUrl: rgbConfig.nodeUrl,
|
|
30
48
|
apiKey: rgbConfig.apiKey,
|
|
49
|
+
transport,
|
|
50
|
+
nwcUri: rgbConfig.nwcUri,
|
|
31
51
|
});
|
|
32
52
|
const client = kaleidoClientManager.getClient();
|
|
33
|
-
|
|
53
|
+
log.info(`[RgbAdapter] Calling client.rln.getNodeInfo() → ${rgbConfig.nodeUrl}`);
|
|
54
|
+
const t0 = Date.now();
|
|
55
|
+
let nodeInfo;
|
|
56
|
+
try {
|
|
57
|
+
nodeInfo = await client.rln.getNodeInfo();
|
|
58
|
+
log.info(`[RgbAdapter] getNodeInfo() OK in ${Date.now() - t0}ms:`, nodeInfo);
|
|
59
|
+
}
|
|
60
|
+
catch (httpErr) {
|
|
61
|
+
const msg = httpErr instanceof Error ? httpErr.message : String(httpErr);
|
|
62
|
+
log.error(`[RgbAdapter] getNodeInfo() FAILED after ${Date.now() - t0}ms: ${msg}`, httpErr);
|
|
63
|
+
throw httpErr;
|
|
64
|
+
}
|
|
34
65
|
this.config = rgbConfig;
|
|
35
66
|
this.connected = true;
|
|
36
|
-
|
|
37
|
-
//
|
|
67
|
+
log.info("[RgbAdapter] Connected to RGB node successfully via SDK");
|
|
68
|
+
// Optionally test maker connection (non-blocking)
|
|
38
69
|
if (rgbConfig.makerUrl) {
|
|
39
70
|
try {
|
|
71
|
+
log.info(`[RgbAdapter] Testing maker API → ${rgbConfig.makerUrl}`);
|
|
40
72
|
await client.maker.listAssets();
|
|
41
|
-
|
|
73
|
+
log.info("[RgbAdapter] Maker API accessible ✓");
|
|
42
74
|
}
|
|
43
75
|
catch (error) {
|
|
44
76
|
const msg = error instanceof Error ? error.message : String(error);
|
|
45
|
-
|
|
77
|
+
log.warn("[RgbAdapter] Maker API not accessible (swaps will show error):", msg);
|
|
78
|
+
// Don't throw - maker is optional, only needed for swaps
|
|
46
79
|
}
|
|
47
80
|
}
|
|
81
|
+
else {
|
|
82
|
+
log.info("[RgbAdapter] No maker URL provided (swaps disabled)");
|
|
83
|
+
}
|
|
48
84
|
}
|
|
49
85
|
catch (error) {
|
|
50
86
|
const msg = error instanceof Error ? error.message : String(error);
|
|
51
|
-
|
|
87
|
+
log.error(`[RgbAdapter] connect() failed: ${msg}`);
|
|
88
|
+
throw new ConnectionError(`Failed to connect to RGB node: ${msg}`, "RGB_LN", error instanceof Error ? error : undefined);
|
|
52
89
|
}
|
|
53
90
|
}
|
|
54
91
|
async disconnect() {
|
|
55
92
|
kaleidoClientManager.reset();
|
|
56
93
|
this.connected = false;
|
|
57
94
|
this.config = null;
|
|
58
|
-
|
|
95
|
+
log.info("[RgbAdapter] Disconnected");
|
|
59
96
|
}
|
|
60
97
|
isConnected() {
|
|
61
98
|
return this.connected && kaleidoClientManager.isInitialized();
|
|
62
99
|
}
|
|
63
100
|
async getConnectionInfo() {
|
|
64
101
|
if (!this.isConnected()) {
|
|
65
|
-
throw new ProtocolError(
|
|
102
|
+
throw new ProtocolError("Not connected", "RGB_LN", "NOT_CONNECTED");
|
|
66
103
|
}
|
|
67
104
|
const info = {
|
|
68
|
-
protocol:
|
|
105
|
+
protocol: "RGB_LN",
|
|
69
106
|
connected: true,
|
|
70
|
-
network: this.config?.network ||
|
|
107
|
+
network: this.config?.network || "regtest",
|
|
71
108
|
};
|
|
109
|
+
// Try to get node info if node is configured
|
|
72
110
|
if (kaleidoClientManager.hasNode()) {
|
|
73
111
|
try {
|
|
74
112
|
const client = kaleidoClientManager.getClient();
|
|
75
113
|
const nodeInfo = await client.rln.getNodeInfo();
|
|
76
114
|
const networkInfo = await client.rln.getNetworkInfo();
|
|
77
|
-
info.nodeId = nodeInfo.pubkey ||
|
|
115
|
+
info.nodeId = nodeInfo.pubkey || "";
|
|
78
116
|
info.blockHeight = networkInfo.height || 0;
|
|
79
|
-
info.syncStatus = {
|
|
117
|
+
info.syncStatus = {
|
|
118
|
+
synced: true,
|
|
119
|
+
progress: 100,
|
|
120
|
+
};
|
|
80
121
|
}
|
|
81
122
|
catch (error) {
|
|
82
|
-
|
|
123
|
+
log.warn("[RgbAdapter] Could not get node info:", error);
|
|
83
124
|
}
|
|
84
125
|
}
|
|
85
126
|
return info;
|
|
@@ -89,91 +130,134 @@ export class RgbAdapter {
|
|
|
89
130
|
// ========================================================================
|
|
90
131
|
async listAssets() {
|
|
91
132
|
if (!this.isConnected()) {
|
|
92
|
-
throw new ProtocolError(
|
|
133
|
+
throw new ProtocolError("Not connected", "RGB_LN", "NOT_CONNECTED");
|
|
93
134
|
}
|
|
94
135
|
const client = kaleidoClientManager.getClient();
|
|
136
|
+
// Get node assets (always works if node is connected)
|
|
95
137
|
let nodeAssetsArray = [];
|
|
96
138
|
if (kaleidoClientManager.hasNode()) {
|
|
97
139
|
try {
|
|
98
140
|
const nodeAssets = await client.rln.listAssets();
|
|
99
|
-
|
|
141
|
+
// ListAssetsResponse is an object with nia, uda, cfa arrays
|
|
142
|
+
const nodeAssetsResponse = nodeAssets;
|
|
100
143
|
nodeAssetsArray = [
|
|
101
|
-
...(
|
|
102
|
-
...(
|
|
103
|
-
...(
|
|
144
|
+
...(nodeAssetsResponse.nia || []),
|
|
145
|
+
...(nodeAssetsResponse.uda || []),
|
|
146
|
+
...(nodeAssetsResponse.cfa || []),
|
|
104
147
|
];
|
|
148
|
+
log.info("[RgbAdapter] Got assets from node via SDK:", nodeAssetsArray.length);
|
|
105
149
|
}
|
|
106
150
|
catch (error) {
|
|
107
|
-
|
|
151
|
+
log.warn("[RgbAdapter] Could not get node assets:", error);
|
|
108
152
|
}
|
|
109
153
|
}
|
|
154
|
+
// Wallet asset lists must reflect wallet-owned node assets only.
|
|
155
|
+
// Maker-listed assets belong to market discovery and should be queried
|
|
156
|
+
// through the dedicated maker APIs used by swap flows.
|
|
110
157
|
if (nodeAssetsArray.length === 0) {
|
|
111
|
-
|
|
112
|
-
try {
|
|
113
|
-
const btcBalance = await client.rln.getBtcBalance();
|
|
114
|
-
return [this.createBtcAsset(btcBalance)];
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
return [];
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
// Add BTC as first asset
|
|
121
|
-
const assets = [];
|
|
122
|
-
try {
|
|
123
|
-
const btcBalance = await client.rln.getBtcBalance();
|
|
124
|
-
assets.push(this.createBtcAsset(btcBalance));
|
|
158
|
+
throw new ProtocolError("No wallet assets available from node", "RGB_LN", "NO_ASSETS_AVAILABLE");
|
|
125
159
|
}
|
|
126
|
-
|
|
127
|
-
// Skip BTC if balance check fails
|
|
128
|
-
}
|
|
129
|
-
assets.push(...nodeAssetsArray.map(a => this.convertNodeAssetToUnified(a)));
|
|
130
|
-
return assets;
|
|
160
|
+
return nodeAssetsArray.map((asset) => convertNodeAssetToUnified(asset));
|
|
131
161
|
}
|
|
132
162
|
async getAsset(assetId) {
|
|
133
163
|
const assets = await this.listAssets();
|
|
134
|
-
const asset = assets.find(a => a.id === assetId || a.ticker === assetId);
|
|
164
|
+
const asset = assets.find((a) => a.id === assetId || a.ticker === assetId);
|
|
135
165
|
if (!asset) {
|
|
136
|
-
throw new ProtocolError(`Asset not found: ${assetId}`,
|
|
166
|
+
throw new ProtocolError(`Asset not found: ${assetId}`, "RGB_LN", "ASSET_NOT_FOUND");
|
|
137
167
|
}
|
|
138
168
|
return asset;
|
|
139
169
|
}
|
|
140
170
|
async getAssetBalance(assetId) {
|
|
141
171
|
if (!kaleidoClientManager.hasNode()) {
|
|
142
|
-
throw new ProtocolError(
|
|
172
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
173
|
+
}
|
|
174
|
+
if (!assetId || !assetId.trim()) {
|
|
175
|
+
throw new ProtocolError("Asset ID is required", "RGB_LN", "INVALID_ASSET_ID");
|
|
143
176
|
}
|
|
144
177
|
try {
|
|
145
178
|
const client = kaleidoClientManager.getClient();
|
|
146
|
-
if
|
|
179
|
+
// Check if requesting BTC balance
|
|
180
|
+
if (assetId === "BTC" || assetId.toLowerCase() === "btc") {
|
|
147
181
|
const btcBalance = await client.rln.getBtcBalance();
|
|
148
|
-
return
|
|
182
|
+
return convertBtcBalance(btcBalance);
|
|
183
|
+
}
|
|
184
|
+
// Get RGB asset balance
|
|
185
|
+
const balanceData = await client.rln.getAssetBalance({
|
|
186
|
+
asset_id: assetId,
|
|
187
|
+
});
|
|
188
|
+
return convertSdkBalance(balanceData);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
throw this.handleSdkError(error, "Failed to get asset balance");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async refreshBalances() {
|
|
195
|
+
if (!kaleidoClientManager.hasNode())
|
|
196
|
+
return;
|
|
197
|
+
try {
|
|
198
|
+
const client = kaleidoClientManager.getClient();
|
|
199
|
+
const refreshTransfers = client.rln?.refreshTransfers?.bind(client.rln) ?? client.refreshTransfers?.bind(client);
|
|
200
|
+
if (refreshTransfers) {
|
|
201
|
+
await refreshTransfers({ skip_sync: false });
|
|
149
202
|
}
|
|
150
|
-
const balanceData = await client.rln.getAssetBalance({ asset_id: assetId });
|
|
151
|
-
return this.convertSdkBalance(balanceData);
|
|
152
203
|
}
|
|
153
204
|
catch (error) {
|
|
154
|
-
|
|
205
|
+
log.warn("[RgbAdapter] Could not refresh transfers:", error);
|
|
155
206
|
}
|
|
156
207
|
}
|
|
157
|
-
async refreshBalances() { }
|
|
158
208
|
// ========================================================================
|
|
159
209
|
// Transaction Operations
|
|
160
210
|
// ========================================================================
|
|
161
211
|
async listTransactions(filter) {
|
|
162
212
|
if (!kaleidoClientManager.hasNode()) {
|
|
163
|
-
throw new ProtocolError(
|
|
213
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
164
214
|
}
|
|
165
215
|
try {
|
|
166
216
|
const client = kaleidoClientManager.getClient();
|
|
217
|
+
// listTransfers requires asset_id for RGB on-chain transfers
|
|
167
218
|
if (!filter?.asset) {
|
|
168
|
-
throw new ProtocolError(
|
|
219
|
+
throw new ProtocolError("Asset ID is required for listing RGB transfers", "RGB_LN", "ASSET_ID_REQUIRED");
|
|
169
220
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
221
|
+
// Fetch on-chain transfers, Lightning payments AND swaps in parallel.
|
|
222
|
+
// RGB assets can move via all three rails; the asset card needs to
|
|
223
|
+
// surface all of them. listPayments() and listSwaps() return ALL
|
|
224
|
+
// entries — filter client-side by asset_id.
|
|
225
|
+
const [transfersResponse, paymentsResponse, swapsResponse] = await Promise.all([
|
|
226
|
+
client.rln.listTransfers({ asset_id: filter.asset }),
|
|
227
|
+
client.rln.listPayments().catch(() => ({ payments: [] })),
|
|
228
|
+
client.rln.listSwaps().catch(() => ({ maker: [], taker: [] })),
|
|
229
|
+
]);
|
|
230
|
+
const transferTxs = (transfersResponse.transfers ?? []).map((transfer) => convertTransferToTransaction(transfer));
|
|
231
|
+
const paymentTxs = (paymentsResponse.payments ?? [])
|
|
232
|
+
.filter((payment) => {
|
|
233
|
+
const paymentAssetId = payment.asset_id;
|
|
234
|
+
// Match BTC payments to BTC, RGB payments to their asset_id.
|
|
235
|
+
if (filter.asset === "BTC" || filter.asset?.toLowerCase() === "btc") {
|
|
236
|
+
return !paymentAssetId;
|
|
237
|
+
}
|
|
238
|
+
return paymentAssetId === filter.asset;
|
|
239
|
+
})
|
|
240
|
+
.map((payment) => convertPaymentToTransaction(payment));
|
|
241
|
+
const isAssetBtc = filter.asset === "BTC" || filter.asset?.toLowerCase() === "btc";
|
|
242
|
+
const matchesSwapAsset = (swap) => {
|
|
243
|
+
const fromAsset = swap.from_asset ?? null;
|
|
244
|
+
const toAsset = swap.to_asset ?? null;
|
|
245
|
+
// BTC side of a swap is encoded as a missing asset_id.
|
|
246
|
+
if (isAssetBtc)
|
|
247
|
+
return fromAsset === null || toAsset === null;
|
|
248
|
+
return fromAsset === filter.asset || toAsset === filter.asset;
|
|
249
|
+
};
|
|
250
|
+
const swapTxs = [
|
|
251
|
+
...(swapsResponse.maker ?? [])
|
|
252
|
+
.filter(matchesSwapAsset)
|
|
253
|
+
.map((swap) => convertSwapToTransaction(swap, "maker")),
|
|
254
|
+
...(swapsResponse.taker ?? [])
|
|
255
|
+
.filter(matchesSwapAsset)
|
|
256
|
+
.map((swap) => convertSwapToTransaction(swap, "taker")),
|
|
257
|
+
];
|
|
258
|
+
const merged = [...transferTxs, ...paymentTxs, ...swapTxs];
|
|
259
|
+
return merged
|
|
260
|
+
.filter((tx) => {
|
|
177
261
|
if (filter.type && tx.type !== filter.type)
|
|
178
262
|
return false;
|
|
179
263
|
if (filter.status && tx.status !== filter.status)
|
|
@@ -184,20 +268,21 @@ export class RgbAdapter {
|
|
|
184
268
|
return false;
|
|
185
269
|
return true;
|
|
186
270
|
})
|
|
271
|
+
.sort((a, b) => b.timestamp - a.timestamp)
|
|
187
272
|
.slice(filter?.offset || 0, (filter?.offset || 0) + (filter?.limit || 100));
|
|
188
273
|
}
|
|
189
274
|
catch (error) {
|
|
190
|
-
throw this.handleSdkError(error,
|
|
275
|
+
throw this.handleSdkError(error, "Failed to list transactions");
|
|
191
276
|
}
|
|
192
277
|
}
|
|
193
278
|
async getTransaction(txId, assetId) {
|
|
194
279
|
if (!assetId) {
|
|
195
|
-
throw new ProtocolError(
|
|
280
|
+
throw new ProtocolError("Asset ID is required to look up an RGB transaction", "RGB_LN", "ASSET_ID_REQUIRED");
|
|
196
281
|
}
|
|
197
282
|
const transactions = await this.listTransactions({ asset: assetId });
|
|
198
|
-
const tx = transactions.find(t => t.id === txId);
|
|
283
|
+
const tx = transactions.find((t) => t.id === txId);
|
|
199
284
|
if (!tx) {
|
|
200
|
-
throw new ProtocolError(`Transaction not found: ${txId}`,
|
|
285
|
+
throw new ProtocolError(`Transaction not found: ${txId}`, "RGB_LN", "TX_NOT_FOUND");
|
|
201
286
|
}
|
|
202
287
|
return tx;
|
|
203
288
|
}
|
|
@@ -206,57 +291,62 @@ export class RgbAdapter {
|
|
|
206
291
|
// ========================================================================
|
|
207
292
|
async createInvoice(request) {
|
|
208
293
|
if (!kaleidoClientManager.hasNode()) {
|
|
209
|
-
throw new ProtocolError(
|
|
294
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
210
295
|
}
|
|
211
296
|
try {
|
|
212
297
|
const client = kaleidoClientManager.getClient();
|
|
298
|
+
// Create Lightning invoice (BTC or RGB over Lightning)
|
|
299
|
+
// Build params - always include expiry_sec
|
|
213
300
|
const lnInvoiceParams = {
|
|
214
|
-
expiry_sec: request.expirySeconds || 3600,
|
|
301
|
+
expiry_sec: request.expirySeconds || 3600, // Default to 1 hour
|
|
215
302
|
};
|
|
216
|
-
|
|
303
|
+
// Include asset fields if provided (for RGB Lightning invoices)
|
|
304
|
+
const isRgbInvoice = request.asset && request.asset !== "BTC" && request.asset !== "btc";
|
|
217
305
|
if (isRgbInvoice) {
|
|
218
306
|
lnInvoiceParams.asset_id = request.asset;
|
|
219
307
|
if (request.assetAmount && request.assetAmount > 0) {
|
|
220
308
|
lnInvoiceParams.asset_amount = request.assetAmount;
|
|
221
309
|
}
|
|
222
|
-
//
|
|
223
|
-
|
|
310
|
+
// The node requires amt_msat >= 3000000 for ANY RGB Lightning invoice,
|
|
311
|
+
// even zero-amount ones where asset_amount is omitted.
|
|
312
|
+
const RGB_HTLC_MIN_MSAT = 3000000; // 3000 sats in msats
|
|
224
313
|
const requestedMsat = request.amount && request.amount > 0 ? request.amount * 1000 : 0;
|
|
225
314
|
lnInvoiceParams.amt_msat = Math.max(requestedMsat, RGB_HTLC_MIN_MSAT);
|
|
226
315
|
}
|
|
227
316
|
else {
|
|
317
|
+
// BTC Lightning invoice — only include amt_msat if amount is provided
|
|
228
318
|
if (request.amount && request.amount > 0) {
|
|
229
319
|
lnInvoiceParams.amt_msat = request.amount * 1000;
|
|
230
320
|
}
|
|
231
321
|
}
|
|
232
|
-
const lnInvoice = await client.rln.createLNInvoice(lnInvoiceParams);
|
|
322
|
+
const lnInvoice = (await client.rln.createLNInvoice(lnInvoiceParams));
|
|
233
323
|
return {
|
|
234
|
-
invoice: lnInvoice.invoice ??
|
|
235
|
-
paymentHash: lnInvoice.payment_hash ??
|
|
324
|
+
invoice: lnInvoice.invoice ?? "",
|
|
325
|
+
paymentHash: lnInvoice.payment_hash ?? "",
|
|
236
326
|
amount: request.amount,
|
|
237
327
|
expiresAt: Date.now() + (request.expirySeconds || 3600) * 1000,
|
|
238
328
|
description: request.description,
|
|
239
329
|
};
|
|
240
330
|
}
|
|
241
331
|
catch (error) {
|
|
242
|
-
throw this.handleSdkError(error,
|
|
332
|
+
throw this.handleSdkError(error, "Failed to create invoice");
|
|
243
333
|
}
|
|
244
334
|
}
|
|
245
335
|
async decodeInvoice(invoice) {
|
|
246
336
|
if (!kaleidoClientManager.hasNode()) {
|
|
247
|
-
throw new ProtocolError(
|
|
337
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
248
338
|
}
|
|
249
339
|
try {
|
|
250
340
|
const client = kaleidoClientManager.getClient();
|
|
251
|
-
const decoded = await client.rln.decodeLNInvoice({ invoice });
|
|
341
|
+
const decoded = (await client.rln.decodeLNInvoice({ invoice }));
|
|
252
342
|
const amtMsat = decoded.amt_msat;
|
|
253
343
|
return {
|
|
254
|
-
paymentHash: decoded.payment_hash ??
|
|
344
|
+
paymentHash: decoded.payment_hash ?? "",
|
|
255
345
|
amount: amtMsat != null ? amtMsat / 1000 : undefined,
|
|
256
346
|
amountMsat: amtMsat ?? undefined,
|
|
257
347
|
description: decoded.description,
|
|
258
348
|
expiresAt: decoded.expiry_sec ? Date.now() + decoded.expiry_sec * 1000 : 0,
|
|
259
|
-
destination: decoded.payee_pubkey ||
|
|
349
|
+
destination: decoded.payee_pubkey || "",
|
|
260
350
|
asset_id: decoded.asset_id ?? undefined,
|
|
261
351
|
asset_amount: decoded.asset_amount ?? undefined,
|
|
262
352
|
payment_hash: decoded.payment_hash,
|
|
@@ -264,51 +354,95 @@ export class RgbAdapter {
|
|
|
264
354
|
};
|
|
265
355
|
}
|
|
266
356
|
catch (error) {
|
|
267
|
-
throw this.handleSdkError(error,
|
|
357
|
+
throw this.handleSdkError(error, "Failed to decode invoice");
|
|
268
358
|
}
|
|
269
359
|
}
|
|
270
360
|
async sendPayment(request) {
|
|
271
361
|
if (!kaleidoClientManager.hasNode()) {
|
|
272
|
-
throw new ProtocolError(
|
|
362
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
273
363
|
}
|
|
274
364
|
try {
|
|
275
365
|
const client = kaleidoClientManager.getClient();
|
|
276
|
-
const sendParams = {
|
|
277
|
-
|
|
278
|
-
|
|
366
|
+
const sendParams = {
|
|
367
|
+
invoice: request.invoice,
|
|
368
|
+
};
|
|
369
|
+
// Forward `amt_msat` only for amountless invoices. Previously this
|
|
370
|
+
// truthy-check forwarded any positive `request.amount`, silently
|
|
371
|
+
// re-amounting amount-bearing invoices.
|
|
372
|
+
if (request.amount && request.amount > 0) {
|
|
373
|
+
let invoiceIsAmountless = false;
|
|
374
|
+
try {
|
|
375
|
+
const decoded = await this.decodeInvoice(request.invoice);
|
|
376
|
+
invoiceIsAmountless = !decoded.amount_msat && !decoded.amountMsat && !decoded.amount;
|
|
377
|
+
}
|
|
378
|
+
catch {
|
|
379
|
+
// If decode fails, err on the side of not overriding.
|
|
380
|
+
invoiceIsAmountless = false;
|
|
381
|
+
}
|
|
382
|
+
if (invoiceIsAmountless) {
|
|
383
|
+
sendParams.amt_msat = request.amount * 1000;
|
|
384
|
+
}
|
|
279
385
|
}
|
|
280
|
-
const result = await client.rln.sendPayment(sendParams);
|
|
386
|
+
const result = (await client.rln.sendPayment(sendParams));
|
|
281
387
|
return {
|
|
282
|
-
paymentHash: result.payment_hash ??
|
|
388
|
+
paymentHash: result.payment_hash ?? "",
|
|
283
389
|
preimage: result.payment_preimage,
|
|
284
390
|
amount: result.amount_msat ? result.amount_msat / 1000 : 0,
|
|
285
391
|
fee: result.fee_msat ? result.fee_msat / 1000 : 0,
|
|
286
|
-
status:
|
|
392
|
+
status: mapPaymentStatus(result.status),
|
|
393
|
+
timestamp: Date.now(),
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
throw this.handleSdkError(error, "Failed to send payment");
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
async payKeysend(request) {
|
|
401
|
+
if (!kaleidoClientManager.hasNode()) {
|
|
402
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
const client = kaleidoClientManager.getClient();
|
|
406
|
+
const result = (await client.rln.keysend({
|
|
407
|
+
dest_pubkey: request.pubkey,
|
|
408
|
+
amt_msat: request.amount,
|
|
409
|
+
asset_id: request.assetId,
|
|
410
|
+
asset_amount: request.assetAmount,
|
|
411
|
+
}));
|
|
412
|
+
return {
|
|
413
|
+
paymentHash: result.payment_hash ?? "",
|
|
414
|
+
preimage: result.payment_preimage,
|
|
415
|
+
amount: request.amount / 1000,
|
|
416
|
+
fee: 0,
|
|
417
|
+
status: mapPaymentStatus(result.status),
|
|
287
418
|
timestamp: Date.now(),
|
|
288
419
|
};
|
|
289
420
|
}
|
|
290
421
|
catch (error) {
|
|
291
|
-
throw this.handleSdkError(error,
|
|
422
|
+
throw this.handleSdkError(error, "Failed to send keysend payment");
|
|
292
423
|
}
|
|
293
424
|
}
|
|
294
425
|
async getPaymentStatus(paymentHash) {
|
|
295
426
|
if (!kaleidoClientManager.hasNode()) {
|
|
296
|
-
throw new ProtocolError(
|
|
427
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
297
428
|
}
|
|
298
429
|
try {
|
|
299
430
|
const client = kaleidoClientManager.getClient();
|
|
300
|
-
const response = await client.rln.getPayment({
|
|
431
|
+
const response = (await client.rln.getPayment({
|
|
432
|
+
payment_hash: paymentHash,
|
|
433
|
+
}));
|
|
434
|
+
// The response may be the payment directly or wrapped in a { payment } object
|
|
301
435
|
const payment = (response.payment ?? response);
|
|
302
436
|
return {
|
|
303
437
|
paymentHash,
|
|
304
|
-
status:
|
|
438
|
+
status: mapPaymentStatus(payment.status),
|
|
305
439
|
amount: payment.amount_msat ? payment.amount_msat / 1000 : undefined,
|
|
306
440
|
fee: payment.fee_msat ? payment.fee_msat / 1000 : undefined,
|
|
307
441
|
timestamp: payment.created_at,
|
|
308
442
|
};
|
|
309
443
|
}
|
|
310
444
|
catch (error) {
|
|
311
|
-
throw this.handleSdkError(error,
|
|
445
|
+
throw this.handleSdkError(error, "Failed to get payment status");
|
|
312
446
|
}
|
|
313
447
|
}
|
|
314
448
|
// ========================================================================
|
|
@@ -316,19 +450,19 @@ export class RgbAdapter {
|
|
|
316
450
|
// ========================================================================
|
|
317
451
|
async getReceiveAddress(assetId) {
|
|
318
452
|
if (!kaleidoClientManager.hasNode()) {
|
|
319
|
-
throw new ProtocolError(
|
|
453
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
320
454
|
}
|
|
321
455
|
try {
|
|
322
456
|
const client = kaleidoClientManager.getClient();
|
|
323
|
-
const addressData = await client.rln.getAddress();
|
|
457
|
+
const addressData = (await client.rln.getAddress());
|
|
324
458
|
return {
|
|
325
|
-
address: addressData.address ??
|
|
326
|
-
format:
|
|
459
|
+
address: addressData.address ?? "",
|
|
460
|
+
format: "BTC_ADDRESS",
|
|
327
461
|
asset: assetId,
|
|
328
462
|
};
|
|
329
463
|
}
|
|
330
464
|
catch (error) {
|
|
331
|
-
throw this.handleSdkError(error,
|
|
465
|
+
throw this.handleSdkError(error, "Failed to get receive address");
|
|
332
466
|
}
|
|
333
467
|
}
|
|
334
468
|
// ========================================================================
|
|
@@ -336,68 +470,83 @@ export class RgbAdapter {
|
|
|
336
470
|
// ========================================================================
|
|
337
471
|
async getNodeInfo() {
|
|
338
472
|
if (!kaleidoClientManager.hasNode()) {
|
|
339
|
-
throw new ProtocolError(
|
|
473
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
340
474
|
}
|
|
341
475
|
try {
|
|
342
|
-
|
|
476
|
+
const client = kaleidoClientManager.getClient();
|
|
477
|
+
return await client.rln.getNodeInfo();
|
|
343
478
|
}
|
|
344
479
|
catch (error) {
|
|
345
|
-
throw this.handleSdkError(error,
|
|
480
|
+
throw this.handleSdkError(error, "Failed to get node info");
|
|
346
481
|
}
|
|
347
482
|
}
|
|
348
483
|
async getBtcBalance() {
|
|
349
484
|
if (!kaleidoClientManager.hasNode()) {
|
|
350
|
-
throw new ProtocolError(
|
|
485
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
351
486
|
}
|
|
352
487
|
try {
|
|
353
488
|
const client = kaleidoClientManager.getClient();
|
|
354
489
|
const btcBalance = await client.rln.getBtcBalance();
|
|
355
490
|
const vanilla = btcBalance?.vanilla || {};
|
|
356
491
|
const colored = btcBalance?.colored || {};
|
|
357
|
-
const
|
|
358
|
-
const
|
|
492
|
+
const spendableVanilla = vanilla.spendable || 0;
|
|
493
|
+
const spendableColored = colored.spendable || 0;
|
|
494
|
+
const futureVanilla = vanilla.future || 0;
|
|
495
|
+
const futureColored = colored.future || 0;
|
|
496
|
+
const confirmed = spendableVanilla + spendableColored;
|
|
497
|
+
// `future` is the expected balance after all pending txs settle.
|
|
498
|
+
// Pending incoming = amount above spendable; pending outgoing reduces future below spendable.
|
|
499
|
+
const futureTotal = futureVanilla + futureColored;
|
|
359
500
|
const unconfirmed = Math.max(futureTotal - confirmed, 0);
|
|
360
501
|
return { confirmed, unconfirmed, total: futureTotal };
|
|
361
502
|
}
|
|
362
503
|
catch (error) {
|
|
363
|
-
throw this.handleSdkError(error,
|
|
504
|
+
throw this.handleSdkError(error, "Failed to get BTC balance");
|
|
364
505
|
}
|
|
365
506
|
}
|
|
366
507
|
async listChannels() {
|
|
367
508
|
if (!kaleidoClientManager.hasNode()) {
|
|
368
|
-
throw new ProtocolError(
|
|
509
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
369
510
|
}
|
|
370
511
|
try {
|
|
371
|
-
const
|
|
372
|
-
|
|
512
|
+
const client = kaleidoClientManager.getClient();
|
|
513
|
+
const response = (await client.rln.listChannels());
|
|
514
|
+
if (Array.isArray(response))
|
|
515
|
+
return response;
|
|
516
|
+
if (response && "channels" in response && Array.isArray(response.channels)) {
|
|
517
|
+
return response.channels;
|
|
518
|
+
}
|
|
519
|
+
return [];
|
|
373
520
|
}
|
|
374
521
|
catch (error) {
|
|
375
|
-
throw this.handleSdkError(error,
|
|
522
|
+
throw this.handleSdkError(error, "Failed to list channels");
|
|
376
523
|
}
|
|
377
524
|
}
|
|
378
525
|
async listPayments() {
|
|
379
526
|
if (!kaleidoClientManager.hasNode()) {
|
|
380
|
-
throw new ProtocolError(
|
|
527
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
381
528
|
}
|
|
382
529
|
try {
|
|
383
|
-
|
|
530
|
+
const client = kaleidoClientManager.getClient();
|
|
531
|
+
return await client.rln.listPayments();
|
|
384
532
|
}
|
|
385
533
|
catch (error) {
|
|
386
|
-
throw this.handleSdkError(error,
|
|
534
|
+
throw this.handleSdkError(error, "Failed to list payments");
|
|
387
535
|
}
|
|
388
536
|
}
|
|
389
537
|
async listTransfers(options) {
|
|
390
538
|
if (!kaleidoClientManager.hasNode()) {
|
|
391
|
-
throw new ProtocolError(
|
|
539
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
392
540
|
}
|
|
393
541
|
try {
|
|
542
|
+
const client = kaleidoClientManager.getClient();
|
|
394
543
|
if (!options?.asset_id) {
|
|
395
544
|
return { transfers: [] };
|
|
396
545
|
}
|
|
397
|
-
return await
|
|
546
|
+
return await client.rln.listTransfers({ asset_id: options.asset_id });
|
|
398
547
|
}
|
|
399
548
|
catch (error) {
|
|
400
|
-
throw this.handleSdkError(error,
|
|
549
|
+
throw this.handleSdkError(error, "Failed to list transfers");
|
|
401
550
|
}
|
|
402
551
|
}
|
|
403
552
|
// ========================================================================
|
|
@@ -405,107 +554,218 @@ export class RgbAdapter {
|
|
|
405
554
|
// ========================================================================
|
|
406
555
|
async createRgbInvoice(params) {
|
|
407
556
|
if (!kaleidoClientManager.hasNode()) {
|
|
408
|
-
throw new ProtocolError(
|
|
557
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
409
558
|
}
|
|
410
559
|
try {
|
|
411
|
-
const
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
560
|
+
const client = kaleidoClientManager.getClient();
|
|
561
|
+
const durationSeconds = (params.durationSeconds ||
|
|
562
|
+
params.duration_seconds ||
|
|
563
|
+
3600);
|
|
564
|
+
const invoiceReq = {
|
|
565
|
+
asset_id: (params.assetId || params.asset_id),
|
|
566
|
+
expiration_timestamp: Math.floor(Date.now() / 1000) + durationSeconds,
|
|
567
|
+
min_confirmations: (params.minConfirmations ||
|
|
568
|
+
params.min_confirmations ||
|
|
569
|
+
1),
|
|
570
|
+
witness: (params.witness ?? true),
|
|
417
571
|
...(params.assignment ? { assignment: params.assignment } : {}),
|
|
572
|
+
};
|
|
573
|
+
return await client.rln.createRgbInvoice(invoiceReq);
|
|
574
|
+
}
|
|
575
|
+
catch (error) {
|
|
576
|
+
throw this.handleSdkError(error, "Failed to create RGB invoice");
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
async createRgbUtxos(params = {}) {
|
|
580
|
+
if (!kaleidoClientManager.hasNode()) {
|
|
581
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
582
|
+
}
|
|
583
|
+
try {
|
|
584
|
+
const client = kaleidoClientManager.getClient();
|
|
585
|
+
await client.rln.createUtxos({
|
|
586
|
+
up_to: params.upTo ?? false,
|
|
587
|
+
num: params.num ?? 3,
|
|
588
|
+
size: params.size ?? 3000,
|
|
589
|
+
fee_rate: await this.resolveFeeRate(params.feeRate, "normal"),
|
|
590
|
+
skip_sync: false,
|
|
418
591
|
});
|
|
592
|
+
return { success: true };
|
|
419
593
|
}
|
|
420
594
|
catch (error) {
|
|
421
|
-
throw this.handleSdkError(error,
|
|
595
|
+
throw this.handleSdkError(error, "Failed to create RGB UTXOs");
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
async listRgbUnspents() {
|
|
599
|
+
if (!kaleidoClientManager.hasNode()) {
|
|
600
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
601
|
+
}
|
|
602
|
+
try {
|
|
603
|
+
const client = kaleidoClientManager.getClient();
|
|
604
|
+
const response = await client.rln.listUnspents();
|
|
605
|
+
return response;
|
|
606
|
+
}
|
|
607
|
+
catch (error) {
|
|
608
|
+
throw this.handleSdkError(error, "Failed to list unspent outputs");
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Resolve a sat/vB fee rate to use for an RGB on-chain operation.
|
|
613
|
+
*
|
|
614
|
+
* Thin wrapper around {@link resolveRgbFeeRatePolicy} that provides the
|
|
615
|
+
* `estimateFn` and `network` from the live adapter state. The pure
|
|
616
|
+
* policy lives outside the class so it can be unit-tested without
|
|
617
|
+
* spinning up a kaleido client.
|
|
618
|
+
*
|
|
619
|
+
* Closes [GL #26] for the RGB adapter — previously every RGB on-chain
|
|
620
|
+
* spend used a hardcoded `1` (createUtxos) or `5` (sendAsset, sendBtc)
|
|
621
|
+
* which is a regtest-era default. On a busy mainnet mempool that's
|
|
622
|
+
* effectively "never confirms".
|
|
623
|
+
*/
|
|
624
|
+
async resolveFeeRate(provided, urgency = "normal") {
|
|
625
|
+
return resolveRgbFeeRatePolicy({
|
|
626
|
+
provided,
|
|
627
|
+
urgency,
|
|
628
|
+
network: this.config?.network ?? null,
|
|
629
|
+
estimateFn: async (blocks) => {
|
|
630
|
+
try {
|
|
631
|
+
const { fee_rate } = await this.estimateRgbFee(blocks);
|
|
632
|
+
return fee_rate;
|
|
633
|
+
}
|
|
634
|
+
catch (err) {
|
|
635
|
+
log.warn(`[RgbAdapter] fee estimation failed (urgency=${urgency}, blocks=${blocks}):`, err);
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
});
|
|
640
|
+
}
|
|
641
|
+
async estimateRgbFee(blocks) {
|
|
642
|
+
if (!kaleidoClientManager.hasNode()) {
|
|
643
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
644
|
+
}
|
|
645
|
+
try {
|
|
646
|
+
const client = kaleidoClientManager.getClient();
|
|
647
|
+
const response = await client.rln.estimateFee({ blocks });
|
|
648
|
+
return { fee_rate: response?.fee_rate ?? 1 };
|
|
649
|
+
}
|
|
650
|
+
catch (error) {
|
|
651
|
+
throw this.handleSdkError(error, "Failed to estimate fee");
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
async getRgbDetailedBalance() {
|
|
655
|
+
if (!kaleidoClientManager.hasNode()) {
|
|
656
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
657
|
+
}
|
|
658
|
+
try {
|
|
659
|
+
const client = kaleidoClientManager.getClient();
|
|
660
|
+
const balance = await client.rln.getBtcBalance();
|
|
661
|
+
const empty = { settled: 0, future: 0, spendable: 0 };
|
|
662
|
+
return {
|
|
663
|
+
vanilla: balance?.vanilla ?? empty,
|
|
664
|
+
colored: balance?.colored ?? empty,
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
catch (error) {
|
|
668
|
+
throw this.handleSdkError(error, "Failed to get detailed BTC balance");
|
|
422
669
|
}
|
|
423
670
|
}
|
|
424
671
|
async decodeRgbInvoice(params) {
|
|
425
672
|
if (!kaleidoClientManager.hasNode()) {
|
|
426
|
-
throw new ProtocolError(
|
|
673
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
427
674
|
}
|
|
428
675
|
try {
|
|
429
|
-
|
|
676
|
+
const client = kaleidoClientManager.getClient();
|
|
677
|
+
return await client.rln.decodeRgbInvoice({
|
|
430
678
|
invoice: params.invoice || params,
|
|
431
679
|
});
|
|
432
680
|
}
|
|
433
681
|
catch (error) {
|
|
434
|
-
throw this.handleSdkError(error,
|
|
682
|
+
throw this.handleSdkError(error, "Failed to decode RGB invoice");
|
|
435
683
|
}
|
|
436
684
|
}
|
|
437
685
|
async getInvoiceStatus(params) {
|
|
438
686
|
if (!kaleidoClientManager.hasNode()) {
|
|
439
|
-
throw new ProtocolError(
|
|
687
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
440
688
|
}
|
|
441
689
|
try {
|
|
442
|
-
|
|
690
|
+
const client = kaleidoClientManager.getClient();
|
|
691
|
+
return await client.rln.getInvoiceStatus(params);
|
|
443
692
|
}
|
|
444
693
|
catch (error) {
|
|
445
|
-
throw this.handleSdkError(error,
|
|
694
|
+
throw this.handleSdkError(error, "Failed to get invoice status");
|
|
446
695
|
}
|
|
447
696
|
}
|
|
448
697
|
async sendAsset(params) {
|
|
449
698
|
if (!kaleidoClientManager.hasNode()) {
|
|
450
|
-
throw new ProtocolError(
|
|
699
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
451
700
|
}
|
|
452
701
|
try {
|
|
453
702
|
const client = kaleidoClientManager.getClient();
|
|
454
|
-
const assetId = params.assetId || params.asset_id;
|
|
455
|
-
const
|
|
456
|
-
const
|
|
457
|
-
|
|
703
|
+
const assetId = (params.assetId || params.asset_id);
|
|
704
|
+
const assignmentObj = params.assignment;
|
|
705
|
+
const amount = (params.amount ?? assignmentObj?.value);
|
|
706
|
+
// The SDK always requires an assignment; derive it from amount when not explicitly provided
|
|
707
|
+
const assignment = params.assignment ?? (amount != null ? { type: "Fungible", value: amount } : undefined);
|
|
708
|
+
const sendReq = {
|
|
458
709
|
donation: params.donation || false,
|
|
459
|
-
fee_rate: params.feeRate
|
|
710
|
+
fee_rate: await this.resolveFeeRate((params.feeRate ?? params.fee_rate), "normal"),
|
|
460
711
|
min_confirmations: 1,
|
|
461
712
|
recipient_map: {
|
|
462
|
-
[assetId]: [
|
|
463
|
-
|
|
713
|
+
[assetId]: [
|
|
714
|
+
{
|
|
715
|
+
recipient_id: (params.recipientId ||
|
|
716
|
+
params.recipient_id),
|
|
464
717
|
assignment,
|
|
465
|
-
transport_endpoints: params.transportEndpoints ||
|
|
718
|
+
transport_endpoints: (params.transportEndpoints ||
|
|
719
|
+
params.transport_endpoints ||
|
|
720
|
+
[]),
|
|
466
721
|
...(params.witness_data ? { witness_data: params.witness_data } : {}),
|
|
467
|
-
}
|
|
722
|
+
},
|
|
723
|
+
],
|
|
468
724
|
},
|
|
469
|
-
// skip_sync is a valid runtime param; cast bridges kaleido-sdk type drift.
|
|
470
725
|
skip_sync: false,
|
|
471
|
-
}
|
|
726
|
+
};
|
|
727
|
+
return await client.rln.sendRgb(sendReq);
|
|
472
728
|
}
|
|
473
729
|
catch (error) {
|
|
474
|
-
throw this.handleSdkError(error,
|
|
730
|
+
throw this.handleSdkError(error, "Failed to send RGB asset");
|
|
475
731
|
}
|
|
476
732
|
}
|
|
477
733
|
async sendBtcOnchain(params) {
|
|
478
734
|
if (!kaleidoClientManager.hasNode()) {
|
|
479
|
-
throw new ProtocolError(
|
|
735
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
480
736
|
}
|
|
481
737
|
try {
|
|
482
|
-
|
|
738
|
+
const client = kaleidoClientManager.getClient();
|
|
739
|
+
return await client.rln.sendBtc({
|
|
483
740
|
address: params.address,
|
|
484
741
|
amount: params.amount,
|
|
485
|
-
fee_rate: params.feeRate
|
|
742
|
+
fee_rate: await this.resolveFeeRate(params.feeRate, "normal"),
|
|
486
743
|
skip_sync: false,
|
|
487
744
|
});
|
|
488
745
|
}
|
|
489
746
|
catch (error) {
|
|
490
|
-
throw this.handleSdkError(error,
|
|
747
|
+
throw this.handleSdkError(error, "Failed to send BTC on-chain");
|
|
491
748
|
}
|
|
492
749
|
}
|
|
493
750
|
// ========================================================================
|
|
494
|
-
// Swap Operations
|
|
751
|
+
// Swap Operations
|
|
495
752
|
// ========================================================================
|
|
496
753
|
supportsSwaps() {
|
|
497
|
-
|
|
754
|
+
// Swaps via Kaleidoswap require a configured maker URL — without one
|
|
755
|
+
// every quote request errors. The UI must reflect that.
|
|
756
|
+
return !!this.config?.makerUrl;
|
|
498
757
|
}
|
|
499
758
|
async getSwapQuote(request) {
|
|
500
759
|
if (!this.isConnected()) {
|
|
501
|
-
throw new ProtocolError(
|
|
760
|
+
throw new ProtocolError("Not connected", "RGB_LN", "NOT_CONNECTED");
|
|
502
761
|
}
|
|
762
|
+
// Check if maker is configured
|
|
503
763
|
if (!this.config?.makerUrl) {
|
|
504
|
-
throw new ProtocolError(
|
|
764
|
+
throw new ProtocolError("Maker API not configured. Swaps are not available in node-only mode.", "RGB_LN", "MAKER_NOT_CONFIGURED");
|
|
505
765
|
}
|
|
506
766
|
try {
|
|
507
767
|
const client = kaleidoClientManager.getClient();
|
|
508
|
-
const quoteResponse = await client.maker.getQuote({
|
|
768
|
+
const quoteResponse = (await client.maker.getQuote({
|
|
509
769
|
from_asset: {
|
|
510
770
|
asset_id: request.fromAsset,
|
|
511
771
|
layer: SdkLayer.RGB_LN,
|
|
@@ -516,7 +776,7 @@ export class RgbAdapter {
|
|
|
516
776
|
layer: SdkLayer.RGB_LN,
|
|
517
777
|
amount: request.toAmount,
|
|
518
778
|
},
|
|
519
|
-
});
|
|
779
|
+
}));
|
|
520
780
|
return {
|
|
521
781
|
id: quoteResponse.rfq_id,
|
|
522
782
|
fromAsset: quoteResponse.from_asset.asset_id,
|
|
@@ -534,285 +794,119 @@ export class RgbAdapter {
|
|
|
534
794
|
},
|
|
535
795
|
},
|
|
536
796
|
expiresAt: quoteResponse.expires_at,
|
|
537
|
-
provider:
|
|
797
|
+
provider: "Kaleidoswap",
|
|
538
798
|
};
|
|
539
799
|
}
|
|
540
800
|
catch (error) {
|
|
541
|
-
throw this.handleSdkError(error,
|
|
801
|
+
throw this.handleSdkError(error, "Maker API connection failed");
|
|
542
802
|
}
|
|
543
803
|
}
|
|
544
804
|
async executeSwap(quote) {
|
|
545
805
|
if (!this.isConnected()) {
|
|
546
|
-
throw new ProtocolError(
|
|
806
|
+
throw new ProtocolError("Not connected", "RGB_LN", "NOT_CONNECTED");
|
|
547
807
|
}
|
|
808
|
+
// Check if maker is configured
|
|
548
809
|
if (!this.config?.makerUrl) {
|
|
549
|
-
throw new ProtocolError(
|
|
810
|
+
throw new ProtocolError("Maker API not configured. Swaps are not available in node-only mode.", "RGB_LN", "MAKER_NOT_CONFIGURED");
|
|
550
811
|
}
|
|
551
812
|
try {
|
|
552
813
|
const client = kaleidoClientManager.getClient();
|
|
553
814
|
const quoteAny = quote;
|
|
554
|
-
const
|
|
555
|
-
rfq_id: quoteAny.rfqId || quote.id ||
|
|
556
|
-
from_asset: {
|
|
557
|
-
|
|
558
|
-
|
|
815
|
+
const quote_request = {
|
|
816
|
+
rfq_id: quoteAny.rfqId || quote.id || "",
|
|
817
|
+
from_asset: {
|
|
818
|
+
asset_id: quote.fromAsset,
|
|
819
|
+
amount: quote.fromAmount,
|
|
820
|
+
layer: quoteAny.fromLayer || "RGB_LN",
|
|
821
|
+
},
|
|
822
|
+
to_asset: {
|
|
823
|
+
asset_id: quote.toAsset,
|
|
824
|
+
amount: quote.toAmount,
|
|
825
|
+
layer: quoteAny.toLayer || "RGB_LN",
|
|
826
|
+
},
|
|
827
|
+
receiver_address: {
|
|
828
|
+
address: quoteAny.receiverAddress || "",
|
|
829
|
+
format: "BTC_ADDRESS",
|
|
830
|
+
},
|
|
559
831
|
min_onchain_conf: 1,
|
|
560
|
-
refund_address:
|
|
561
|
-
email:
|
|
832
|
+
refund_address: "",
|
|
833
|
+
email: "",
|
|
562
834
|
};
|
|
563
|
-
const result = await client.maker.createSwapOrder(
|
|
835
|
+
const result = await client.maker.createSwapOrder(quote_request);
|
|
564
836
|
const swapResult = result;
|
|
565
|
-
const swapId = (swapResult.order_id ?? swapResult.id ??
|
|
837
|
+
const swapId = (swapResult.order_id ?? swapResult.id ?? "");
|
|
566
838
|
if (swapId && swapResult.access_token) {
|
|
567
839
|
this.swapAccessTokens.set(swapId, swapResult.access_token);
|
|
568
840
|
}
|
|
569
841
|
return {
|
|
570
842
|
swapId,
|
|
571
|
-
paymentHash: (swapResult.payment_hash ??
|
|
572
|
-
status:
|
|
843
|
+
paymentHash: (swapResult.payment_hash ?? ""),
|
|
844
|
+
status: mapSwapStatus(swapResult.status),
|
|
573
845
|
quote,
|
|
574
846
|
timestamp: Date.now(),
|
|
575
847
|
};
|
|
576
848
|
}
|
|
577
849
|
catch (error) {
|
|
578
|
-
throw this.handleSdkError(error,
|
|
850
|
+
throw this.handleSdkError(error, "Failed to execute swap");
|
|
579
851
|
}
|
|
580
852
|
}
|
|
581
853
|
async getSwapStatus(swapId) {
|
|
582
854
|
if (!this.isConnected()) {
|
|
583
|
-
throw new ProtocolError(
|
|
855
|
+
throw new ProtocolError("Not connected", "RGB_LN", "NOT_CONNECTED");
|
|
584
856
|
}
|
|
585
857
|
try {
|
|
586
858
|
const client = kaleidoClientManager.getClient();
|
|
587
859
|
const accessToken = this.swapAccessTokens.get(swapId);
|
|
588
860
|
if (!accessToken) {
|
|
589
|
-
throw new ProtocolError(
|
|
861
|
+
throw new ProtocolError("Missing swap access token for status lookup", "RGB_LN", "SWAP_ACCESS_TOKEN_MISSING");
|
|
590
862
|
}
|
|
591
|
-
const status = await client.maker.getSwapOrderStatus({
|
|
863
|
+
const status = (await client.maker.getSwapOrderStatus({
|
|
592
864
|
order_id: swapId,
|
|
593
865
|
access_token: accessToken,
|
|
594
|
-
});
|
|
866
|
+
}));
|
|
595
867
|
const order = (status.order ?? status);
|
|
596
868
|
return {
|
|
597
869
|
swapId,
|
|
598
|
-
status:
|
|
599
|
-
quote: {},
|
|
870
|
+
status: mapSwapStatus(order.status),
|
|
871
|
+
quote: {}, // Would need to store original quote
|
|
600
872
|
timestamp: order.created_at || Date.now(),
|
|
601
873
|
};
|
|
602
874
|
}
|
|
603
875
|
catch (error) {
|
|
604
|
-
throw this.handleSdkError(error,
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
// ========================================================================
|
|
608
|
-
// Protocol-Specific Operations (escape hatch)
|
|
609
|
-
// ========================================================================
|
|
610
|
-
async executeProtocolOperation(operation, params) {
|
|
611
|
-
if (!kaleidoClientManager.hasNode()) {
|
|
612
|
-
throw new ProtocolError('Node not configured', 'RGB', 'NODE_NOT_CONFIGURED');
|
|
613
|
-
}
|
|
614
|
-
const client = kaleidoClientManager.getClient();
|
|
615
|
-
switch (operation) {
|
|
616
|
-
case 'initNode':
|
|
617
|
-
return client.rln.initWallet(params);
|
|
618
|
-
case 'unlockNode':
|
|
619
|
-
return client.rln.unlockWallet(params);
|
|
620
|
-
case 'lockNode':
|
|
621
|
-
return client.rln.lockWallet();
|
|
622
|
-
case 'createUtxos':
|
|
623
|
-
return client.rln.createUtxos(params);
|
|
624
|
-
case 'issueAssetNIA':
|
|
625
|
-
return client.rln.issueAssetNIA(params);
|
|
626
|
-
case 'issueAssetCFA':
|
|
627
|
-
return client.rln.issueAssetCFA(params);
|
|
628
|
-
case 'estimateFee':
|
|
629
|
-
return client.rln.estimateFee(params);
|
|
630
|
-
case 'failTransfers':
|
|
631
|
-
return client.rln.failTransfers(params);
|
|
632
|
-
case 'refreshTransfers':
|
|
633
|
-
return client.rln.refreshTransfers(params);
|
|
634
|
-
case 'sync':
|
|
635
|
-
return client.rln.syncRgbWallet();
|
|
636
|
-
case 'connectPeer':
|
|
637
|
-
return client.rln.connectPeer(params);
|
|
638
|
-
case 'disconnectPeer':
|
|
639
|
-
return client.rln.disconnectPeer(params);
|
|
640
|
-
case 'listPeers':
|
|
641
|
-
return client.rln.listPeers();
|
|
642
|
-
case 'openChannel':
|
|
643
|
-
return client.rln.openChannel(params);
|
|
644
|
-
case 'closeChannel':
|
|
645
|
-
return client.rln.closeChannel(params);
|
|
646
|
-
case 'getAssetMetadata':
|
|
647
|
-
return client.rln.getAssetMetadata(params);
|
|
648
|
-
case 'getTakerPubkey':
|
|
649
|
-
return client.rln.getTakerPubkey();
|
|
650
|
-
case 'whitelistSwap':
|
|
651
|
-
return client.rln.whitelistSwap(params);
|
|
652
|
-
case 'initSwap':
|
|
653
|
-
return client.maker.initSwap(params);
|
|
654
|
-
case 'confirmSwap':
|
|
655
|
-
return client.maker.executeSwap(params);
|
|
656
|
-
case 'listSwaps':
|
|
657
|
-
return client.rln.listSwaps();
|
|
658
|
-
case 'getSwap':
|
|
659
|
-
return client.rln.getSwap(params);
|
|
660
|
-
case 'getLspInfo':
|
|
661
|
-
return client.maker.getLspInfo();
|
|
662
|
-
case 'createLspOrder':
|
|
663
|
-
return client.maker.createLspOrder(params);
|
|
664
|
-
case 'getLspOrder':
|
|
665
|
-
return client.maker.getLspOrder(params);
|
|
666
|
-
case 'estimateLspFees':
|
|
667
|
-
return client.maker.estimateLspFees(params);
|
|
668
|
-
default:
|
|
669
|
-
throw new ProtocolError(`Unknown operation: ${operation}`, 'RGB', 'UNKNOWN_OPERATION');
|
|
876
|
+
throw this.handleSdkError(error, "Failed to get swap status");
|
|
670
877
|
}
|
|
671
878
|
}
|
|
672
879
|
// ========================================================================
|
|
673
|
-
//
|
|
880
|
+
// SDK ↔ unified-shape converters moved to ./converters.ts (this-free;
|
|
881
|
+
// covered by tests/unit/rgb-converters.test.ts).
|
|
674
882
|
// ========================================================================
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
return {
|
|
678
|
-
id: 'BTC',
|
|
679
|
-
name: 'Bitcoin (RGB Node)',
|
|
680
|
-
ticker: 'BTC',
|
|
681
|
-
precision: 8,
|
|
682
|
-
protocol: 'RGB',
|
|
683
|
-
layer: 'BTC_L1',
|
|
684
|
-
balance,
|
|
685
|
-
capabilities: {
|
|
686
|
-
canSend: true, canReceive: true, canSwap: true,
|
|
687
|
-
supportsLightning: true, supportsOnchain: true,
|
|
688
|
-
},
|
|
689
|
-
};
|
|
690
|
-
}
|
|
691
|
-
convertNodeAssetToUnified(asset) {
|
|
692
|
-
return {
|
|
693
|
-
id: asset.asset_id,
|
|
694
|
-
name: asset.name,
|
|
695
|
-
ticker: asset.ticker,
|
|
696
|
-
precision: asset.precision || 8,
|
|
697
|
-
protocol: 'RGB',
|
|
698
|
-
layer: 'RGB_LN',
|
|
699
|
-
balance: this.convertNodeBalance(asset.balance),
|
|
700
|
-
capabilities: {
|
|
701
|
-
canSend: true, canReceive: true, canSwap: false,
|
|
702
|
-
supportsLightning: true, supportsOnchain: true,
|
|
703
|
-
},
|
|
704
|
-
};
|
|
705
|
-
}
|
|
706
|
-
convertBtcBalance(btcBalance) {
|
|
707
|
-
const vanilla = btcBalance.vanilla ?? { settled: 0, future: 0, spendable: 0 };
|
|
708
|
-
return {
|
|
709
|
-
total: vanilla.settled || 0,
|
|
710
|
-
available: vanilla.spendable || 0,
|
|
711
|
-
pending: vanilla.future || 0,
|
|
712
|
-
totalDisplay: this.formatAmount(vanilla.settled || 0, 8),
|
|
713
|
-
availableDisplay: this.formatAmount(vanilla.spendable || 0, 8),
|
|
714
|
-
};
|
|
715
|
-
}
|
|
716
|
-
convertSdkBalance(balance) {
|
|
717
|
-
return {
|
|
718
|
-
total: balance.settled || 0,
|
|
719
|
-
available: balance.spendable || 0,
|
|
720
|
-
pending: balance.future || 0,
|
|
721
|
-
locked: balance.offchain_outbound || 0,
|
|
722
|
-
totalDisplay: this.formatAmount(balance.settled || 0, 8),
|
|
723
|
-
availableDisplay: this.formatAmount(balance.spendable || 0, 8),
|
|
724
|
-
};
|
|
725
|
-
}
|
|
726
|
-
convertNodeBalance(balance) {
|
|
727
|
-
const total = balance?.settled || 0;
|
|
728
|
-
const available = balance?.spendable || 0;
|
|
729
|
-
const pending = balance?.future || 0;
|
|
730
|
-
return {
|
|
731
|
-
total, available, pending,
|
|
732
|
-
locked: balance?.offchain_outbound || 0,
|
|
733
|
-
totalDisplay: this.formatAmount(total, 8),
|
|
734
|
-
availableDisplay: this.formatAmount(available, 8),
|
|
735
|
-
};
|
|
736
|
-
}
|
|
737
|
-
convertTransferToTransaction(transfer) {
|
|
738
|
-
return {
|
|
739
|
-
id: transfer.txid || `tx_${Date.now()}`,
|
|
740
|
-
type: this.mapTransferType(transfer.kind),
|
|
741
|
-
status: this.mapTransferStatus(transfer.status),
|
|
742
|
-
timestamp: transfer.created_at || Date.now(),
|
|
743
|
-
amount: transfer.amount || 0,
|
|
744
|
-
amountDisplay: this.formatAmount(transfer.amount || 0, 8),
|
|
745
|
-
fee: transfer.fee,
|
|
746
|
-
feeDisplay: this.formatAmount(transfer.fee || 0, 8),
|
|
747
|
-
asset: {},
|
|
748
|
-
from: transfer.sender,
|
|
749
|
-
to: transfer.recipient,
|
|
750
|
-
protocolData: transfer,
|
|
751
|
-
};
|
|
752
|
-
}
|
|
753
|
-
mapTransferType(kind) {
|
|
754
|
-
if (!kind)
|
|
755
|
-
return 'send';
|
|
756
|
-
if (kind.includes('receive') || kind.includes('ReceiveAsset'))
|
|
757
|
-
return 'receive';
|
|
758
|
-
if (kind.includes('send') || kind.includes('SendAsset'))
|
|
759
|
-
return 'send';
|
|
760
|
-
return 'send';
|
|
761
|
-
}
|
|
762
|
-
mapTransferStatus(status) {
|
|
763
|
-
if (!status)
|
|
764
|
-
return 'pending';
|
|
765
|
-
if (status === 'Settled' || status === 'settled')
|
|
766
|
-
return 'confirmed';
|
|
767
|
-
if (status === 'Failed' || status === 'failed')
|
|
768
|
-
return 'failed';
|
|
769
|
-
return 'pending';
|
|
770
|
-
}
|
|
771
|
-
mapPaymentStatus(status) {
|
|
772
|
-
if (!status)
|
|
773
|
-
return 'pending';
|
|
774
|
-
if (status === 'succeeded' || status === 'success' || status === 'Succeeded')
|
|
775
|
-
return 'confirmed';
|
|
776
|
-
if (status === 'failed' || status === 'Failed')
|
|
777
|
-
return 'failed';
|
|
778
|
-
return 'pending';
|
|
779
|
-
}
|
|
780
|
-
mapSwapStatus(status) {
|
|
781
|
-
if (!status)
|
|
782
|
-
return 'pending';
|
|
783
|
-
if (status === 'completed' || status === 'success' || status === 'Completed')
|
|
784
|
-
return 'confirmed';
|
|
785
|
-
if (status === 'failed' || status === 'error' || status === 'Failed')
|
|
786
|
-
return 'failed';
|
|
787
|
-
return 'pending';
|
|
788
|
-
}
|
|
789
|
-
formatAmount(amount, precision) {
|
|
790
|
-
return (amount / Math.pow(10, precision)).toFixed(precision);
|
|
791
|
-
}
|
|
883
|
+
// Pure mappers + formatAmount moved to ./helpers.ts (this-free; covered
|
|
884
|
+
// by tests/unit/rgb-helpers.test.ts).
|
|
792
885
|
// ========================================================================
|
|
793
886
|
// Error Handling
|
|
794
887
|
// ========================================================================
|
|
795
888
|
handleSdkError(error, context) {
|
|
796
889
|
if (error instanceof NodeNotConfiguredError) {
|
|
797
|
-
throw new ProtocolError(
|
|
890
|
+
throw new ProtocolError("Node not configured", "RGB_LN", "NODE_NOT_CONFIGURED");
|
|
798
891
|
}
|
|
799
892
|
else if (error instanceof QuoteExpiredError) {
|
|
800
|
-
throw new ProtocolError(
|
|
893
|
+
throw new ProtocolError("Quote expired", "RGB_LN", "QUOTE_EXPIRED");
|
|
801
894
|
}
|
|
802
895
|
else if (error instanceof SdkInsufficientBalanceError) {
|
|
803
|
-
throw new InsufficientBalanceError(
|
|
896
|
+
throw new InsufficientBalanceError("Insufficient balance", "RGB_LN", 0, 0);
|
|
804
897
|
}
|
|
805
898
|
else if (error instanceof APIError) {
|
|
806
|
-
throw new ProtocolError(`${context}: ${error.message}`,
|
|
899
|
+
throw new ProtocolError(`${context}: ${error.message}`, "RGB_LN", "API_ERROR", error);
|
|
807
900
|
}
|
|
808
901
|
else if (error instanceof NetworkError) {
|
|
809
|
-
throw new ConnectionError(`${context}: Network error - ${error.message}`,
|
|
902
|
+
throw new ConnectionError(`${context}: Network error - ${error.message}`, "RGB_LN", error);
|
|
810
903
|
}
|
|
811
904
|
else if (error instanceof KaleidoError) {
|
|
812
|
-
throw new ProtocolError(`${context}: ${error.message}`,
|
|
905
|
+
throw new ProtocolError(`${context}: ${error.message}`, "RGB_LN", "SDK_ERROR", error);
|
|
813
906
|
}
|
|
814
|
-
|
|
815
|
-
|
|
907
|
+
// Default error handling
|
|
908
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
909
|
+
throw new ProtocolError(`${context}: ${msg}`, "RGB_LN", "UNKNOWN_ERROR", error instanceof Error ? error : undefined);
|
|
816
910
|
}
|
|
817
911
|
}
|
|
818
912
|
//# sourceMappingURL=RgbAdapter.js.map
|