@kaleidorg/wallet-engine 1.0.0-beta.32 → 1.0.0-beta.34
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/dist/adapters/SparkAdapter.d.ts +93 -16
- package/dist/adapters/SparkAdapter.d.ts.map +1 -1
- package/dist/adapters/SparkAdapter.js +831 -171
- 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/spark.d.ts +11 -0
- package/dist/adapters/spark.d.ts.map +1 -0
- package/dist/adapters/spark.js +11 -0
- package/dist/adapters/spark.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/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 +54 -9
- package/dist/lib/spark-client-manager.d.ts.map +1 -1
- package/dist/lib/spark-client-manager.js +176 -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/package.json +11 -2
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Spark Client Manager
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Manages the lifecycle of a SparkWallet from `@buildonspark/spark-sdk`.
|
|
5
|
+
* The native SDK inlines WASM as a binary buffer (no dynamic import needed)
|
|
6
|
+
* and uses gRPC over fetch, both of which are supported in an MV3
|
|
7
|
+
* ServiceWorker and in Node — so the SDK is imported statically by default.
|
|
8
|
+
*
|
|
9
|
+
* Platform seam: consumers may inject an `SparkSdkFactory` via
|
|
10
|
+
* `setSdkFactory()` to avoid the static import path (e.g. React Native /
|
|
11
|
+
* Metro, where `import('@buildonspark/spark-sdk')` mis-bundles). When no
|
|
12
|
+
* factory is set the static `SparkWallet.initialize` path is used.
|
|
5
13
|
*/
|
|
6
14
|
import type { SparkConfig } from '../types/spark.js';
|
|
7
|
-
|
|
15
|
+
import { SparkReadonlyClient } from '@buildonspark/spark-sdk';
|
|
8
16
|
/**
|
|
9
|
-
* SDK factory injected by consumers.
|
|
10
|
-
*
|
|
17
|
+
* SDK factory injected by consumers to avoid the static import path.
|
|
18
|
+
* Optional — when absent the manager uses the statically-imported SDK.
|
|
11
19
|
*/
|
|
12
20
|
export interface SparkSdkFactory {
|
|
13
21
|
initializeWallet: (config: {
|
|
@@ -21,20 +29,57 @@ export interface SparkSdkFactory {
|
|
|
21
29
|
}
|
|
22
30
|
declare class SparkClientManager {
|
|
23
31
|
private wallet;
|
|
32
|
+
private readonlyClient;
|
|
24
33
|
private config;
|
|
34
|
+
/** Serializes concurrent initialize() calls to prevent races during SW restart. */
|
|
25
35
|
private _initPromise;
|
|
36
|
+
/** Serializes concurrent readonly client initialization. */
|
|
37
|
+
private _readonlyInitPromise;
|
|
38
|
+
/** Optional SDK factory escape hatch (React Native / Metro). */
|
|
26
39
|
private sdkFactory;
|
|
27
40
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
41
|
+
* Inject an SDK factory before calling initialize(). Avoids the static
|
|
42
|
+
* `@buildonspark/spark-sdk` import path on platforms where it mis-bundles.
|
|
30
43
|
*/
|
|
31
44
|
setSdkFactory(factory: SparkSdkFactory): void;
|
|
45
|
+
/**
|
|
46
|
+
* Initialize the SparkWallet.
|
|
47
|
+
* Concurrent calls share the same in-flight promise.
|
|
48
|
+
*/
|
|
32
49
|
initialize(config: SparkConfig): Promise<void>;
|
|
33
50
|
private _doInitialize;
|
|
34
|
-
|
|
51
|
+
/**
|
|
52
|
+
* Wrap `transferTokens` so every outgoing token transfer — regardless of
|
|
53
|
+
* caller (SparkAdapter.sendAsset, Flashnet swaps / liquidity, or any future
|
|
54
|
+
* path) — is persisted to the sent-token outbox.
|
|
55
|
+
*
|
|
56
|
+
* The Spark SDK reports no direction for token transactions, so without a
|
|
57
|
+
* local record an outgoing transfer is indistinguishable from a receive
|
|
58
|
+
* (and a send with no change output is not returned by the server at all).
|
|
59
|
+
* Recording at this single choke point guarantees no token send is missed.
|
|
60
|
+
*
|
|
61
|
+
* Metadata is minimal here; SparkAdapter.sendAsset re-saves the same hash
|
|
62
|
+
* with full token metadata, which supersedes this entry (records are keyed
|
|
63
|
+
* by hash). Paths with no richer recorder degrade to a generic "TOKEN" label.
|
|
64
|
+
*/
|
|
65
|
+
private installTokenSendRecorder;
|
|
66
|
+
/**
|
|
67
|
+
* Return the active wallet instance.
|
|
68
|
+
* Throws if initialize() has not been called successfully.
|
|
69
|
+
*/
|
|
70
|
+
getWallet(): any;
|
|
35
71
|
isInitialized(): boolean;
|
|
36
|
-
getWallet(): SparkWallet;
|
|
37
72
|
getConfig(): SparkConfig | null;
|
|
73
|
+
getReadonlyClient(): Promise<SparkReadonlyClient>;
|
|
74
|
+
/**
|
|
75
|
+
* Register an event listener on the wallet (e.g. incoming transfer notifications).
|
|
76
|
+
*/
|
|
77
|
+
on(event: string, listener: (...args: unknown[]) => void): void;
|
|
78
|
+
/**
|
|
79
|
+
* Disconnect and release resources.
|
|
80
|
+
*/
|
|
81
|
+
disconnect(): Promise<void>;
|
|
82
|
+
reset(): void;
|
|
38
83
|
}
|
|
39
84
|
export declare const sparkClientManager: SparkClientManager;
|
|
40
85
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spark-client-manager.d.ts","sourceRoot":"","sources":["../../src/lib/spark-client-manager.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"spark-client-manager.d.ts","sourceRoot":"","sources":["../../src/lib/spark-client-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,OAAO,EAAe,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AA+C1E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,CAAC,MAAM,EAAE;QACzB,cAAc,EAAE,MAAM,CAAA;QACtB,OAAO,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAC7B,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC,CAAA;CAC/B;AAMD,cAAM,kBAAkB;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,MAAM,CAA2B;IACzC,mFAAmF;IACnF,OAAO,CAAC,YAAY,CAA6B;IACjD,4DAA4D;IAC5D,OAAO,CAAC,oBAAoB,CAA4C;IACxE,gEAAgE;IAChE,OAAO,CAAC,UAAU,CAA+B;IAEjD;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAI7C;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;YAShC,aAAa;IA2C3B;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,wBAAwB;IAwBhC;;;OAGG;IACH,SAAS,IAAI,GAAG;IAOhB,aAAa,IAAI,OAAO;IAIxB,SAAS,IAAI,WAAW,GAAG,IAAI;IAIzB,iBAAiB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAqBvD;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,IAAI;IAO/D;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAejC,KAAK,IAAI,IAAI;CAQd;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAA"}
|
|
@@ -1,22 +1,87 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Spark Client Manager
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Manages the lifecycle of a SparkWallet from `@buildonspark/spark-sdk`.
|
|
5
|
+
* The native SDK inlines WASM as a binary buffer (no dynamic import needed)
|
|
6
|
+
* and uses gRPC over fetch, both of which are supported in an MV3
|
|
7
|
+
* ServiceWorker and in Node — so the SDK is imported statically by default.
|
|
8
|
+
*
|
|
9
|
+
* Platform seam: consumers may inject an `SparkSdkFactory` via
|
|
10
|
+
* `setSdkFactory()` to avoid the static import path (e.g. React Native /
|
|
11
|
+
* Metro, where `import('@buildonspark/spark-sdk')` mis-bundles). When no
|
|
12
|
+
* factory is set the static `SparkWallet.initialize` path is used.
|
|
5
13
|
*/
|
|
14
|
+
import { log } from './log.js';
|
|
15
|
+
import { SparkWallet, SparkReadonlyClient } from '@buildonspark/spark-sdk';
|
|
16
|
+
import { saveSentTokenRecord } from './spark-sent-token-records.js';
|
|
17
|
+
import { bech32 } from '@scure/base';
|
|
18
|
+
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
19
|
+
const NETWORK_MAP = {
|
|
20
|
+
mainnet: 'MAINNET',
|
|
21
|
+
testnet: 'TESTNET',
|
|
22
|
+
regtest: 'REGTEST',
|
|
23
|
+
signet: 'SIGNET',
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Decode an `nsec1…` bech32 secret into a 32-byte private key hex, or null.
|
|
27
|
+
* Mirrors the extension's `importNostrPrivateKey` nsec branch without pulling
|
|
28
|
+
* in the nostr module — the Spark SDK accepts a raw hex seed via
|
|
29
|
+
* `mnemonicOrSeed`, so an nsec-rooted wallet resolves to its hex private key.
|
|
30
|
+
*/
|
|
31
|
+
function nsecToPrivateKeyHex(input) {
|
|
32
|
+
try {
|
|
33
|
+
const decoded = bech32.decode(input, 1023);
|
|
34
|
+
if (decoded.prefix !== 'nsec')
|
|
35
|
+
return null;
|
|
36
|
+
const data = bech32.fromWords(decoded.words);
|
|
37
|
+
if (data.length !== 32)
|
|
38
|
+
return null;
|
|
39
|
+
return bytesToHex(Uint8Array.from(data));
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a Spark wallet secret to the value handed to the SDK. Accepts an
|
|
47
|
+
* `nsec1…` root secret (resolved to hex), otherwise passes the input through
|
|
48
|
+
* unchanged (the SDK handles BIP39 mnemonics and hex seeds itself).
|
|
49
|
+
*/
|
|
50
|
+
function resolveSparkMnemonicOrSeed(walletSecret) {
|
|
51
|
+
const trimmed = walletSecret.trim();
|
|
52
|
+
if (trimmed.startsWith('nsec1')) {
|
|
53
|
+
const hex = nsecToPrivateKeyHex(trimmed);
|
|
54
|
+
if (hex)
|
|
55
|
+
return hex;
|
|
56
|
+
}
|
|
57
|
+
return walletSecret;
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// SparkClientManager
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
6
62
|
class SparkClientManager {
|
|
7
63
|
constructor() {
|
|
8
64
|
this.wallet = null;
|
|
65
|
+
this.readonlyClient = null;
|
|
9
66
|
this.config = null;
|
|
67
|
+
/** Serializes concurrent initialize() calls to prevent races during SW restart. */
|
|
10
68
|
this._initPromise = null;
|
|
69
|
+
/** Serializes concurrent readonly client initialization. */
|
|
70
|
+
this._readonlyInitPromise = null;
|
|
71
|
+
/** Optional SDK factory escape hatch (React Native / Metro). */
|
|
11
72
|
this.sdkFactory = null;
|
|
12
73
|
}
|
|
13
74
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
75
|
+
* Inject an SDK factory before calling initialize(). Avoids the static
|
|
76
|
+
* `@buildonspark/spark-sdk` import path on platforms where it mis-bundles.
|
|
16
77
|
*/
|
|
17
78
|
setSdkFactory(factory) {
|
|
18
79
|
this.sdkFactory = factory;
|
|
19
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Initialize the SparkWallet.
|
|
83
|
+
* Concurrent calls share the same in-flight promise.
|
|
84
|
+
*/
|
|
20
85
|
initialize(config) {
|
|
21
86
|
if (this._initPromise)
|
|
22
87
|
return this._initPromise;
|
|
@@ -27,75 +92,151 @@ class SparkClientManager {
|
|
|
27
92
|
}
|
|
28
93
|
async _doInitialize(config) {
|
|
29
94
|
if (this.wallet) {
|
|
30
|
-
|
|
95
|
+
log.warn('[SparkClientManager] Wallet already initialized, re-initializing...');
|
|
31
96
|
await this.disconnect();
|
|
32
97
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
testnet: 'TESTNET',
|
|
36
|
-
regtest: 'REGTEST',
|
|
37
|
-
signet: 'SIGNET',
|
|
38
|
-
};
|
|
39
|
-
const network = networkMap[config.network ?? 'mainnet'] ?? 'MAINNET';
|
|
98
|
+
const network = NETWORK_MAP[config.network ?? 'mainnet'] ?? 'MAINNET';
|
|
99
|
+
const mnemonicOrSeed = resolveSparkMnemonicOrSeed(config.mnemonic);
|
|
40
100
|
try {
|
|
41
101
|
let result;
|
|
42
102
|
if (this.sdkFactory) {
|
|
43
103
|
result = await this.sdkFactory.initializeWallet({
|
|
44
|
-
mnemonicOrSeed
|
|
104
|
+
mnemonicOrSeed,
|
|
45
105
|
options: { network },
|
|
46
106
|
});
|
|
47
107
|
}
|
|
48
108
|
else {
|
|
49
|
-
// Fallback: dynamic import (works in Node/extension, may fail in Metro)
|
|
50
|
-
const { SparkWallet } = await import('@buildonspark/spark-sdk');
|
|
51
109
|
result = await SparkWallet.initialize({
|
|
52
|
-
mnemonicOrSeed
|
|
110
|
+
mnemonicOrSeed,
|
|
53
111
|
options: { network: network },
|
|
54
112
|
});
|
|
55
113
|
}
|
|
56
114
|
this.wallet = result.wallet;
|
|
57
115
|
this.config = config;
|
|
58
|
-
|
|
116
|
+
this.installTokenSendRecorder(this.wallet);
|
|
117
|
+
log.info('[SparkClientManager] SparkWallet initialized, network:', network);
|
|
118
|
+
// Enable privacy mode so BTC transactions are hidden from public APIs
|
|
59
119
|
try {
|
|
60
120
|
await this.wallet.setPrivacyEnabled(true);
|
|
61
|
-
|
|
121
|
+
log.info('[SparkClientManager] Privacy mode enabled');
|
|
62
122
|
}
|
|
63
|
-
catch (
|
|
64
|
-
const
|
|
65
|
-
|
|
123
|
+
catch (privacyError) {
|
|
124
|
+
const privMsg = privacyError instanceof Error ? privacyError.message : String(privacyError);
|
|
125
|
+
log.warn('[SparkClientManager] Failed to enable privacy mode:', privMsg);
|
|
66
126
|
}
|
|
67
127
|
}
|
|
68
128
|
catch (error) {
|
|
69
129
|
this.wallet = null;
|
|
70
130
|
const msg = error instanceof Error ? error.message : String(error);
|
|
71
|
-
throw new Error(`Failed to initialize SparkWallet: ${msg}`);
|
|
131
|
+
throw Object.assign(new Error(`Failed to initialize SparkWallet: ${msg}`), { cause: error });
|
|
72
132
|
}
|
|
73
133
|
}
|
|
74
|
-
|
|
75
|
-
|
|
134
|
+
/**
|
|
135
|
+
* Wrap `transferTokens` so every outgoing token transfer — regardless of
|
|
136
|
+
* caller (SparkAdapter.sendAsset, Flashnet swaps / liquidity, or any future
|
|
137
|
+
* path) — is persisted to the sent-token outbox.
|
|
138
|
+
*
|
|
139
|
+
* The Spark SDK reports no direction for token transactions, so without a
|
|
140
|
+
* local record an outgoing transfer is indistinguishable from a receive
|
|
141
|
+
* (and a send with no change output is not returned by the server at all).
|
|
142
|
+
* Recording at this single choke point guarantees no token send is missed.
|
|
143
|
+
*
|
|
144
|
+
* Metadata is minimal here; SparkAdapter.sendAsset re-saves the same hash
|
|
145
|
+
* with full token metadata, which supersedes this entry (records are keyed
|
|
146
|
+
* by hash). Paths with no richer recorder degrade to a generic "TOKEN" label.
|
|
147
|
+
*/
|
|
148
|
+
installTokenSendRecorder(wallet) {
|
|
149
|
+
if (typeof wallet?.transferTokens !== 'function')
|
|
150
|
+
return;
|
|
151
|
+
const original = wallet.transferTokens.bind(wallet);
|
|
152
|
+
wallet.transferTokens = async (params) => {
|
|
153
|
+
const txId = await original(params);
|
|
76
154
|
try {
|
|
77
|
-
await
|
|
155
|
+
const senderSparkAddress = (await wallet.getSparkAddress());
|
|
156
|
+
await saveSentTokenRecord({
|
|
157
|
+
hash: typeof txId === 'string' ? txId : String(txId),
|
|
158
|
+
senderSparkAddress,
|
|
159
|
+
amount: Number(params?.tokenAmount ?? 0n),
|
|
160
|
+
assetId: String(params?.tokenIdentifier ?? ''),
|
|
161
|
+
ticker: '',
|
|
162
|
+
name: '',
|
|
163
|
+
decimals: 0,
|
|
164
|
+
timestamp: Date.now(),
|
|
165
|
+
});
|
|
78
166
|
}
|
|
79
|
-
catch (
|
|
80
|
-
|
|
81
|
-
console.warn('[SparkClientManager] Error during cleanup:', msg);
|
|
167
|
+
catch (err) {
|
|
168
|
+
log.warn('[SparkClientManager] Failed to record token send:', err);
|
|
82
169
|
}
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
this.config = null;
|
|
86
|
-
}
|
|
87
|
-
isInitialized() {
|
|
88
|
-
return this.wallet !== null;
|
|
170
|
+
return txId;
|
|
171
|
+
};
|
|
89
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Return the active wallet instance.
|
|
175
|
+
* Throws if initialize() has not been called successfully.
|
|
176
|
+
*/
|
|
90
177
|
getWallet() {
|
|
91
178
|
if (!this.wallet) {
|
|
92
|
-
throw new Error('
|
|
179
|
+
throw new Error('SparkWallet not initialized. Call initialize() first.');
|
|
93
180
|
}
|
|
94
181
|
return this.wallet;
|
|
95
182
|
}
|
|
183
|
+
isInitialized() {
|
|
184
|
+
return this.wallet !== null;
|
|
185
|
+
}
|
|
96
186
|
getConfig() {
|
|
97
187
|
return this.config;
|
|
98
188
|
}
|
|
189
|
+
async getReadonlyClient() {
|
|
190
|
+
if (this.readonlyClient)
|
|
191
|
+
return this.readonlyClient;
|
|
192
|
+
if (this._readonlyInitPromise)
|
|
193
|
+
return this._readonlyInitPromise;
|
|
194
|
+
if (!this.config?.mnemonic) {
|
|
195
|
+
throw new Error('SparkReadonlyClient cannot be created without mnemonic config.');
|
|
196
|
+
}
|
|
197
|
+
const network = NETWORK_MAP[this.config.network ?? 'mainnet'] ?? 'MAINNET';
|
|
198
|
+
this._readonlyInitPromise = (async () => {
|
|
199
|
+
const mnemonicOrSeed = resolveSparkMnemonicOrSeed(this.config.mnemonic);
|
|
200
|
+
const client = await SparkReadonlyClient.createWithMasterKey({ network }, mnemonicOrSeed);
|
|
201
|
+
this.readonlyClient = client;
|
|
202
|
+
return client;
|
|
203
|
+
})().finally(() => {
|
|
204
|
+
this._readonlyInitPromise = null;
|
|
205
|
+
});
|
|
206
|
+
return this._readonlyInitPromise;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Register an event listener on the wallet (e.g. incoming transfer notifications).
|
|
210
|
+
*/
|
|
211
|
+
on(event, listener) {
|
|
212
|
+
this.wallet?.on?.(event, listener);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Disconnect and release resources.
|
|
216
|
+
*/
|
|
217
|
+
async disconnect() {
|
|
218
|
+
if (this.wallet) {
|
|
219
|
+
try {
|
|
220
|
+
await this.wallet.cleanupConnections();
|
|
221
|
+
log.info('[SparkClientManager] Wallet disconnected');
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
225
|
+
log.warn('[SparkClientManager] Error during disconnect:', msg);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
this.wallet = null;
|
|
229
|
+
this.readonlyClient = null;
|
|
230
|
+
this.config = null;
|
|
231
|
+
}
|
|
232
|
+
reset() {
|
|
233
|
+
this.wallet = null;
|
|
234
|
+
this.readonlyClient = null;
|
|
235
|
+
this.config = null;
|
|
236
|
+
this._initPromise = null;
|
|
237
|
+
this._readonlyInitPromise = null;
|
|
238
|
+
log.info('[SparkClientManager] Complete reset performed');
|
|
239
|
+
}
|
|
99
240
|
}
|
|
100
241
|
export const sparkClientManager = new SparkClientManager();
|
|
101
242
|
//# sourceMappingURL=spark-client-manager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spark-client-manager.js","sourceRoot":"","sources":["../../src/lib/spark-client-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"spark-client-manager.js","sourceRoot":"","sources":["../../src/lib/spark-client-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK ↔ unified-shape converters for the Spark adapter.
|
|
3
|
+
*
|
|
4
|
+
* The three converters here cover the three sources of Spark activity:
|
|
5
|
+
*
|
|
6
|
+
* - `convertTransferToTransaction` — native Spark transfer
|
|
7
|
+
* - `convertTokenTransactionToUnified` — RGB-Spark token transaction
|
|
8
|
+
* (with direction-inference from output ownership)
|
|
9
|
+
* - `buildSentRecordTransaction` — offline fallback from the
|
|
10
|
+
* locally-stored send-token outbox
|
|
11
|
+
*/
|
|
12
|
+
import type { UnifiedTransaction } from '../types/base.js';
|
|
13
|
+
import type { SparkTransfer } from '../types/spark.js';
|
|
14
|
+
import type { SentTokenTxRecord } from './spark-sent-token-records.js';
|
|
15
|
+
/**
|
|
16
|
+
* Project a native Spark transfer into the unified shape. BTC is the only
|
|
17
|
+
* native Spark asset, so the asset is hard-coded — this branch never
|
|
18
|
+
* surfaces RGB-Spark token transfers (see `convertTokenTransactionToUnified`).
|
|
19
|
+
*/
|
|
20
|
+
export declare function convertTransferToTransaction(transfer: SparkTransfer): UnifiedTransaction;
|
|
21
|
+
/**
|
|
22
|
+
* Convert a TokenTransactionWithStatus from the Spark SDK into a
|
|
23
|
+
* UnifiedTransaction.
|
|
24
|
+
*
|
|
25
|
+
* Direction: mints/creates are always receives. For transfers the protocol
|
|
26
|
+
* exposes no direction field, so we derive it from output ownership — the
|
|
27
|
+
* SDK orders token outputs recipients-first, change-last, so a wallet-owned
|
|
28
|
+
* first output (`tokenOutputs[0]`) means the wallet was the recipient
|
|
29
|
+
* (receive); anything else means it sent. A hash in `sentHashSet` (our
|
|
30
|
+
* local outbox) overrides this as an authoritative "send" — it covers the
|
|
31
|
+
* rare batch transfer where the wallet is a non-first recipient.
|
|
32
|
+
*
|
|
33
|
+
* Amount: receives sum the wallet-owned outputs; sends sum the outputs that
|
|
34
|
+
* left the wallet (everything not wallet-owned), falling back to the
|
|
35
|
+
* recorded amount when the gateway returns no figure.
|
|
36
|
+
*/
|
|
37
|
+
export declare function convertTokenTransactionToUnified(txWithStatus: {
|
|
38
|
+
tokenTransaction?: unknown;
|
|
39
|
+
status: number;
|
|
40
|
+
tokenTransactionHash: Uint8Array;
|
|
41
|
+
}, walletIdentityPubKey: string, tokenMetaMap: Map<string, {
|
|
42
|
+
name: string;
|
|
43
|
+
ticker: string;
|
|
44
|
+
decimals: number;
|
|
45
|
+
}>, rawTokenMetaMap: Map<string, {
|
|
46
|
+
id: string;
|
|
47
|
+
meta: {
|
|
48
|
+
name: string;
|
|
49
|
+
ticker: string;
|
|
50
|
+
decimals: number;
|
|
51
|
+
};
|
|
52
|
+
}>, sentHashSet: Set<string>, storedRecordMap: Map<string, SentTokenTxRecord>, storedAmountMap: Map<string, bigint>, networkType: string, requestedAsset?: string, requestedTokenRawId?: string): UnifiedTransaction | null;
|
|
53
|
+
/**
|
|
54
|
+
* Build a UnifiedTransaction directly from a locally-stored send record,
|
|
55
|
+
* with no Spark RPC. Used as the offline / failed-fetch fallback in
|
|
56
|
+
* `listTransactions` so a completed token withdrawal always appears in
|
|
57
|
+
* history even when the Spark gateway is unreachable.
|
|
58
|
+
*
|
|
59
|
+
* Marks the transaction as `confirmed` on the rationale that the record is
|
|
60
|
+
* only written after the SDK returns a tx id — i.e. the transfer was
|
|
61
|
+
* signed and broadcast.
|
|
62
|
+
*/
|
|
63
|
+
export declare function buildSentRecordTransaction(record: SentTokenTxRecord, requestedAsset?: string): UnifiedTransaction;
|
|
64
|
+
//# sourceMappingURL=spark-converters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-converters.d.ts","sourceRoot":"","sources":["../../src/lib/spark-converters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAmC,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAA;AAqBnE;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,aAAa,GAAG,kBAAkB,CAiBxF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gCAAgC,CAC9C,YAAY,EAAE;IACZ,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,oBAAoB,EAAE,UAAU,CAAA;CACjC,EACD,oBAAoB,EAAE,MAAM,EAC5B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7E,eAAe,EAAE,GAAG,CAClB,MAAM,EACN;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CACzE,EACD,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC/C,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,WAAW,EAAE,MAAM,EACnB,cAAc,CAAC,EAAE,MAAM,EACvB,mBAAmB,CAAC,EAAE,MAAM,GAC3B,kBAAkB,GAAG,IAAI,CA4J3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,iBAAiB,EACzB,cAAc,CAAC,EAAE,MAAM,GACtB,kBAAkB,CA6BpB"}
|