@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.
Files changed (41) hide show
  1. package/dist/adapters/SparkAdapter.d.ts +93 -16
  2. package/dist/adapters/SparkAdapter.d.ts.map +1 -1
  3. package/dist/adapters/SparkAdapter.js +831 -171
  4. package/dist/adapters/SparkAdapter.js.map +1 -1
  5. package/dist/adapters/arkade.d.ts +15 -0
  6. package/dist/adapters/arkade.d.ts.map +1 -0
  7. package/dist/adapters/arkade.js +15 -0
  8. package/dist/adapters/arkade.js.map +1 -0
  9. package/dist/adapters/spark.d.ts +11 -0
  10. package/dist/adapters/spark.d.ts.map +1 -0
  11. package/dist/adapters/spark.js +11 -0
  12. package/dist/adapters/spark.js.map +1 -0
  13. package/dist/lib/psbt-signer.d.ts +60 -0
  14. package/dist/lib/psbt-signer.d.ts.map +1 -0
  15. package/dist/lib/psbt-signer.js +161 -0
  16. package/dist/lib/psbt-signer.js.map +1 -0
  17. package/dist/lib/spark-activity.d.ts +5 -0
  18. package/dist/lib/spark-activity.d.ts.map +1 -0
  19. package/dist/lib/spark-activity.js +11 -0
  20. package/dist/lib/spark-activity.js.map +1 -0
  21. package/dist/lib/spark-balance-cache.d.ts +58 -0
  22. package/dist/lib/spark-balance-cache.d.ts.map +1 -0
  23. package/dist/lib/spark-balance-cache.js +86 -0
  24. package/dist/lib/spark-balance-cache.js.map +1 -0
  25. package/dist/lib/spark-client-manager.d.ts +54 -9
  26. package/dist/lib/spark-client-manager.d.ts.map +1 -1
  27. package/dist/lib/spark-client-manager.js +176 -35
  28. package/dist/lib/spark-client-manager.js.map +1 -1
  29. package/dist/lib/spark-converters.d.ts +64 -0
  30. package/dist/lib/spark-converters.d.ts.map +1 -0
  31. package/dist/lib/spark-converters.js +242 -0
  32. package/dist/lib/spark-converters.js.map +1 -0
  33. package/dist/lib/spark-helpers.d.ts +72 -0
  34. package/dist/lib/spark-helpers.d.ts.map +1 -0
  35. package/dist/lib/spark-helpers.js +151 -0
  36. package/dist/lib/spark-helpers.js.map +1 -0
  37. package/dist/lib/spark-sent-token-records.d.ts +43 -0
  38. package/dist/lib/spark-sent-token-records.d.ts.map +1 -0
  39. package/dist/lib/spark-sent-token-records.js +105 -0
  40. package/dist/lib/spark-sent-token-records.js.map +1 -0
  41. package/package.json +11 -2
@@ -1,13 +1,21 @@
1
1
  /**
2
2
  * Spark Client Manager
3
- * Manages the lifecycle of a SparkWallet from @buildonspark/spark-sdk.
4
- * Uses injected SDK factory to avoid dynamic import() issues in Metro.
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
- type SparkWallet = any;
15
+ import { SparkReadonlyClient } from '@buildonspark/spark-sdk';
8
16
  /**
9
- * SDK factory injected by consumers.
10
- * Consumers must call `setSdkFactory()` before `initialize()`.
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
- * Set the SDK factory before calling initialize().
29
- * This avoids dynamic import() which breaks in Metro bundler.
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
- disconnect(): Promise<void>;
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;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,KAAK,WAAW,GAAG,GAAG,CAAA;AAEtB;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,gBAAgB,EAAE,CAAC,MAAM,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,GAAG,CAAA;KAAE,CAAC,CAAA;CACjH;AAED,cAAM,kBAAkB;IACtB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,UAAU,CAA+B;IAEjD;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAI7C,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;YAShC,aAAa;IAiDrB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAajC,aAAa,IAAI,OAAO;IAIxB,SAAS,IAAI,WAAW;IAOxB,SAAS,IAAI,WAAW,GAAG,IAAI;CAGhC;AAED,eAAO,MAAM,kBAAkB,oBAA2B,CAAA"}
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
- * Manages the lifecycle of a SparkWallet from @buildonspark/spark-sdk.
4
- * Uses injected SDK factory to avoid dynamic import() issues in Metro.
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
- * Set the SDK factory before calling initialize().
15
- * This avoids dynamic import() which breaks in Metro bundler.
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
- console.warn('[SparkClientManager] Wallet already initialized, re-initializing...');
95
+ log.warn('[SparkClientManager] Wallet already initialized, re-initializing...');
31
96
  await this.disconnect();
32
97
  }
33
- const networkMap = {
34
- mainnet: 'MAINNET',
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: config.mnemonic,
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: config.mnemonic,
110
+ mnemonicOrSeed,
53
111
  options: { network: network },
54
112
  });
55
113
  }
56
114
  this.wallet = result.wallet;
57
115
  this.config = config;
58
- console.log('[SparkClientManager] SparkWallet initialized, network:', network);
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
- console.log('[SparkClientManager] Privacy mode enabled');
121
+ log.info('[SparkClientManager] Privacy mode enabled');
62
122
  }
63
- catch (error) {
64
- const msg = error instanceof Error ? error.message : String(error);
65
- console.warn('[SparkClientManager] Failed to enable privacy mode:', msg);
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
- async disconnect() {
75
- if (this.wallet) {
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 this.wallet.cleanupConnections();
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 (error) {
80
- const msg = error instanceof Error ? error.message : String(error);
81
- console.warn('[SparkClientManager] Error during cleanup:', msg);
167
+ catch (err) {
168
+ log.warn('[SparkClientManager] Failed to record token send:', err);
82
169
  }
83
- this.wallet = null;
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('[SparkClientManager] Wallet not initialized');
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":"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"}
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"}