@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
|
@@ -0,0 +1,242 @@
|
|
|
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 { encodeBech32mTokenIdentifier } from '@buildonspark/spark-sdk';
|
|
13
|
+
import { normalizeTxHash } from './spark-sent-token-records.js';
|
|
14
|
+
import { formatAmount, mapTransferStatus, rawTokenIdFromBytes, tokenRefsMatch, txHashFromBytes, u8aToBigInt, u8aToHex, } from './spark-helpers.js';
|
|
15
|
+
const BTC_ASSET = {
|
|
16
|
+
id: 'BTC',
|
|
17
|
+
name: 'Bitcoin',
|
|
18
|
+
ticker: 'BTC',
|
|
19
|
+
precision: 8,
|
|
20
|
+
protocol: 'SPARK',
|
|
21
|
+
layer: 'SPARK_SPARK',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Project a native Spark transfer into the unified shape. BTC is the only
|
|
25
|
+
* native Spark asset, so the asset is hard-coded — this branch never
|
|
26
|
+
* surfaces RGB-Spark token transfers (see `convertTokenTransactionToUnified`).
|
|
27
|
+
*/
|
|
28
|
+
export function convertTransferToTransaction(transfer) {
|
|
29
|
+
const isIncoming = transfer.transferDirection === 'INCOMING';
|
|
30
|
+
return {
|
|
31
|
+
id: transfer.id,
|
|
32
|
+
type: isIncoming ? 'receive' : 'send',
|
|
33
|
+
status: mapTransferStatus(transfer.status),
|
|
34
|
+
timestamp: transfer.createdTime?.getTime() ?? Date.now(),
|
|
35
|
+
amount: transfer.totalValue,
|
|
36
|
+
amountDisplay: formatAmount(transfer.totalValue, 8),
|
|
37
|
+
fee: 0,
|
|
38
|
+
feeDisplay: '0.00000000',
|
|
39
|
+
asset: BTC_ASSET,
|
|
40
|
+
protocolData: {
|
|
41
|
+
sparkInvoice: transfer.sparkInvoice,
|
|
42
|
+
type: transfer.type,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convert a TokenTransactionWithStatus from the Spark SDK into a
|
|
48
|
+
* UnifiedTransaction.
|
|
49
|
+
*
|
|
50
|
+
* Direction: mints/creates are always receives. For transfers the protocol
|
|
51
|
+
* exposes no direction field, so we derive it from output ownership — the
|
|
52
|
+
* SDK orders token outputs recipients-first, change-last, so a wallet-owned
|
|
53
|
+
* first output (`tokenOutputs[0]`) means the wallet was the recipient
|
|
54
|
+
* (receive); anything else means it sent. A hash in `sentHashSet` (our
|
|
55
|
+
* local outbox) overrides this as an authoritative "send" — it covers the
|
|
56
|
+
* rare batch transfer where the wallet is a non-first recipient.
|
|
57
|
+
*
|
|
58
|
+
* Amount: receives sum the wallet-owned outputs; sends sum the outputs that
|
|
59
|
+
* left the wallet (everything not wallet-owned), falling back to the
|
|
60
|
+
* recorded amount when the gateway returns no figure.
|
|
61
|
+
*/
|
|
62
|
+
export function convertTokenTransactionToUnified(txWithStatus, walletIdentityPubKey, tokenMetaMap, rawTokenMetaMap, sentHashSet, storedRecordMap, storedAmountMap, networkType, requestedAsset, requestedTokenRawId) {
|
|
63
|
+
const tx = txWithStatus.tokenTransaction;
|
|
64
|
+
if (!tx)
|
|
65
|
+
return null;
|
|
66
|
+
const outputs = tx.tokenOutputs ?? [];
|
|
67
|
+
if (outputs.length === 0)
|
|
68
|
+
return null;
|
|
69
|
+
const txHash = txHashFromBytes(txWithStatus.tokenTransactionHash);
|
|
70
|
+
const walletPubKeyLower = walletIdentityPubKey.toLowerCase();
|
|
71
|
+
const ownsOutput = (o) => !!o.ownerPublicKey && u8aToHex(o.ownerPublicKey).toLowerCase() === walletPubKeyLower;
|
|
72
|
+
// Direction: mints/creates are receives; an outbox hit is an authoritative
|
|
73
|
+
// send; otherwise the first output's owner decides (see method doc).
|
|
74
|
+
const inputCase = tx.tokenInputs?.$case;
|
|
75
|
+
let type;
|
|
76
|
+
if (inputCase === 'mintInput' || inputCase === 'createInput') {
|
|
77
|
+
type = 'receive';
|
|
78
|
+
}
|
|
79
|
+
else if (sentHashSet.has(txHash)) {
|
|
80
|
+
type = 'send';
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
type = ownsOutput(outputs[0]) ? 'receive' : 'send';
|
|
84
|
+
}
|
|
85
|
+
const storedRecord = type === 'send' ? storedRecordMap.get(txHash) : undefined;
|
|
86
|
+
// Resolve token identity from the strongest local source available.
|
|
87
|
+
const firstOutput = outputs[0];
|
|
88
|
+
const tokenIdBytes = firstOutput.tokenIdentifier;
|
|
89
|
+
let tokenId = '';
|
|
90
|
+
let meta = { name: 'Unknown Token', ticker: 'TOKEN', decimals: 0 };
|
|
91
|
+
if (storedRecord?.assetId) {
|
|
92
|
+
tokenId =
|
|
93
|
+
requestedAsset && tokenRefsMatch(storedRecord.assetId, requestedAsset)
|
|
94
|
+
? requestedAsset
|
|
95
|
+
: storedRecord.assetId;
|
|
96
|
+
meta = {
|
|
97
|
+
name: storedRecord.name || storedRecord.assetId,
|
|
98
|
+
ticker: storedRecord.ticker || 'TOKEN',
|
|
99
|
+
decimals: storedRecord.decimals,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
else if (tokenIdBytes && tokenIdBytes.length > 0) {
|
|
103
|
+
const rawTokenId = rawTokenIdFromBytes(tokenIdBytes);
|
|
104
|
+
const rawFound = rawTokenMetaMap.get(rawTokenId);
|
|
105
|
+
if (requestedAsset && requestedTokenRawId && rawTokenId === requestedTokenRawId) {
|
|
106
|
+
tokenId = requestedAsset;
|
|
107
|
+
meta = rawFound?.meta ?? tokenMetaMap.get(requestedAsset) ?? meta;
|
|
108
|
+
}
|
|
109
|
+
if (rawFound) {
|
|
110
|
+
tokenId || (tokenId = rawFound.id);
|
|
111
|
+
meta = rawFound.meta;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
if (!tokenId) {
|
|
115
|
+
tokenId = encodeBech32mTokenIdentifier({
|
|
116
|
+
tokenIdentifier: tokenIdBytes,
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK network enum varies by version
|
|
118
|
+
network: networkType,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const found = tokenMetaMap.get(tokenId);
|
|
122
|
+
if (found)
|
|
123
|
+
meta = found;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Fallback: take first entry from map when encoding fails
|
|
127
|
+
for (const [id, m] of tokenMetaMap) {
|
|
128
|
+
tokenId = id;
|
|
129
|
+
meta = m;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (requestedAsset && !tokenId) {
|
|
135
|
+
tokenId = requestedAsset;
|
|
136
|
+
const found = tokenMetaMap.get(requestedAsset);
|
|
137
|
+
if (found)
|
|
138
|
+
meta = found;
|
|
139
|
+
}
|
|
140
|
+
// Amount
|
|
141
|
+
let totalAmount = 0n;
|
|
142
|
+
if (type === 'receive') {
|
|
143
|
+
// Sum the outputs the wallet owns — its received amount — ignoring any
|
|
144
|
+
// change the sender kept for itself.
|
|
145
|
+
for (const o of outputs) {
|
|
146
|
+
if (ownsOutput(o))
|
|
147
|
+
totalAmount += u8aToBigInt(o.tokenAmount);
|
|
148
|
+
}
|
|
149
|
+
// Fallback for mints / unexpected shapes where no output resolves as owned.
|
|
150
|
+
if (totalAmount === 0n) {
|
|
151
|
+
for (const o of outputs)
|
|
152
|
+
totalAmount += u8aToBigInt(o.tokenAmount);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
// Send: the amount that left the wallet is the sum of outputs the wallet
|
|
157
|
+
// does NOT own (recipients), excluding its own change output.
|
|
158
|
+
for (const o of outputs) {
|
|
159
|
+
if (!ownsOutput(o))
|
|
160
|
+
totalAmount += u8aToBigInt(o.tokenAmount);
|
|
161
|
+
}
|
|
162
|
+
// Fall back to the amount recorded at send time if the gateway returned
|
|
163
|
+
// nothing usable (e.g. a redacted or change-less response).
|
|
164
|
+
if (totalAmount === 0n) {
|
|
165
|
+
totalAmount = storedAmountMap.get(txHash) ?? 0n;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const amount = Number(totalAmount);
|
|
169
|
+
// Map token transaction status
|
|
170
|
+
// TokenTransactionStatus: FINALIZED=2 → confirmed, *CANCELLED=3,4 → failed
|
|
171
|
+
const statusNum = txWithStatus.status;
|
|
172
|
+
let status = 'pending';
|
|
173
|
+
if (statusNum === 2) {
|
|
174
|
+
status = 'confirmed'; // TOKEN_TRANSACTION_FINALIZED
|
|
175
|
+
}
|
|
176
|
+
else if (statusNum === 3 || statusNum === 4) {
|
|
177
|
+
status = 'failed'; // *_CANCELLED
|
|
178
|
+
}
|
|
179
|
+
const rawTs = tx.clientCreatedTimestamp;
|
|
180
|
+
const timestamp = rawTs instanceof Date ? rawTs.getTime() : typeof rawTs === 'number' ? rawTs : Date.now();
|
|
181
|
+
return {
|
|
182
|
+
id: `token-${txHash.slice(0, 16)}`,
|
|
183
|
+
type,
|
|
184
|
+
status,
|
|
185
|
+
timestamp,
|
|
186
|
+
amount,
|
|
187
|
+
amountDisplay: formatAmount(amount, meta.decimals),
|
|
188
|
+
fee: 0,
|
|
189
|
+
feeDisplay: '0',
|
|
190
|
+
asset: {
|
|
191
|
+
id: tokenId,
|
|
192
|
+
name: meta.name,
|
|
193
|
+
ticker: meta.ticker,
|
|
194
|
+
precision: meta.decimals,
|
|
195
|
+
protocol: 'SPARK',
|
|
196
|
+
layer: 'SPARK_SPARK',
|
|
197
|
+
},
|
|
198
|
+
protocolData: {
|
|
199
|
+
type: inputCase ?? 'unknown',
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Build a UnifiedTransaction directly from a locally-stored send record,
|
|
205
|
+
* with no Spark RPC. Used as the offline / failed-fetch fallback in
|
|
206
|
+
* `listTransactions` so a completed token withdrawal always appears in
|
|
207
|
+
* history even when the Spark gateway is unreachable.
|
|
208
|
+
*
|
|
209
|
+
* Marks the transaction as `confirmed` on the rationale that the record is
|
|
210
|
+
* only written after the SDK returns a tx id — i.e. the transfer was
|
|
211
|
+
* signed and broadcast.
|
|
212
|
+
*/
|
|
213
|
+
export function buildSentRecordTransaction(record, requestedAsset) {
|
|
214
|
+
const decimals = record.decimals || 0;
|
|
215
|
+
const amount = record.amount || 0;
|
|
216
|
+
const tokenId = requestedAsset && tokenRefsMatch(record.assetId, requestedAsset)
|
|
217
|
+
? requestedAsset
|
|
218
|
+
: record.assetId;
|
|
219
|
+
return {
|
|
220
|
+
id: `token-${normalizeTxHash(record.hash).slice(0, 16)}`,
|
|
221
|
+
type: 'send',
|
|
222
|
+
status: 'confirmed',
|
|
223
|
+
timestamp: record.timestamp || Date.now(),
|
|
224
|
+
amount,
|
|
225
|
+
amountDisplay: formatAmount(amount, decimals),
|
|
226
|
+
fee: 0,
|
|
227
|
+
feeDisplay: '0',
|
|
228
|
+
asset: {
|
|
229
|
+
id: tokenId,
|
|
230
|
+
name: record.name || record.assetId,
|
|
231
|
+
ticker: record.ticker || 'TOKEN',
|
|
232
|
+
precision: decimals,
|
|
233
|
+
protocol: 'SPARK',
|
|
234
|
+
layer: 'SPARK_SPARK',
|
|
235
|
+
},
|
|
236
|
+
protocolData: {
|
|
237
|
+
type: 'transferInput',
|
|
238
|
+
source: 'local-record',
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=spark-converters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-converters.js","sourceRoot":"","sources":["../../src/lib/spark-converters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for the Spark adapter.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the extension's spark adapter so the adapter file can stay
|
|
5
|
+
* focused on the IProtocolAdapter surface + RPC orchestration. Everything in
|
|
6
|
+
* this module is side-effect free.
|
|
7
|
+
*/
|
|
8
|
+
import type { TransactionStatus } from '../types/base.js';
|
|
9
|
+
/**
|
|
10
|
+
* Render a raw integer amount in the asset's display precision.
|
|
11
|
+
* Always emits exactly `precision` decimal digits (no trailing-zero trim) —
|
|
12
|
+
* callers that want a tighter rendering should post-process.
|
|
13
|
+
*/
|
|
14
|
+
export declare function formatAmount(amount: number, precision: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Map a Spark transfer status string to our unified TransactionStatus.
|
|
17
|
+
*
|
|
18
|
+
* The Spark SDK ships two related but distinct status vocabularies:
|
|
19
|
+
* 1. Native transfers use the `TRANSFER_STATUS_*` enum from the SDK
|
|
20
|
+
* (COMPLETED / EXPIRED / RETURNED / SENDER_INITIATED /
|
|
21
|
+
* RECEIVER_KEY_TWEAKED).
|
|
22
|
+
* 2. Lightning send requests use a looser lowercase vocabulary
|
|
23
|
+
* (`completed` / `complete` / `succeeded` / `success` / `failed` /
|
|
24
|
+
* `error`) which has drifted across SDK versions.
|
|
25
|
+
*
|
|
26
|
+
* Both are mapped here so callers don't need to know which vocabulary a
|
|
27
|
+
* given record came from.
|
|
28
|
+
*/
|
|
29
|
+
export declare function mapTransferStatus(status?: string): TransactionStatus;
|
|
30
|
+
/**
|
|
31
|
+
* Wrap a promise with a rejection timeout. Used to fail fast on slow Spark
|
|
32
|
+
* RPC calls; the SDK's own 30 s ceiling is too long for popup UI.
|
|
33
|
+
*/
|
|
34
|
+
export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* True when a Spark balance snapshot represents a fresh / still-syncing
|
|
37
|
+
* wallet — zero sats AND no token balances. The adapter applies a shorter
|
|
38
|
+
* TTL to empty snapshots so the UI doesn't get stuck on "0 sats" while the
|
|
39
|
+
* Spark wallet syncs.
|
|
40
|
+
*/
|
|
41
|
+
export declare function isEmptyBalance(value: {
|
|
42
|
+
balance?: bigint | number | string;
|
|
43
|
+
tokenBalances?: Map<unknown, unknown> | unknown;
|
|
44
|
+
}): boolean;
|
|
45
|
+
/** Convert a Uint8Array to lowercase hex string. */
|
|
46
|
+
export declare function u8aToHex(bytes: Uint8Array): string;
|
|
47
|
+
/** Convert a big-endian Uint8Array to bigint (uint128 max). */
|
|
48
|
+
export declare function u8aToBigInt(bytes: Uint8Array): bigint;
|
|
49
|
+
/** Hex tx hash from raw bytes, run through the project's normalizer. */
|
|
50
|
+
export declare function txHashFromBytes(bytes: Uint8Array): string;
|
|
51
|
+
/** Normalized raw token id from raw bytes; empty string when bytes are missing. */
|
|
52
|
+
export declare function rawTokenIdFromBytes(bytes: Uint8Array | undefined): string;
|
|
53
|
+
/**
|
|
54
|
+
* Decode a bech32m-encoded Spark token id (e.g. `btkn1…`) back to its
|
|
55
|
+
* normalized raw hex form. Returns `""` for falsy input or decode failures —
|
|
56
|
+
* tokens that aren't bech32m-encoded simply round-trip through the empty
|
|
57
|
+
* string and fall back to the caller's other matchers.
|
|
58
|
+
*/
|
|
59
|
+
export declare function rawTokenIdFromBech32mTokenId(tokenId: string | undefined): string;
|
|
60
|
+
/**
|
|
61
|
+
* Cross-format token id comparison: matches identical strings directly,
|
|
62
|
+
* otherwise decodes both via bech32m / normalizeTxHash and compares the
|
|
63
|
+
* raw forms. Returns false when either side is empty.
|
|
64
|
+
*/
|
|
65
|
+
export declare function tokenRefsMatch(left: string | undefined, right: string | undefined): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Parse one of the SDK's polymorphic expiry shapes (Date | number | ISO
|
|
68
|
+
* string) into a finite millisecond timestamp. Returns undefined for
|
|
69
|
+
* unparseable / falsy / Infinity values so callers can branch on absence.
|
|
70
|
+
*/
|
|
71
|
+
export declare function parseSdkExpiryMs(expiry: unknown): number | undefined;
|
|
72
|
+
//# sourceMappingURL=spark-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/spark-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAGtD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAuBpE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAOhG;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;IAClC,aAAa,CAAC,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,CAAA;CAChD,GAAG,OAAO,CAKV;AAED,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIlD;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAIrD;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEzD;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQhF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAU3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAcpE"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers for the Spark adapter.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from the extension's spark adapter so the adapter file can stay
|
|
5
|
+
* focused on the IProtocolAdapter surface + RPC orchestration. Everything in
|
|
6
|
+
* this module is side-effect free.
|
|
7
|
+
*/
|
|
8
|
+
import { bech32m } from '@scure/base';
|
|
9
|
+
import { normalizeTxHash } from './spark-sent-token-records.js';
|
|
10
|
+
/**
|
|
11
|
+
* Render a raw integer amount in the asset's display precision.
|
|
12
|
+
* Always emits exactly `precision` decimal digits (no trailing-zero trim) —
|
|
13
|
+
* callers that want a tighter rendering should post-process.
|
|
14
|
+
*/
|
|
15
|
+
export function formatAmount(amount, precision) {
|
|
16
|
+
return (amount / Math.pow(10, precision)).toFixed(precision);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Map a Spark transfer status string to our unified TransactionStatus.
|
|
20
|
+
*
|
|
21
|
+
* The Spark SDK ships two related but distinct status vocabularies:
|
|
22
|
+
* 1. Native transfers use the `TRANSFER_STATUS_*` enum from the SDK
|
|
23
|
+
* (COMPLETED / EXPIRED / RETURNED / SENDER_INITIATED /
|
|
24
|
+
* RECEIVER_KEY_TWEAKED).
|
|
25
|
+
* 2. Lightning send requests use a looser lowercase vocabulary
|
|
26
|
+
* (`completed` / `complete` / `succeeded` / `success` / `failed` /
|
|
27
|
+
* `error`) which has drifted across SDK versions.
|
|
28
|
+
*
|
|
29
|
+
* Both are mapped here so callers don't need to know which vocabulary a
|
|
30
|
+
* given record came from.
|
|
31
|
+
*/
|
|
32
|
+
export function mapTransferStatus(status) {
|
|
33
|
+
if (!status)
|
|
34
|
+
return 'pending';
|
|
35
|
+
// SDK TransferStatus enum keys.
|
|
36
|
+
if (status === 'TRANSFER_STATUS_COMPLETED')
|
|
37
|
+
return 'confirmed';
|
|
38
|
+
if (status === 'TRANSFER_STATUS_EXPIRED' || status === 'TRANSFER_STATUS_RETURNED') {
|
|
39
|
+
return 'failed';
|
|
40
|
+
}
|
|
41
|
+
if (status === 'TRANSFER_STATUS_SENDER_INITIATED' ||
|
|
42
|
+
status === 'TRANSFER_STATUS_RECEIVER_KEY_TWEAKED') {
|
|
43
|
+
return 'pending';
|
|
44
|
+
}
|
|
45
|
+
// LightningSendRequest status vocabulary — case-insensitive.
|
|
46
|
+
const s = status.toLowerCase();
|
|
47
|
+
if (s === 'completed' || s === 'complete' || s === 'succeeded' || s === 'success') {
|
|
48
|
+
return 'confirmed';
|
|
49
|
+
}
|
|
50
|
+
if (s === 'failed' || s === 'error')
|
|
51
|
+
return 'failed';
|
|
52
|
+
return 'pending';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Wrap a promise with a rejection timeout. Used to fail fast on slow Spark
|
|
56
|
+
* RPC calls; the SDK's own 30 s ceiling is too long for popup UI.
|
|
57
|
+
*/
|
|
58
|
+
export function withTimeout(promise, timeoutMs, label) {
|
|
59
|
+
return Promise.race([
|
|
60
|
+
promise,
|
|
61
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs)),
|
|
62
|
+
]);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* True when a Spark balance snapshot represents a fresh / still-syncing
|
|
66
|
+
* wallet — zero sats AND no token balances. The adapter applies a shorter
|
|
67
|
+
* TTL to empty snapshots so the UI doesn't get stuck on "0 sats" while the
|
|
68
|
+
* Spark wallet syncs.
|
|
69
|
+
*/
|
|
70
|
+
export function isEmptyBalance(value) {
|
|
71
|
+
const raw = value?.balance;
|
|
72
|
+
const sats = typeof raw === 'bigint' ? raw : BigInt(raw ?? 0);
|
|
73
|
+
const tokenCount = value?.tokenBalances instanceof Map ? value.tokenBalances.size : 0;
|
|
74
|
+
return sats === 0n && tokenCount === 0;
|
|
75
|
+
}
|
|
76
|
+
/** Convert a Uint8Array to lowercase hex string. */
|
|
77
|
+
export function u8aToHex(bytes) {
|
|
78
|
+
return Array.from(bytes)
|
|
79
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
80
|
+
.join('');
|
|
81
|
+
}
|
|
82
|
+
/** Convert a big-endian Uint8Array to bigint (uint128 max). */
|
|
83
|
+
export function u8aToBigInt(bytes) {
|
|
84
|
+
let result = 0n;
|
|
85
|
+
for (const b of bytes)
|
|
86
|
+
result = (result << 8n) | BigInt(b);
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
/** Hex tx hash from raw bytes, run through the project's normalizer. */
|
|
90
|
+
export function txHashFromBytes(bytes) {
|
|
91
|
+
return normalizeTxHash(u8aToHex(bytes));
|
|
92
|
+
}
|
|
93
|
+
/** Normalized raw token id from raw bytes; empty string when bytes are missing. */
|
|
94
|
+
export function rawTokenIdFromBytes(bytes) {
|
|
95
|
+
return bytes ? normalizeTxHash(u8aToHex(bytes)) : '';
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Decode a bech32m-encoded Spark token id (e.g. `btkn1…`) back to its
|
|
99
|
+
* normalized raw hex form. Returns `""` for falsy input or decode failures —
|
|
100
|
+
* tokens that aren't bech32m-encoded simply round-trip through the empty
|
|
101
|
+
* string and fall back to the caller's other matchers.
|
|
102
|
+
*/
|
|
103
|
+
export function rawTokenIdFromBech32mTokenId(tokenId) {
|
|
104
|
+
if (!tokenId)
|
|
105
|
+
return '';
|
|
106
|
+
try {
|
|
107
|
+
const decoded = bech32m.decode(tokenId, 500);
|
|
108
|
+
return rawTokenIdFromBytes(new Uint8Array(bech32m.fromWords(decoded.words)));
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
return '';
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Cross-format token id comparison: matches identical strings directly,
|
|
116
|
+
* otherwise decodes both via bech32m / normalizeTxHash and compares the
|
|
117
|
+
* raw forms. Returns false when either side is empty.
|
|
118
|
+
*/
|
|
119
|
+
export function tokenRefsMatch(left, right) {
|
|
120
|
+
const normalizedLeft = left?.trim();
|
|
121
|
+
const normalizedRight = right?.trim();
|
|
122
|
+
if (!normalizedLeft || !normalizedRight)
|
|
123
|
+
return false;
|
|
124
|
+
if (normalizedLeft === normalizedRight)
|
|
125
|
+
return true;
|
|
126
|
+
const leftRaw = rawTokenIdFromBech32mTokenId(normalizedLeft) || normalizeTxHash(normalizedLeft);
|
|
127
|
+
const rightRaw = rawTokenIdFromBech32mTokenId(normalizedRight) || normalizeTxHash(normalizedRight);
|
|
128
|
+
return !!leftRaw && leftRaw === rightRaw;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Parse one of the SDK's polymorphic expiry shapes (Date | number | ISO
|
|
132
|
+
* string) into a finite millisecond timestamp. Returns undefined for
|
|
133
|
+
* unparseable / falsy / Infinity values so callers can branch on absence.
|
|
134
|
+
*/
|
|
135
|
+
export function parseSdkExpiryMs(expiry) {
|
|
136
|
+
if (!expiry)
|
|
137
|
+
return undefined;
|
|
138
|
+
if (expiry instanceof Date) {
|
|
139
|
+
const time = expiry.getTime();
|
|
140
|
+
return Number.isFinite(time) ? time : undefined;
|
|
141
|
+
}
|
|
142
|
+
if (typeof expiry === 'number') {
|
|
143
|
+
return Number.isFinite(expiry) ? expiry : undefined;
|
|
144
|
+
}
|
|
145
|
+
if (typeof expiry === 'string') {
|
|
146
|
+
const time = new Date(expiry).getTime();
|
|
147
|
+
return Number.isFinite(time) ? time : undefined;
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=spark-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-helpers.js","sourceRoot":"","sources":["../../src/lib/spark-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spark sent-token-transaction outbox.
|
|
3
|
+
*
|
|
4
|
+
* The Spark SDK exposes no direction for token transactions — a
|
|
5
|
+
* `queryTokenTransactions*` response cannot tell a send apart from a receive
|
|
6
|
+
* (both leave the wallet owning an output: the received amount, or the change
|
|
7
|
+
* of a send). A send with no change output is not returned at all.
|
|
8
|
+
*
|
|
9
|
+
* To make outgoing token transfers visible in history we persist a record of
|
|
10
|
+
* every send the wallet performs. This module is the single source of truth
|
|
11
|
+
* for that outbox; it is intentionally dependency-light so it can be used both
|
|
12
|
+
* by the SparkAdapter and by the low-level `transferTokens` wrapper in
|
|
13
|
+
* `spark-client-manager.ts` without import cycles.
|
|
14
|
+
*
|
|
15
|
+
* Storage is platform-agnostic: it uses the engine's ports storage
|
|
16
|
+
* (`getPlatform()?.storage`, an `IStorageProvider`), persisting the whole
|
|
17
|
+
* record array as a JSON string under a single key. When no platform is set it
|
|
18
|
+
* degrades to an in-module in-memory Map so callers never crash.
|
|
19
|
+
*/
|
|
20
|
+
/** Cap on retained records — newest first, oldest dropped. */
|
|
21
|
+
export declare const MAX_SENT_TOKEN_TX_HISTORY = 200;
|
|
22
|
+
export interface SentTokenTxRecord {
|
|
23
|
+
hash: string;
|
|
24
|
+
/** Spark address of the wallet that created the send. Prevents cross-wallet misclassification. */
|
|
25
|
+
senderSparkAddress?: string;
|
|
26
|
+
/** Raw token amount (integer, before decimal division). */
|
|
27
|
+
amount: number;
|
|
28
|
+
assetId: string;
|
|
29
|
+
ticker: string;
|
|
30
|
+
name: string;
|
|
31
|
+
decimals: number;
|
|
32
|
+
timestamp: number;
|
|
33
|
+
}
|
|
34
|
+
/** Normalize transaction hashes across SDK/storage shapes. */
|
|
35
|
+
export declare function normalizeTxHash(hash: string): string;
|
|
36
|
+
export declare function loadSentTokenRecords(): Promise<SentTokenTxRecord[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Persist a send record. Records are keyed by hash — re-saving the same hash
|
|
39
|
+
* replaces the earlier entry, so a richer record (with token metadata) written
|
|
40
|
+
* after a minimal one supersedes it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function saveSentTokenRecord(record: SentTokenTxRecord): Promise<void>;
|
|
43
|
+
//# sourceMappingURL=spark-sent-token-records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-sent-token-records.d.ts","sourceRoot":"","sources":["../../src/lib/spark-sent-token-records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,8DAA8D;AAC9D,eAAO,MAAM,yBAAyB,MAAM,CAAA;AAE5C,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,kGAAkG;IAClG,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;CAClB;AAsBD,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAmCzE;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAalF"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spark sent-token-transaction outbox.
|
|
3
|
+
*
|
|
4
|
+
* The Spark SDK exposes no direction for token transactions — a
|
|
5
|
+
* `queryTokenTransactions*` response cannot tell a send apart from a receive
|
|
6
|
+
* (both leave the wallet owning an output: the received amount, or the change
|
|
7
|
+
* of a send). A send with no change output is not returned at all.
|
|
8
|
+
*
|
|
9
|
+
* To make outgoing token transfers visible in history we persist a record of
|
|
10
|
+
* every send the wallet performs. This module is the single source of truth
|
|
11
|
+
* for that outbox; it is intentionally dependency-light so it can be used both
|
|
12
|
+
* by the SparkAdapter and by the low-level `transferTokens` wrapper in
|
|
13
|
+
* `spark-client-manager.ts` without import cycles.
|
|
14
|
+
*
|
|
15
|
+
* Storage is platform-agnostic: it uses the engine's ports storage
|
|
16
|
+
* (`getPlatform()?.storage`, an `IStorageProvider`), persisting the whole
|
|
17
|
+
* record array as a JSON string under a single key. When no platform is set it
|
|
18
|
+
* degrades to an in-module in-memory Map so callers never crash.
|
|
19
|
+
*/
|
|
20
|
+
import { log } from './log.js';
|
|
21
|
+
import { getPlatform } from '../ports/index.js';
|
|
22
|
+
/** Single storage key holding the JSON-serialized record array. */
|
|
23
|
+
const STORAGE_KEY = 'sparkSentTokenTxHashes';
|
|
24
|
+
/** Cap on retained records — newest first, oldest dropped. */
|
|
25
|
+
export const MAX_SENT_TOKEN_TX_HISTORY = 200;
|
|
26
|
+
/** In-memory fallback used when no platform storage is injected. */
|
|
27
|
+
const memoryStore = new Map();
|
|
28
|
+
async function readRaw() {
|
|
29
|
+
const storage = getPlatform()?.storage;
|
|
30
|
+
if (storage) {
|
|
31
|
+
return storage.get(STORAGE_KEY);
|
|
32
|
+
}
|
|
33
|
+
return memoryStore.get(STORAGE_KEY) ?? null;
|
|
34
|
+
}
|
|
35
|
+
async function writeRaw(value) {
|
|
36
|
+
const storage = getPlatform()?.storage;
|
|
37
|
+
if (storage) {
|
|
38
|
+
await storage.set(STORAGE_KEY, value);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
memoryStore.set(STORAGE_KEY, value);
|
|
42
|
+
}
|
|
43
|
+
/** Normalize transaction hashes across SDK/storage shapes. */
|
|
44
|
+
export function normalizeTxHash(hash) {
|
|
45
|
+
return hash.trim().toLowerCase().replace(/^0x/, '');
|
|
46
|
+
}
|
|
47
|
+
export async function loadSentTokenRecords() {
|
|
48
|
+
try {
|
|
49
|
+
const raw = await readRaw();
|
|
50
|
+
if (!raw)
|
|
51
|
+
return [];
|
|
52
|
+
const stored = JSON.parse(raw);
|
|
53
|
+
if (!Array.isArray(stored))
|
|
54
|
+
return [];
|
|
55
|
+
return stored
|
|
56
|
+
.map((r) => {
|
|
57
|
+
if (typeof r === 'string') {
|
|
58
|
+
// Legacy format: plain hash string, no amount info — migrate in-place with amount 0.
|
|
59
|
+
return {
|
|
60
|
+
hash: normalizeTxHash(r),
|
|
61
|
+
senderSparkAddress: undefined,
|
|
62
|
+
amount: 0,
|
|
63
|
+
assetId: '',
|
|
64
|
+
ticker: 'TOKEN',
|
|
65
|
+
name: '',
|
|
66
|
+
decimals: 0,
|
|
67
|
+
timestamp: 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (typeof r === 'object' &&
|
|
71
|
+
r !== null &&
|
|
72
|
+
typeof r.hash === 'string') {
|
|
73
|
+
const rec = r;
|
|
74
|
+
return { ...rec, hash: normalizeTxHash(rec.hash) };
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
})
|
|
78
|
+
.filter((r) => r !== null);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Persist a send record. Records are keyed by hash — re-saving the same hash
|
|
86
|
+
* replaces the earlier entry, so a richer record (with token metadata) written
|
|
87
|
+
* after a minimal one supersedes it.
|
|
88
|
+
*/
|
|
89
|
+
export async function saveSentTokenRecord(record) {
|
|
90
|
+
try {
|
|
91
|
+
const normalizedRecord = { ...record, hash: normalizeTxHash(record.hash) };
|
|
92
|
+
if (!normalizedRecord.hash)
|
|
93
|
+
return;
|
|
94
|
+
const existing = await loadSentTokenRecords();
|
|
95
|
+
const updated = [
|
|
96
|
+
normalizedRecord,
|
|
97
|
+
...existing.filter((r) => normalizeTxHash(r.hash) !== normalizedRecord.hash),
|
|
98
|
+
].slice(0, MAX_SENT_TOKEN_TX_HISTORY);
|
|
99
|
+
await writeRaw(JSON.stringify(updated));
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
log.error('[sent-token-records] Failed to save sent token transaction record:', err);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=spark-sent-token-records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-sent-token-records.js","sourceRoot":"","sources":["../../src/lib/spark-sent-token-records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC3B,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAEtC,mEAAmE;AACnE,MAAM,WAAW,GAAG,wBAAwB,CAAA;AAE5C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,yBAAyB,GAAG,GAAG,CAAA;AAe5C,oEAAoE;AACpE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAA;AAE7C,KAAK,UAAU,OAAO;IACpB,MAAM,OAAO,GAAG,WAAW,EAAE,EAAE,OAAO,CAAA;IACtC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,IAAI,CAAA;AAC7C,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,KAAa;IACnC,MAAM,OAAO,GAAG,WAAW,EAAE,EAAE,OAAO,CAAA;IACtC,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;QACrC,OAAM;IACR,CAAC;IACD,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;AACrC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAA;QAC3B,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAA;QACnB,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAA;QACrC,OAAO,MAAM;aACV,GAAG,CAAC,CAAC,CAAC,EAA4B,EAAE;YACnC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,qFAAqF;gBACrF,OAAO;oBACL,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;oBACxB,kBAAkB,EAAE,SAAS;oBAC7B,MAAM,EAAE,CAAC;oBACT,OAAO,EAAE,EAAE;oBACX,MAAM,EAAE,OAAO;oBACf,IAAI,EAAE,EAAE;oBACR,QAAQ,EAAE,CAAC;oBACX,SAAS,EAAE,CAAC;iBACb,CAAA;YACH,CAAC;YACD,IACE,OAAO,CAAC,KAAK,QAAQ;gBACrB,CAAC,KAAK,IAAI;gBACV,OAAQ,CAAwB,CAAC,IAAI,KAAK,QAAQ,EAClD,CAAC;gBACD,MAAM,GAAG,GAAG,CAAsB,CAAA;gBAClC,OAAO,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAA;YACpD,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAA0B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAA;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAyB;IACjE,IAAI,CAAC;QACH,MAAM,gBAAgB,GAAG,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA;QAC1E,IAAI,CAAC,gBAAgB,CAAC,IAAI;YAAE,OAAM;QAClC,MAAM,QAAQ,GAAG,MAAM,oBAAoB,EAAE,CAAA;QAC7C,MAAM,OAAO,GAAG;YACd,gBAAgB;YAChB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,gBAAgB,CAAC,IAAI,CAAC;SAC7E,CAAC,KAAK,CAAC,CAAC,EAAE,yBAAyB,CAAC,CAAA;QACrC,MAAM,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,CAAC,oEAAoE,EAAE,GAAG,CAAC,CAAA;IACtF,CAAC;AACH,CAAC"}
|