@bsv/wallet-toolbox-mobile 2.3.2 → 2.4.0
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/out/src/WalletPermissionsManager.d.ts +19 -0
- package/out/src/WalletPermissionsManager.d.ts.map +1 -1
- package/out/src/WalletPermissionsManager.js +55 -0
- package/out/src/WalletPermissionsManager.js.map +1 -1
- package/out/src/monitor/Monitor.d.ts +3 -4
- package/out/src/monitor/Monitor.d.ts.map +1 -1
- package/out/src/monitor/Monitor.js +1 -1
- package/out/src/monitor/Monitor.js.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.d.ts +5 -3
- package/out/src/monitor/tasks/TaskArcSSE.d.ts.map +1 -1
- package/out/src/monitor/tasks/TaskArcSSE.js +42 -55
- package/out/src/monitor/tasks/TaskArcSSE.js.map +1 -1
- package/out/src/sdk/WalletServices.interfaces.d.ts +23 -1
- package/out/src/sdk/WalletServices.interfaces.d.ts.map +1 -1
- package/out/src/services/Services.d.ts +3 -0
- package/out/src/services/Services.d.ts.map +1 -1
- package/out/src/services/Services.js +20 -1
- package/out/src/services/Services.js.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts +1 -0
- package/out/src/services/chaintracker/ChaintracksChainTracker.d.ts.map +1 -1
- package/out/src/services/chaintracker/ChaintracksChainTracker.js +9 -6
- package/out/src/services/chaintracker/ChaintracksChainTracker.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts +2 -0
- package/out/src/services/chaintracker/chaintracks/Chaintracks.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js +29 -1
- package/out/src/services/chaintracker/chaintracks/Chaintracks.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.d.ts +52 -0
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.js +228 -0
- package/out/src/services/chaintracker/chaintracks/GoChaintracksServiceClient.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.d.ts +24 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.d.ts.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js +55 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.js.map +1 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.d.ts +13 -0
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.js +45 -7
- package/out/src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.d.ts +2 -0
- package/out/src/services/chaintracker/chaintracks/index.mobile.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/index.mobile.js +2 -0
- package/out/src/services/chaintracker/chaintracks/index.mobile.js.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts +8 -0
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.d.ts.map +1 -1
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js +53 -10
- package/out/src/services/chaintracker/chaintracks/util/ChaintracksFetch.js.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts +19 -1
- package/out/src/services/createDefaultWalletServicesOptions.d.ts.map +1 -1
- package/out/src/services/createDefaultWalletServicesOptions.js +49 -2
- package/out/src/services/createDefaultWalletServicesOptions.js.map +1 -1
- package/out/src/services/providers/ARC.d.ts +4 -0
- package/out/src/services/providers/ARC.d.ts.map +1 -1
- package/out/src/services/providers/ARC.js +65 -4
- package/out/src/services/providers/ARC.js.map +1 -1
- package/out/src/services/providers/ArcSSEClient.d.ts +1 -0
- package/out/src/services/providers/ArcSSEClient.d.ts.map +1 -1
- package/out/src/services/providers/ArcSSEClient.js +12 -9
- package/out/src/services/providers/ArcSSEClient.js.map +1 -1
- package/out/src/services/providers/Arcade.d.ts +72 -0
- package/out/src/services/providers/Arcade.d.ts.map +1 -0
- package/out/src/services/providers/Arcade.js +299 -0
- package/out/src/services/providers/Arcade.js.map +1 -0
- package/out/src/signer/methods/buildSignableTransaction.d.ts +54 -0
- package/out/src/signer/methods/buildSignableTransaction.d.ts.map +1 -1
- package/out/src/signer/methods/buildSignableTransaction.js +118 -2
- package/out/src/signer/methods/buildSignableTransaction.js.map +1 -1
- package/out/src/storage/methods/processAction.d.ts.map +1 -1
- package/out/src/storage/methods/processAction.js +38 -1
- package/out/src/storage/methods/processAction.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Arcade = void 0;
|
|
4
|
+
const sdk_1 = require("@bsv/sdk");
|
|
5
|
+
const utilityHelpers_1 = require("../../utility/utilityHelpers");
|
|
6
|
+
const WalletError_1 = require("../../sdk/WalletError");
|
|
7
|
+
// Shared wire-contract types only (no behavior coupling): Arcade is ARC-compatible on the
|
|
8
|
+
// configuration and `getTxData` response shape, so it reuses those interfaces.
|
|
9
|
+
const ARC_1 = require("./ARC");
|
|
10
|
+
function defaultDeploymentId() {
|
|
11
|
+
return `ts-sdk-${sdk_1.Utils.toHex((0, sdk_1.Random)(16))}`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Broadcaster for bsv-blockchain/arcade — the Teranode-native, ARC-compatible broadcaster.
|
|
15
|
+
*
|
|
16
|
+
* Arcade is intentionally a separate, self-contained class (not a subclass of {@link ARC}) so
|
|
17
|
+
* the audited ARC transport is never altered. It is ARC-compatible on headers, configuration and
|
|
18
|
+
* the `getTxData` response shape — but differs where it must:
|
|
19
|
+
*
|
|
20
|
+
* - Endpoints are served at the root: `/tx` and `/tx/{txid}` (no `/v1` prefix).
|
|
21
|
+
* - A submit returns HTTP 202; HTTP 400 is a terminal validation failure (REJECTED) and is
|
|
22
|
+
* surfaced as an invalid-transaction status error rather than a transient service error.
|
|
23
|
+
* - Submission encoding is Extended Format (EF), not BEEF: Arcade's `/tx` parser rejects BEEF
|
|
24
|
+
* ("failed to parse transaction") and runs fee/script validation that needs per-input source
|
|
25
|
+
* data, which EF carries inline.
|
|
26
|
+
*/
|
|
27
|
+
class Arcade {
|
|
28
|
+
name;
|
|
29
|
+
URL;
|
|
30
|
+
apiKey;
|
|
31
|
+
deploymentId;
|
|
32
|
+
callbackUrl;
|
|
33
|
+
callbackToken;
|
|
34
|
+
headers;
|
|
35
|
+
httpClient;
|
|
36
|
+
constructor(URL, config, name) {
|
|
37
|
+
this.name = name ?? 'arcade';
|
|
38
|
+
this.URL = URL;
|
|
39
|
+
if (typeof config === 'string') {
|
|
40
|
+
this.apiKey = config;
|
|
41
|
+
this.httpClient = (0, sdk_1.defaultHttpClient)();
|
|
42
|
+
this.deploymentId = defaultDeploymentId();
|
|
43
|
+
this.callbackToken = undefined;
|
|
44
|
+
this.callbackUrl = undefined;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const configObj = config ?? {};
|
|
48
|
+
const { apiKey, deploymentId, httpClient, callbackToken, callbackUrl, headers } = configObj;
|
|
49
|
+
this.apiKey = apiKey;
|
|
50
|
+
this.httpClient = httpClient ?? (0, sdk_1.defaultHttpClient)();
|
|
51
|
+
this.deploymentId = deploymentId ?? defaultDeploymentId();
|
|
52
|
+
this.callbackToken = callbackToken;
|
|
53
|
+
this.callbackUrl = callbackUrl;
|
|
54
|
+
this.headers = headers;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Constructs a dictionary of the default & supplied request headers. */
|
|
58
|
+
requestHeaders() {
|
|
59
|
+
const headers = {
|
|
60
|
+
'Content-Type': 'application/json',
|
|
61
|
+
'XDeployment-ID': this.deploymentId
|
|
62
|
+
};
|
|
63
|
+
if (this.apiKey != null && this.apiKey !== '') {
|
|
64
|
+
headers.Authorization = `Bearer ${this.apiKey}`;
|
|
65
|
+
}
|
|
66
|
+
if (this.callbackUrl != null && this.callbackUrl !== '') {
|
|
67
|
+
headers['X-CallbackUrl'] = this.callbackUrl;
|
|
68
|
+
}
|
|
69
|
+
if (this.callbackToken != null && this.callbackToken !== '') {
|
|
70
|
+
headers['X-CallbackToken'] = this.callbackToken;
|
|
71
|
+
}
|
|
72
|
+
if (this.headers != null) {
|
|
73
|
+
for (const key in this.headers) {
|
|
74
|
+
headers[key] = this.headers[key];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return headers;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Submit a single transaction to Arcade's `POST /tx` endpoint.
|
|
81
|
+
*
|
|
82
|
+
* `rawTx` must be a single (raw or Extended Format) transaction hex — NOT BEEF. The canonical
|
|
83
|
+
* txid is taken from `txids` when supplied (Arcade derives the same txid from the parsed tx).
|
|
84
|
+
*/
|
|
85
|
+
async postRawTx(rawTx, txids) {
|
|
86
|
+
let txid = sdk_1.Utils.toHex((0, utilityHelpers_1.doubleSha256BE)(sdk_1.Utils.toArray(rawTx, 'hex')));
|
|
87
|
+
if (txids == null) {
|
|
88
|
+
txids = [txid];
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
txid = txids.at(-1);
|
|
92
|
+
}
|
|
93
|
+
const requestOptions = {
|
|
94
|
+
method: 'POST',
|
|
95
|
+
headers: this.requestHeaders(),
|
|
96
|
+
data: { rawTx },
|
|
97
|
+
signal: AbortSignal.timeout(1000 * 30) // 30 seconds timeout, error.code will be 'ABORT_ERR'
|
|
98
|
+
};
|
|
99
|
+
const r = {
|
|
100
|
+
txid,
|
|
101
|
+
status: 'success',
|
|
102
|
+
notes: []
|
|
103
|
+
};
|
|
104
|
+
const url = `${this.URL}/tx`;
|
|
105
|
+
const nn = () => ({ name: this.name, when: new Date().toISOString() });
|
|
106
|
+
const nne = () => ({ ...nn(), rawTx, txids: txids.join(','), url });
|
|
107
|
+
try {
|
|
108
|
+
const response = await this.httpClient.request(url, requestOptions);
|
|
109
|
+
const { txid, extraInfo, txStatus, competingTxs } = response.data;
|
|
110
|
+
const nnr = () => ({
|
|
111
|
+
txid,
|
|
112
|
+
extraInfo,
|
|
113
|
+
txStatus,
|
|
114
|
+
competingTxs: competingTxs?.join(',')
|
|
115
|
+
});
|
|
116
|
+
if (response.ok) {
|
|
117
|
+
// Arcade's 202 submit response omits extraInfo; avoid a trailing 'undefined'.
|
|
118
|
+
r.data = extraInfo != null && extraInfo !== '' ? `${txStatus} ${extraInfo}` : `${txStatus}`;
|
|
119
|
+
if (r.txid !== txid)
|
|
120
|
+
r.data += ` txid altered from ${r.txid} to ${txid}`;
|
|
121
|
+
r.txid = txid;
|
|
122
|
+
if ((0, ARC_1.isArcDoubleSpendTxStatus)(txStatus)) {
|
|
123
|
+
r.status = 'error';
|
|
124
|
+
r.doubleSpend = true;
|
|
125
|
+
r.competingTxs = competingTxs;
|
|
126
|
+
r.notes.push({ ...nne(), ...nnr(), what: 'postRawTxDoubleSpend' });
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
r.notes.push({ ...nn(), ...nnr(), what: 'postRawTxSuccess' });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else if (typeof response === 'string') {
|
|
133
|
+
r.notes.push({ ...nne(), what: 'postRawTxString', response });
|
|
134
|
+
r.status = 'error';
|
|
135
|
+
// response is not normally a string
|
|
136
|
+
r.serviceError = true;
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
r.status = 'error';
|
|
140
|
+
// Arcade returns HTTP 400 for terminal validation errors — surface those as
|
|
141
|
+
// invalid-transaction status errors while keeping rate limits, batch limits,
|
|
142
|
+
// 5xx/backpressure and unknown failures as service errors.
|
|
143
|
+
const n = {
|
|
144
|
+
...nn(),
|
|
145
|
+
...nne(),
|
|
146
|
+
...nnr(),
|
|
147
|
+
what: 'postRawTxError'
|
|
148
|
+
};
|
|
149
|
+
const ed = {};
|
|
150
|
+
r.data = ed;
|
|
151
|
+
const st = typeof response.status;
|
|
152
|
+
let status;
|
|
153
|
+
if (st === 'number' || st === 'string') {
|
|
154
|
+
n.status = response.status;
|
|
155
|
+
ed.status = response.status.toString();
|
|
156
|
+
if (typeof response.status === 'number')
|
|
157
|
+
status = response.status;
|
|
158
|
+
else {
|
|
159
|
+
const parsed = Number(response.status);
|
|
160
|
+
if (Number.isFinite(parsed))
|
|
161
|
+
status = parsed;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
n.status = st;
|
|
166
|
+
ed.status = 'ERR_UNKNOWN';
|
|
167
|
+
}
|
|
168
|
+
const d = response.data;
|
|
169
|
+
if (d && typeof d === 'string') {
|
|
170
|
+
n.data = response.data.slice(0, 128);
|
|
171
|
+
}
|
|
172
|
+
else if (d && typeof d === 'object') {
|
|
173
|
+
ed.more = d;
|
|
174
|
+
ed.detail = d.detail;
|
|
175
|
+
if (typeof ed.detail !== 'string')
|
|
176
|
+
ed.detail = undefined;
|
|
177
|
+
if (ed.detail) {
|
|
178
|
+
n.detail = ed.detail;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
r.serviceError = (0, ARC_1.isArcServiceErrorStatus)(status, ed.detail);
|
|
182
|
+
r.notes.push(n);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (error_) {
|
|
186
|
+
const e = WalletError_1.WalletError.fromUnknown(error_);
|
|
187
|
+
r.status = 'error';
|
|
188
|
+
r.serviceError = true;
|
|
189
|
+
r.data = `${e.code} ${e.message}`;
|
|
190
|
+
r.notes.push({
|
|
191
|
+
...nne(),
|
|
192
|
+
what: 'postRawTxCatch',
|
|
193
|
+
code: e.code,
|
|
194
|
+
description: e.description
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return r;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Post each tx of interest as Extended Format (EF).
|
|
201
|
+
*
|
|
202
|
+
* EF needs each input's source output (satoshis + locking script). For a BEEF that carries every
|
|
203
|
+
* direct parent transaction in full (e.g. the atomic BEEF produced by createAction), that data is
|
|
204
|
+
* present and {@link Transaction.fromBEEF} can reconstruct EF. A BEEF is NOT guaranteed to contain
|
|
205
|
+
* it, however: BEEF V2 `txidOnly` entries (or an otherwise pruned BEEF) can reference a direct
|
|
206
|
+
* parent without its bytes, leaving no source output to embed — so BEEF -> EF is not always
|
|
207
|
+
* possible. When EF cannot be built for a txid, it is recorded as a (non-terminal) service error
|
|
208
|
+
* so cross-provider aggregation falls through to a BEEF-capable broadcaster, which can still
|
|
209
|
+
* broadcast the (valid) transaction.
|
|
210
|
+
*/
|
|
211
|
+
async postBeef(beef, txids) {
|
|
212
|
+
const r = {
|
|
213
|
+
name: this.name,
|
|
214
|
+
status: 'success',
|
|
215
|
+
txidResults: [],
|
|
216
|
+
notes: []
|
|
217
|
+
};
|
|
218
|
+
const nn = () => ({ name: this.name, when: new Date().toISOString() });
|
|
219
|
+
const beefBin = beef.toBinary();
|
|
220
|
+
for (const txid of txids) {
|
|
221
|
+
let efHex;
|
|
222
|
+
try {
|
|
223
|
+
efHex = sdk_1.Transaction.fromBEEF(beefBin, txid).toHexEF();
|
|
224
|
+
}
|
|
225
|
+
catch (error_) {
|
|
226
|
+
const e = WalletError_1.WalletError.fromUnknown(error_);
|
|
227
|
+
r.status = 'error';
|
|
228
|
+
const tr = {
|
|
229
|
+
txid,
|
|
230
|
+
status: 'error',
|
|
231
|
+
serviceError: true,
|
|
232
|
+
notes: [{ ...nn(), what: 'arcadeEfBuildFailed', txid, code: e.code, description: e.description }]
|
|
233
|
+
};
|
|
234
|
+
r.txidResults.push(tr);
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const prtr = await this.postRawTx(efHex, [txid]);
|
|
238
|
+
r.txidResults.push(prtr);
|
|
239
|
+
if (prtr.status === 'error')
|
|
240
|
+
r.status = 'error';
|
|
241
|
+
}
|
|
242
|
+
return r;
|
|
243
|
+
}
|
|
244
|
+
/** Look up a transaction's current status (and merkle path once mined) via `GET /tx/{txid}`. */
|
|
245
|
+
async getTxData(txid) {
|
|
246
|
+
const requestOptions = {
|
|
247
|
+
method: 'GET',
|
|
248
|
+
headers: this.requestHeaders()
|
|
249
|
+
};
|
|
250
|
+
const response = await this.httpClient.request(`${this.URL}/tx/${txid}`, requestOptions);
|
|
251
|
+
return response.data;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* `getMerklePath` provider: obtain a BUMP merkle proof for a mined transaction from Arcade.
|
|
255
|
+
*
|
|
256
|
+
* Arcade only has a proof for transactions it tracked (i.e. broadcast through it) that have
|
|
257
|
+
* been mined while tracked; for anything else `GET /tx/{txid}` reports a non-mined status (or
|
|
258
|
+
* 404) and this returns no `merklePath`, so {@link Services.getMerklePath} falls through to the
|
|
259
|
+
* other providers (WhatsOnChain/Bitails).
|
|
260
|
+
*
|
|
261
|
+
* The proof is NOT trusted blindly: the canonical block header is resolved from the wallet's
|
|
262
|
+
* own chaintracker via `services.hashToHeader(blockHash)` (which only knows real, mined blocks),
|
|
263
|
+
* and the BUMP's computed merkle root must equal that header's `merkleRoot`. Only then is the
|
|
264
|
+
* proof returned, with the canonical `header` that downstream proof completion requires.
|
|
265
|
+
*/
|
|
266
|
+
async getMerklePath(txid, services) {
|
|
267
|
+
const r = { name: this.name, notes: [] };
|
|
268
|
+
const nn = () => ({ name: this.name, when: new Date().toISOString() });
|
|
269
|
+
try {
|
|
270
|
+
const data = await this.getTxData(txid);
|
|
271
|
+
const mined = data.txStatus === 'MINED' || data.txStatus === 'IMMUTABLE';
|
|
272
|
+
if (!mined || data.merklePath == null || data.merklePath === '' || data.blockHash == null || data.blockHash === '') {
|
|
273
|
+
// No proof from Arcade yet (not mined / untracked / 404) — fall through to other providers.
|
|
274
|
+
r.notes.push({ ...nn(), what: 'getMerklePathArcadeNoProof', txid, txStatus: data.txStatus });
|
|
275
|
+
return r;
|
|
276
|
+
}
|
|
277
|
+
const merklePath = sdk_1.MerklePath.fromHex(data.merklePath);
|
|
278
|
+
// Resolve the canonical header from our own chaintracker; throws if the block is unknown.
|
|
279
|
+
const header = await services.hashToHeader(data.blockHash);
|
|
280
|
+
const computedRoot = merklePath.computeRoot(txid);
|
|
281
|
+
if (computedRoot !== header.merkleRoot) {
|
|
282
|
+
// Arcade's BUMP does not reconcile with the canonical block — reject and fall through.
|
|
283
|
+
r.notes.push({ ...nn(), what: 'getMerklePathArcadeRootMismatch', txid, computedRoot, headerRoot: header.merkleRoot, blockHash: data.blockHash });
|
|
284
|
+
return r;
|
|
285
|
+
}
|
|
286
|
+
r.merklePath = merklePath;
|
|
287
|
+
r.header = header;
|
|
288
|
+
r.notes.push({ ...nn(), what: 'getMerklePathArcadeSuccess', txid, height: header.height, blockHash: header.hash });
|
|
289
|
+
}
|
|
290
|
+
catch (error_) {
|
|
291
|
+
const e = WalletError_1.WalletError.fromUnknown(error_);
|
|
292
|
+
r.error = e;
|
|
293
|
+
r.notes.push({ ...nn(), what: 'getMerklePathArcadeError', txid, code: e.code, description: e.description });
|
|
294
|
+
}
|
|
295
|
+
return r;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
exports.Arcade = Arcade;
|
|
299
|
+
//# sourceMappingURL=Arcade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Arcade.js","sourceRoot":"","sources":["../../../../../src/services/providers/Arcade.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,60 @@ export declare function buildSignableTransaction(dctr: StorageCreateActionResult
|
|
|
8
8
|
pdi: PendingStorageInput[];
|
|
9
9
|
log: string;
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Verify that the outputs returned by storage for caller-specified outputs match
|
|
13
|
+
* exactly what the caller requested in `args.outputs`.
|
|
14
|
+
*
|
|
15
|
+
* The storage response (`StorageCreateActionResult.outputs`) is ordered, by
|
|
16
|
+
* contract, as: the caller's `args.outputs` in their original order, followed by
|
|
17
|
+
* the optional commission output, followed by storage-provided change outputs.
|
|
18
|
+
* Only the `vout` field is randomized when `randomizeOutputs` is set; the array
|
|
19
|
+
* order is stable. Therefore array index `i` (for `i < args.outputs.length`)
|
|
20
|
+
* corresponds to `args.outputs[i]`.
|
|
21
|
+
*
|
|
22
|
+
* Because the locking script that is ultimately signed is taken from the storage
|
|
23
|
+
* response, an untrusted storage provider must not be allowed to alter the
|
|
24
|
+
* recipient script (or amount) of a caller-specified output. Any mismatch is a
|
|
25
|
+
* hard error. (GHSA-36f9-7rg5-cpf8)
|
|
26
|
+
*
|
|
27
|
+
* @throws WERR_INVALID_PARAMETER if storage omitted, reclassified, or modified
|
|
28
|
+
* any caller-specified output.
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifyRequestedOutputsUnchanged(storageOutputs: StorageCreateTransactionSdkOutput[], args: Validation.ValidCreateActionArgs): void;
|
|
31
|
+
/**
|
|
32
|
+
* Default ceiling for a storage-provided commission (service-charge) output, in
|
|
33
|
+
* satoshis. The commission is the one output whose locking script is taken
|
|
34
|
+
* verbatim from storage and cannot be re-derived or verified client-side, so a
|
|
35
|
+
* malicious storage operator could point it at an attacker address. Capping it
|
|
36
|
+
* bounds the worst-case loss from that single output; honest commissions are far
|
|
37
|
+
* below this. (GHSA-36f9-7rg5-cpf8)
|
|
38
|
+
*/
|
|
39
|
+
export declare const MAX_STORAGE_COMMISSION_SATOSHIS = 500000;
|
|
40
|
+
/**
|
|
41
|
+
* Verify that every storage output beyond the caller's requested outputs is
|
|
42
|
+
* either a change output or the (single, bounded) commission output.
|
|
43
|
+
*
|
|
44
|
+
* The storage response is ordered `[caller outputs][commission?][change...]`;
|
|
45
|
+
* `verifyRequestedOutputsUnchanged` already validates the caller region (indices
|
|
46
|
+
* `< args.outputs.length`). This checks the remainder.
|
|
47
|
+
*
|
|
48
|
+
* Change outputs (`providedBy: 'storage', purpose: 'change'`) are safe at any
|
|
49
|
+
* amount: `buildSignableTransaction` ignores the storage-supplied script and
|
|
50
|
+
* re-derives it client-side (`makeChangeLock` / BRC-29 under the client's own
|
|
51
|
+
* change key), so a change output can only ever pay the client. A change output
|
|
52
|
+
* mislabeled by storage is therefore harmless.
|
|
53
|
+
*
|
|
54
|
+
* The commission output's script, by contrast, is taken verbatim from storage
|
|
55
|
+
* and cannot be verified client-side. A malicious storage could inject an extra
|
|
56
|
+
* output — or relabel one as commission — to redirect funds to an attacker while
|
|
57
|
+
* the caller/UI only sees the requested recipients. To bound that, at most one
|
|
58
|
+
* commission output is allowed and its amount must not exceed `maxCommission`.
|
|
59
|
+
* Any other unrecognized output is rejected outright.
|
|
60
|
+
*
|
|
61
|
+
* @throws WERR_INVALID_PARAMETER if storage returned an unrecognized output, more
|
|
62
|
+
* than one commission output, or a commission exceeding `maxCommission`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function verifyUnrequestedOutputsAreChangeOrCommission(storageOutputs: StorageCreateTransactionSdkOutput[], args: Validation.ValidCreateActionArgs, maxCommission?: number): void;
|
|
11
65
|
/**
|
|
12
66
|
* Derive a change output locking script
|
|
13
67
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildSignableTransaction.d.ts","sourceRoot":"","sources":["../../../../../src/signer/methods/buildSignableTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,MAAM,EAAE,WAAW,EAAuC,UAAU,EAAE,MAAM,UAAU,CAAA;AACrG,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EACL,yBAAyB,EAEzB,iCAAiC,EAClC,MAAM,oCAAoC,CAAA;AAG3C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,yBAAyB,EAC/B,IAAI,EAAE,UAAU,CAAC,qBAAqB,EACtC,MAAM,EAAE,MAAM,GACb;IACC,EAAE,EAAE,WAAW,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,mBAAmB,EAAE,CAAA;IAC1B,GAAG,EAAE,MAAM,CAAA;CACZ,
|
|
1
|
+
{"version":3,"file":"buildSignableTransaction.d.ts","sourceRoot":"","sources":["../../../../../src/signer/methods/buildSignableTransaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,MAAM,EAAE,WAAW,EAAuC,UAAU,EAAE,MAAM,UAAU,CAAA;AACrG,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EACL,yBAAyB,EAEzB,iCAAiC,EAClC,MAAM,oCAAoC,CAAA;AAG3C,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAGzC,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,yBAAyB,EAC/B,IAAI,EAAE,UAAU,CAAC,qBAAqB,EACtC,MAAM,EAAE,MAAM,GACb;IACC,EAAE,EAAE,WAAW,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,mBAAmB,EAAE,CAAA;IAC1B,GAAG,EAAE,MAAM,CAAA;CACZ,CA+JF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,+BAA+B,CAC7C,cAAc,EAAE,iCAAiC,EAAE,EACnD,IAAI,EAAE,UAAU,CAAC,qBAAqB,GACrC,IAAI,CAsCN;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,SAAS,CAAA;AAErD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6CAA6C,CAC3D,cAAc,EAAE,iCAAiC,EAAE,EACnD,IAAI,EAAE,UAAU,CAAC,qBAAqB,EACtC,aAAa,GAAE,MAAwC,GACtD,IAAI,CAkCN;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,iCAAiC,EACtC,IAAI,EAAE,yBAAyB,EAC/B,IAAI,EAAE,UAAU,CAAC,qBAAqB,EACtC,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,MAAM,GACb,MAAM,CAUR"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_STORAGE_COMMISSION_SATOSHIS = void 0;
|
|
3
4
|
exports.buildSignableTransaction = buildSignableTransaction;
|
|
5
|
+
exports.verifyRequestedOutputsUnchanged = verifyRequestedOutputsUnchanged;
|
|
6
|
+
exports.verifyUnrequestedOutputsAreChangeOrCommission = verifyUnrequestedOutputsAreChangeOrCommission;
|
|
4
7
|
exports.makeChangeLock = makeChangeLock;
|
|
5
8
|
const sdk_1 = require("@bsv/sdk");
|
|
6
9
|
const WERR_errors_1 = require("../../sdk/WERR_errors");
|
|
@@ -10,6 +13,21 @@ function buildSignableTransaction(dctr, args, wallet) {
|
|
|
10
13
|
const changeKeys = wallet.getClientChangeKeyPair();
|
|
11
14
|
const inputBeef = (args.inputBEEF != null) ? sdk_1.Beef.fromBinary(args.inputBEEF) : undefined;
|
|
12
15
|
const { inputs: storageInputs, outputs: storageOutputs } = dctr;
|
|
16
|
+
// SECURITY (GHSA-36f9-7rg5-cpf8): The locking scripts used to build and sign
|
|
17
|
+
// the transaction are taken from the storage response. When storage is remote
|
|
18
|
+
// (StorageClient, the default configuration), a malicious or compromised
|
|
19
|
+
// storage operator could return a different recipient script than the caller
|
|
20
|
+
// requested; it would be signed and broadcast while the calling app/UI still
|
|
21
|
+
// shows the originally requested recipient. Verify that every caller-specified
|
|
22
|
+
// output is echoed back by storage unchanged before anything is signed.
|
|
23
|
+
verifyRequestedOutputsUnchanged(storageOutputs, args);
|
|
24
|
+
// SECURITY (GHSA-36f9-7rg5-cpf8): verifyRequestedOutputsUnchanged only protects
|
|
25
|
+
// the caller's own outputs. Storage could instead inject an ADDITIONAL output
|
|
26
|
+
// paying an attacker (funded by reducing change), which the loop below signs
|
|
27
|
+
// verbatim. Every output beyond the caller's must be either a change output
|
|
28
|
+
// (script re-derived client-side, so it can only pay the client) or the single
|
|
29
|
+
// bounded commission output. Anything else is rejected before signing.
|
|
30
|
+
verifyUnrequestedOutputsAreChangeOrCommission(storageOutputs, args);
|
|
13
31
|
const tx = new sdk_1.Transaction(args.version, [], [], args.lockTime);
|
|
14
32
|
// The order of outputs in storageOutputs is always:
|
|
15
33
|
// CreateActionArgs.outputs in the original order
|
|
@@ -79,8 +97,7 @@ function buildSignableTransaction(dctr, args, wallet) {
|
|
|
79
97
|
if (argsInput != null) {
|
|
80
98
|
// Type 1: User supplied input, with or without an explicit unlockingScript.
|
|
81
99
|
// If without, signAction must be used to provide the actual unlockScript.
|
|
82
|
-
const
|
|
83
|
-
const unlock = hasUnlock ? (0, utilityHelpers_1.asBsvSdkScript)(argsInput.unlockingScript) : new sdk_1.Script();
|
|
100
|
+
const unlock = typeof argsInput.unlockingScript === 'string' ? (0, utilityHelpers_1.asBsvSdkScript)(argsInput.unlockingScript) : new sdk_1.Script();
|
|
84
101
|
const sourceTransaction = args.isSignAction ? inputBeef?.findTxid(argsInput.outpoint.txid)?.tx : undefined;
|
|
85
102
|
const inputToAdd = {
|
|
86
103
|
sourceTXID: argsInput.outpoint.txid,
|
|
@@ -132,6 +149,105 @@ function buildSignableTransaction(dctr, args, wallet) {
|
|
|
132
149
|
log: ''
|
|
133
150
|
};
|
|
134
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Verify that the outputs returned by storage for caller-specified outputs match
|
|
154
|
+
* exactly what the caller requested in `args.outputs`.
|
|
155
|
+
*
|
|
156
|
+
* The storage response (`StorageCreateActionResult.outputs`) is ordered, by
|
|
157
|
+
* contract, as: the caller's `args.outputs` in their original order, followed by
|
|
158
|
+
* the optional commission output, followed by storage-provided change outputs.
|
|
159
|
+
* Only the `vout` field is randomized when `randomizeOutputs` is set; the array
|
|
160
|
+
* order is stable. Therefore array index `i` (for `i < args.outputs.length`)
|
|
161
|
+
* corresponds to `args.outputs[i]`.
|
|
162
|
+
*
|
|
163
|
+
* Because the locking script that is ultimately signed is taken from the storage
|
|
164
|
+
* response, an untrusted storage provider must not be allowed to alter the
|
|
165
|
+
* recipient script (or amount) of a caller-specified output. Any mismatch is a
|
|
166
|
+
* hard error. (GHSA-36f9-7rg5-cpf8)
|
|
167
|
+
*
|
|
168
|
+
* @throws WERR_INVALID_PARAMETER if storage omitted, reclassified, or modified
|
|
169
|
+
* any caller-specified output.
|
|
170
|
+
*/
|
|
171
|
+
function verifyRequestedOutputsUnchanged(storageOutputs, args) {
|
|
172
|
+
for (let i = 0; i < args.outputs.length; i++) {
|
|
173
|
+
const requested = args.outputs[i];
|
|
174
|
+
const provided = storageOutputs[i];
|
|
175
|
+
if (provided == null) {
|
|
176
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('storage outputs', `present for every requested output. Storage did not return an output for requested output index ${i}.`);
|
|
177
|
+
}
|
|
178
|
+
// A caller-specified output must never be reclassified by storage as change
|
|
179
|
+
// or as storage-provided; doing so would route it through makeChangeLock and
|
|
180
|
+
// bypass the script comparison below.
|
|
181
|
+
if (provided.purpose === 'change' || provided.providedBy === 'storage') {
|
|
182
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('output.providedBy', `consistent with the request. Storage reclassified requested output ${i} as providedBy='${provided.providedBy}' purpose='${provided.purpose ?? ''}'.`);
|
|
183
|
+
}
|
|
184
|
+
const requestedScript = (requested.lockingScript ?? '').toLowerCase();
|
|
185
|
+
const providedScript = (typeof provided.lockingScript === 'string' ? provided.lockingScript : '').toLowerCase();
|
|
186
|
+
if (requestedScript.length === 0 || requestedScript !== providedScript) {
|
|
187
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('output.lockingScript', `equal to the caller-requested locking script. Storage returned a different locking script for output index ${i}; the recipient may have been substituted.`);
|
|
188
|
+
}
|
|
189
|
+
if (provided.satoshis !== requested.satoshis) {
|
|
190
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('output.satoshis', `equal to the caller-requested satoshis. Storage returned ${provided.satoshis} for output index ${i}, caller requested ${requested.satoshis}.`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Default ceiling for a storage-provided commission (service-charge) output, in
|
|
196
|
+
* satoshis. The commission is the one output whose locking script is taken
|
|
197
|
+
* verbatim from storage and cannot be re-derived or verified client-side, so a
|
|
198
|
+
* malicious storage operator could point it at an attacker address. Capping it
|
|
199
|
+
* bounds the worst-case loss from that single output; honest commissions are far
|
|
200
|
+
* below this. (GHSA-36f9-7rg5-cpf8)
|
|
201
|
+
*/
|
|
202
|
+
exports.MAX_STORAGE_COMMISSION_SATOSHIS = 500000;
|
|
203
|
+
/**
|
|
204
|
+
* Verify that every storage output beyond the caller's requested outputs is
|
|
205
|
+
* either a change output or the (single, bounded) commission output.
|
|
206
|
+
*
|
|
207
|
+
* The storage response is ordered `[caller outputs][commission?][change...]`;
|
|
208
|
+
* `verifyRequestedOutputsUnchanged` already validates the caller region (indices
|
|
209
|
+
* `< args.outputs.length`). This checks the remainder.
|
|
210
|
+
*
|
|
211
|
+
* Change outputs (`providedBy: 'storage', purpose: 'change'`) are safe at any
|
|
212
|
+
* amount: `buildSignableTransaction` ignores the storage-supplied script and
|
|
213
|
+
* re-derives it client-side (`makeChangeLock` / BRC-29 under the client's own
|
|
214
|
+
* change key), so a change output can only ever pay the client. A change output
|
|
215
|
+
* mislabeled by storage is therefore harmless.
|
|
216
|
+
*
|
|
217
|
+
* The commission output's script, by contrast, is taken verbatim from storage
|
|
218
|
+
* and cannot be verified client-side. A malicious storage could inject an extra
|
|
219
|
+
* output — or relabel one as commission — to redirect funds to an attacker while
|
|
220
|
+
* the caller/UI only sees the requested recipients. To bound that, at most one
|
|
221
|
+
* commission output is allowed and its amount must not exceed `maxCommission`.
|
|
222
|
+
* Any other unrecognized output is rejected outright.
|
|
223
|
+
*
|
|
224
|
+
* @throws WERR_INVALID_PARAMETER if storage returned an unrecognized output, more
|
|
225
|
+
* than one commission output, or a commission exceeding `maxCommission`.
|
|
226
|
+
*/
|
|
227
|
+
function verifyUnrequestedOutputsAreChangeOrCommission(storageOutputs, args, maxCommission = exports.MAX_STORAGE_COMMISSION_SATOSHIS) {
|
|
228
|
+
let commissionCount = 0;
|
|
229
|
+
for (let i = args.outputs.length; i < storageOutputs.length; i++) {
|
|
230
|
+
const out = storageOutputs[i];
|
|
231
|
+
const isChange = out.providedBy === 'storage' && out.purpose === 'change';
|
|
232
|
+
if (isChange)
|
|
233
|
+
continue;
|
|
234
|
+
// Honest storage remaps a service-charge to purpose 'storage-commission';
|
|
235
|
+
// accept the pre-remap label too so the check is robust across versions.
|
|
236
|
+
const isCommission = out.providedBy === 'storage' && (out.purpose === 'storage-commission' || out.purpose === 'service-charge');
|
|
237
|
+
if (isCommission) {
|
|
238
|
+
commissionCount++;
|
|
239
|
+
if (commissionCount > 1) {
|
|
240
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('storage outputs', `at most one commission output. Storage returned an extra commission output at index ${i}.`);
|
|
241
|
+
}
|
|
242
|
+
if (out.satoshis > maxCommission) {
|
|
243
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('output.satoshis', `a commission no greater than ${maxCommission}. Storage returned a commission of ${out.satoshis} at index ${i}; funds could be redirected to an attacker.`);
|
|
244
|
+
}
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
throw new WERR_errors_1.WERR_INVALID_PARAMETER('storage outputs', 'only change or commission beyond the requested outputs. Storage returned an unrecognized output ' +
|
|
248
|
+
`(providedBy='${out.providedBy}' purpose='${out.purpose ?? ''}') at index ${i}; funds could be redirected to an attacker.`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
135
251
|
/**
|
|
136
252
|
* Derive a change output locking script
|
|
137
253
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildSignableTransaction.js","sourceRoot":"","sources":["../../../../../src/signer/methods/buildSignableTransaction.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"buildSignableTransaction.js","sourceRoot":"","sources":["../../../../../src/signer/methods/buildSignableTransaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processAction.d.ts","sourceRoot":"","sources":["../../../../../src/storage/methods/processAction.ts"],"names":[],"mappings":"AACA,OAAO,EACL,IAAI,EAEJ,cAAc,EAEd,qBAAqB,EACtB,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,oCAAoC,CAAA;AAU3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"processAction.d.ts","sourceRoot":"","sources":["../../../../../src/storage/methods/processAction.ts"],"names":[],"mappings":"AACA,OAAO,EACL,IAAI,EAEJ,cAAc,EAEd,qBAAqB,EACtB,MAAM,UAAU,CAAA;AAEjB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,wBAAwB,EACxB,2BAA2B,EAC5B,MAAM,oCAAoC,CAAA;AAU3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAA;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAU9D,wBAAsB,aAAa,CACjC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,2BAA2B,CAAC,CA0CtC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,gBAAgB,CAAA;IACtB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,MAAM,EAAE,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,CAAA;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,IAAI,CAAA;IACV,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAA;IAEZ;;OAEG;IACH,MAAM,EAAE,SAAS,GAAG,OAAO,CAAA;IAE3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAmFD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,OAAO,EAClB,CAAC,CAAC,EAAE,oBAAoB,EACxB,MAAM,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC;IAAE,GAAG,EAAE,cAAc,EAAE,CAAC;IAAC,GAAG,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAAA;CAAE,CAAC,CAyC3E;AAwLD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,iBAAiB,CAAA;IACtB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb"}
|
|
@@ -11,6 +11,8 @@ const EntityProvenTxReq_1 = require("../schema/entities/EntityProvenTxReq");
|
|
|
11
11
|
const WERR_errors_1 = require("../../sdk/WERR_errors");
|
|
12
12
|
const parseTxScriptOffsets_1 = require("../../utility/parseTxScriptOffsets");
|
|
13
13
|
const utilityHelpers_noBuffer_1 = require("../../utility/utilityHelpers.noBuffer");
|
|
14
|
+
const WalletError_1 = require("../../sdk/WalletError");
|
|
15
|
+
const storageProviderHelpers_1 = require("../storageProviderHelpers");
|
|
14
16
|
async function processAction(storage, auth, args) {
|
|
15
17
|
const logger = args.logger;
|
|
16
18
|
logger?.group('storage processAction');
|
|
@@ -76,12 +78,47 @@ async function verifyMergedBeef(storage, r, readyToSendReqs, logger) {
|
|
|
76
78
|
}
|
|
77
79
|
logger?.log('beef is valid');
|
|
78
80
|
}
|
|
81
|
+
async function getReqDetailsForDelayedShare(storage, txids) {
|
|
82
|
+
const r = {
|
|
83
|
+
beef: new sdk_1.Beef(),
|
|
84
|
+
details: []
|
|
85
|
+
};
|
|
86
|
+
for (const txid of txids) {
|
|
87
|
+
const d = {
|
|
88
|
+
txid,
|
|
89
|
+
status: 'unknown'
|
|
90
|
+
};
|
|
91
|
+
r.details.push(d);
|
|
92
|
+
try {
|
|
93
|
+
d.proven = (0, utilityHelpers_1.verifyOneOrNone)(await storage.findProvenTxs({ partial: { txid } }));
|
|
94
|
+
if (d.proven != null) {
|
|
95
|
+
d.status = 'alreadySent';
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
d.req = (0, utilityHelpers_1.verifyOneOrNone)(await storage.findProvenTxReqs({ partial: { txid } }));
|
|
99
|
+
if (d.req == null) {
|
|
100
|
+
d.status = 'error';
|
|
101
|
+
d.error = `ERR_UNKNOWN_TXID: ${txid} was not found.`;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
(0, storageProviderHelpers_1.classifyReqStatus)(d, d.req);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error_) {
|
|
108
|
+
const e = WalletError_1.WalletError.fromUnknown(error_);
|
|
109
|
+
d.error = `${e.name}: ${e.message}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return r;
|
|
113
|
+
}
|
|
79
114
|
async function shareReqsWithWorld(storage, userId, txids, isDelayed, r, logger) {
|
|
80
115
|
const swr = [];
|
|
81
116
|
const ndr = undefined;
|
|
82
117
|
if ((r == null) && txids.length < 1)
|
|
83
118
|
return { swr, ndr };
|
|
84
|
-
r ||=
|
|
119
|
+
r ||= isDelayed
|
|
120
|
+
? await getReqDetailsForDelayedShare(storage, txids)
|
|
121
|
+
: await storage.getReqsAndBeefToShareWithWorld(txids, []);
|
|
85
122
|
const readyToSendReqs = [];
|
|
86
123
|
classifyReqDetails(r.details, swr, readyToSendReqs);
|
|
87
124
|
const readyToSendReqIds = readyToSendReqs.map(r => r.id);
|