@arkade-os/sdk 0.3.0-alpha.0 → 0.3.0-alpha.2

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 (73) hide show
  1. package/dist/cjs/arknote/index.js +4 -4
  2. package/dist/cjs/bip322/index.js +9 -7
  3. package/dist/cjs/forfeit.js +2 -2
  4. package/dist/cjs/identity/singleKey.js +10 -7
  5. package/dist/cjs/index.js +2 -2
  6. package/dist/cjs/musig2/keys.js +1 -1
  7. package/dist/cjs/musig2/nonces.js +1 -1
  8. package/dist/cjs/musig2/sign.js +1 -1
  9. package/dist/cjs/networks.js +6 -6
  10. package/dist/cjs/providers/ark.js +53 -71
  11. package/dist/cjs/providers/indexer.js +45 -51
  12. package/dist/cjs/providers/utils.js +60 -0
  13. package/dist/cjs/repositories/walletRepository.js +34 -4
  14. package/dist/cjs/script/address.js +3 -3
  15. package/dist/cjs/script/base.js +7 -7
  16. package/dist/cjs/script/tapscript.js +29 -23
  17. package/dist/cjs/script/vhtlc.js +2 -2
  18. package/dist/cjs/tree/signingSession.js +11 -10
  19. package/dist/cjs/tree/txTree.js +9 -9
  20. package/dist/cjs/tree/validation.js +6 -6
  21. package/dist/cjs/utils/arkTransaction.js +5 -5
  22. package/dist/cjs/utils/unknownFields.js +5 -5
  23. package/dist/cjs/wallet/onchain.js +5 -5
  24. package/dist/cjs/wallet/unroll.js +6 -6
  25. package/dist/cjs/wallet/wallet.js +21 -22
  26. package/dist/esm/arknote/index.js +2 -2
  27. package/dist/esm/bip322/index.js +3 -1
  28. package/dist/esm/forfeit.js +1 -1
  29. package/dist/esm/identity/singleKey.js +5 -2
  30. package/dist/esm/index.js +1 -1
  31. package/dist/esm/musig2/keys.js +1 -1
  32. package/dist/esm/musig2/nonces.js +1 -1
  33. package/dist/esm/musig2/sign.js +1 -1
  34. package/dist/esm/networks.js +1 -1
  35. package/dist/esm/providers/ark.js +53 -71
  36. package/dist/esm/providers/indexer.js +45 -51
  37. package/dist/esm/providers/utils.js +57 -0
  38. package/dist/esm/repositories/walletRepository.js +34 -4
  39. package/dist/esm/script/address.js +1 -1
  40. package/dist/esm/script/base.js +3 -3
  41. package/dist/esm/script/tapscript.js +10 -4
  42. package/dist/esm/script/vhtlc.js +1 -1
  43. package/dist/esm/tree/signingSession.js +6 -5
  44. package/dist/esm/tree/txTree.js +5 -5
  45. package/dist/esm/tree/validation.js +3 -3
  46. package/dist/esm/utils/arkTransaction.js +2 -2
  47. package/dist/esm/utils/unknownFields.js +1 -1
  48. package/dist/esm/wallet/onchain.js +2 -2
  49. package/dist/esm/wallet/unroll.js +2 -2
  50. package/dist/esm/wallet/wallet.js +9 -10
  51. package/dist/types/arknote/index.d.ts +1 -1
  52. package/dist/types/bip322/index.d.ts +2 -2
  53. package/dist/types/forfeit.d.ts +1 -1
  54. package/dist/types/identity/index.d.ts +4 -3
  55. package/dist/types/identity/singleKey.d.ts +2 -1
  56. package/dist/types/index.d.ts +1 -1
  57. package/dist/types/providers/ark.d.ts +1 -0
  58. package/dist/types/providers/utils.d.ts +1 -0
  59. package/dist/types/script/address.d.ts +1 -1
  60. package/dist/types/script/base.d.ts +1 -1
  61. package/dist/types/script/default.d.ts +1 -1
  62. package/dist/types/script/tapscript.d.ts +1 -1
  63. package/dist/types/script/vhtlc.d.ts +1 -1
  64. package/dist/types/tree/txTree.d.ts +3 -3
  65. package/dist/types/tree/validation.d.ts +1 -1
  66. package/dist/types/utils/anchor.d.ts +1 -1
  67. package/dist/types/utils/arkTransaction.d.ts +3 -3
  68. package/dist/types/utils/unknownFields.d.ts +1 -1
  69. package/dist/types/wallet/index.d.ts +1 -1
  70. package/dist/types/wallet/onchain.d.ts +2 -2
  71. package/dist/types/wallet/unroll.d.ts +1 -1
  72. package/dist/types/wallet/wallet.d.ts +1 -1
  73. package/package.json +3 -2
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ArkNote = void 0;
4
4
  const base_1 = require("@scure/base");
5
5
  const base_2 = require("../script/base");
6
- const utils_1 = require("@scure/btc-signer/utils");
7
- const btc_signer_1 = require("@scure/btc-signer");
6
+ const utils_js_1 = require("@scure/btc-signer/utils.js");
7
+ const script_js_1 = require("@scure/btc-signer/script.js");
8
8
  /**
9
9
  * ArkNotes are special virtual coins in the Ark protocol that can be created
10
10
  * and spent without requiring any transactions. The server mints them, and they
@@ -29,7 +29,7 @@ class ArkNote {
29
29
  this.value = value;
30
30
  this.HRP = HRP;
31
31
  this.vout = 0;
32
- const preimageHash = (0, utils_1.sha256)(this.preimage);
32
+ const preimageHash = (0, utils_js_1.sha256)(this.preimage);
33
33
  this.vtxoScript = new base_2.VtxoScript([noteTapscript(preimageHash)]);
34
34
  const leaf = this.vtxoScript.leaves[0];
35
35
  this.txid = base_1.hex.encode(new Uint8Array(preimageHash).reverse());
@@ -85,5 +85,5 @@ function readUInt32BE(array, offset) {
85
85
  return view.getUint32(0, false);
86
86
  }
87
87
  function noteTapscript(preimageHash) {
88
- return btc_signer_1.Script.encode(["SHA256", preimageHash, "EQUAL"]);
88
+ return script_js_1.Script.encode(["SHA256", preimageHash, "EQUAL"]);
89
89
  }
@@ -2,7 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BIP322 = void 0;
4
4
  exports.craftToSpendTx = craftToSpendTx;
5
- const btc_signer_1 = require("@scure/btc-signer");
5
+ const script_js_1 = require("@scure/btc-signer/script.js");
6
+ const transaction_js_1 = require("@scure/btc-signer/transaction.js");
7
+ const script_js_2 = require("@scure/btc-signer/script.js");
6
8
  const errors_1 = require("./errors");
7
9
  const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
8
10
  const base_1 = require("@scure/base");
@@ -75,7 +77,7 @@ var BIP322;
75
77
  }
76
78
  BIP322.signature = signature;
77
79
  })(BIP322 || (exports.BIP322 = BIP322 = {}));
78
- const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btc_signer_1.OP.RETURN]);
80
+ const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([script_js_1.OP.RETURN]);
79
81
  const ZERO_32 = new Uint8Array(32).fill(0);
80
82
  const MAX_INDEX = 0xffffffff;
81
83
  const TAG_BIP322 = "BIP0322-signed-message";
@@ -106,7 +108,7 @@ function validateOutputs(outputs) {
106
108
  // craftToSpendTx creates the initial transaction that will be spent in the proof
107
109
  function craftToSpendTx(message, pkScript) {
108
110
  const messageHash = hashMessage(message);
109
- const tx = new btc_signer_1.Transaction({
111
+ const tx = new transaction_js_1.Transaction({
110
112
  version: 0,
111
113
  allowUnknownOutputs: true,
112
114
  allowUnknown: true,
@@ -124,14 +126,14 @@ function craftToSpendTx(message, pkScript) {
124
126
  script: pkScript,
125
127
  });
126
128
  tx.updateInput(0, {
127
- finalScriptSig: btc_signer_1.Script.encode(["OP_0", messageHash]),
129
+ finalScriptSig: script_js_2.Script.encode(["OP_0", messageHash]),
128
130
  });
129
131
  return tx;
130
132
  }
131
133
  // craftToSignTx creates the transaction that will be signed for the proof
132
134
  function craftToSignTx(toSpend, inputs, outputs) {
133
135
  const firstInput = inputs[0];
134
- const tx = new btc_signer_1.Transaction({
136
+ const tx = new transaction_js_1.Transaction({
135
137
  version: 2,
136
138
  allowUnknownOutputs: outputs.length === 0,
137
139
  allowUnknown: true,
@@ -147,13 +149,13 @@ function craftToSignTx(toSpend, inputs, outputs) {
147
149
  script: firstInput.witnessUtxo.script,
148
150
  amount: 0n,
149
151
  },
150
- sighashType: btc_signer_1.SigHash.ALL,
152
+ sighashType: transaction_js_1.SigHash.ALL,
151
153
  });
152
154
  // add other inputs
153
155
  for (const input of inputs) {
154
156
  tx.addInput({
155
157
  ...input,
156
- sighashType: btc_signer_1.SigHash.ALL,
158
+ sighashType: transaction_js_1.SigHash.ALL,
157
159
  });
158
160
  }
159
161
  // add the special OP_RETURN output if no outputs are provided
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildForfeitTx = buildForfeitTx;
4
- const btc_signer_1 = require("@scure/btc-signer");
4
+ const transaction_js_1 = require("@scure/btc-signer/transaction.js");
5
5
  const anchor_1 = require("./utils/anchor");
6
6
  function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
7
- const tx = new btc_signer_1.Transaction({
7
+ const tx = new transaction_js_1.Transaction({
8
8
  version: 3,
9
9
  lockTime: txLocktime,
10
10
  });
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SingleKey = void 0;
4
- const utils_1 = require("@scure/btc-signer/utils");
4
+ const utils_js_1 = require("@scure/btc-signer/utils.js");
5
5
  const base_1 = require("@scure/base");
6
- const btc_signer_1 = require("@scure/btc-signer");
6
+ const transaction_js_1 = require("@scure/btc-signer/transaction.js");
7
7
  const signingSession_1 = require("../tree/signingSession");
8
8
  const secp256k1_1 = require("@noble/secp256k1");
9
9
  const ZERO_32 = new Uint8Array(32).fill(0);
10
- const ALL_SIGHASH = Object.values(btc_signer_1.SigHash).filter((x) => typeof x === "number");
10
+ const ALL_SIGHASH = Object.values(transaction_js_1.SigHash).filter((x) => typeof x === "number");
11
11
  /**
12
12
  * In-memory single key implementation for Bitcoin transaction signing.
13
13
  *
@@ -28,7 +28,7 @@ const ALL_SIGHASH = Object.values(btc_signer_1.SigHash).filter((x) => typeof x =
28
28
  */
29
29
  class SingleKey {
30
30
  constructor(key) {
31
- this.key = key || (0, utils_1.randomPrivateKeyBytes)();
31
+ this.key = key || (0, utils_js_1.randomPrivateKeyBytes)();
32
32
  }
33
33
  static fromPrivateKey(privateKey) {
34
34
  return new SingleKey(privateKey);
@@ -37,7 +37,7 @@ class SingleKey {
37
37
  return new SingleKey(base_1.hex.decode(privateKeyHex));
38
38
  }
39
39
  static fromRandomBytes() {
40
- return new SingleKey((0, utils_1.randomPrivateKeyBytes)());
40
+ return new SingleKey((0, utils_js_1.randomPrivateKeyBytes)());
41
41
  }
42
42
  /**
43
43
  * Export the private key as a hex string.
@@ -73,15 +73,18 @@ class SingleKey {
73
73
  }
74
74
  return txCpy;
75
75
  }
76
+ compressedPublicKey() {
77
+ return Promise.resolve((0, utils_js_1.pubECDSA)(this.key, true));
78
+ }
76
79
  xOnlyPublicKey() {
77
- return Promise.resolve((0, utils_1.pubSchnorr)(this.key));
80
+ return Promise.resolve((0, utils_js_1.pubSchnorr)(this.key));
78
81
  }
79
82
  signerSession() {
80
83
  return signingSession_1.TreeSignerSession.random();
81
84
  }
82
85
  async signMessage(message) {
83
86
  const msgBytes = new TextEncoder().encode(message);
84
- return secp256k1_1.schnorr.sign((0, utils_1.sha256)(msgBytes), this.key);
87
+ return secp256k1_1.schnorr.sign((0, utils_js_1.sha256)(msgBytes), this.key);
85
88
  }
86
89
  }
87
90
  exports.SingleKey = SingleKey;
package/dist/cjs/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.networks = exports.ArkNote = exports.waitForIncomingFunds = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.getArkPsbtFields = exports.setArkPsbtField = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.Response = exports.Request = exports.ServiceWorkerWallet = exports.Worker = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.Ramps = exports.OnchainWallet = exports.SingleKey = exports.Wallet = void 0;
4
- const btc_signer_1 = require("@scure/btc-signer");
5
- Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return btc_signer_1.Transaction; } });
4
+ const transaction_js_1 = require("@scure/btc-signer/transaction.js");
5
+ Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_js_1.Transaction; } });
6
6
  const singleKey_1 = require("./identity/singleKey");
7
7
  Object.defineProperty(exports, "SingleKey", { enumerable: true, get: function () { return singleKey_1.SingleKey; } });
8
8
  const address_1 = require("./script/address");
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.aggregateKeys = aggregateKeys;
37
- const musig = __importStar(require("@scure/btc-signer/musig2"));
37
+ const musig = __importStar(require("@scure/btc-signer/musig2.js"));
38
38
  const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
39
39
  // Aggregates multiple public keys according to the MuSig2 algorithm
40
40
  function aggregateKeys(publicKeys, sort, options = {}) {
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.generateNonces = generateNonces;
37
- const musig = __importStar(require("@scure/btc-signer/musig2"));
37
+ const musig = __importStar(require("@scure/btc-signer/musig2.js"));
38
38
  /**
39
39
  * Generates a pair of public and secret nonces for MuSig2 signing
40
40
  */
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.PartialSig = exports.PartialSignatureError = void 0;
37
37
  exports.sign = sign;
38
- const musig = __importStar(require("@scure/btc-signer/musig2"));
38
+ const musig = __importStar(require("@scure/btc-signer/musig2.js"));
39
39
  const utils_js_1 = require("@noble/curves/utils.js");
40
40
  const secp256k1_1 = require("@noble/secp256k1");
41
41
  const keys_1 = require("./keys");
@@ -1,18 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.networks = exports.getNetwork = void 0;
4
- const btc_signer_1 = require("@scure/btc-signer");
4
+ const utils_js_1 = require("@scure/btc-signer/utils.js");
5
5
  const getNetwork = (network) => {
6
6
  return exports.networks[network];
7
7
  };
8
8
  exports.getNetwork = getNetwork;
9
9
  exports.networks = {
10
- bitcoin: withArkPrefix(btc_signer_1.NETWORK, "ark"),
11
- testnet: withArkPrefix(btc_signer_1.TEST_NETWORK, "tark"),
12
- signet: withArkPrefix(btc_signer_1.TEST_NETWORK, "tark"),
13
- mutinynet: withArkPrefix(btc_signer_1.TEST_NETWORK, "tark"),
10
+ bitcoin: withArkPrefix(utils_js_1.NETWORK, "ark"),
11
+ testnet: withArkPrefix(utils_js_1.TEST_NETWORK, "tark"),
12
+ signet: withArkPrefix(utils_js_1.TEST_NETWORK, "tark"),
13
+ mutinynet: withArkPrefix(utils_js_1.TEST_NETWORK, "tark"),
14
14
  regtest: withArkPrefix({
15
- ...btc_signer_1.TEST_NETWORK,
15
+ ...utils_js_1.TEST_NETWORK,
16
16
  bech32: "bcrt",
17
17
  pubKeyHash: 0x6f,
18
18
  scriptHash: 0xc4,
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RestArkProvider = exports.SettlementEventType = void 0;
4
4
  exports.isFetchTimeoutError = isFetchTimeoutError;
5
5
  const base_1 = require("@scure/base");
6
+ const utils_1 = require("./utils");
6
7
  var SettlementEventType;
7
8
  (function (SettlementEventType) {
8
9
  SettlementEventType["BatchStarted"] = "batch_started";
@@ -45,6 +46,7 @@ class RestArkProvider {
45
46
  vtxoMinAmount: BigInt(fromServer.vtxoMinAmount ?? 0),
46
47
  vtxoMaxAmount: BigInt(fromServer.vtxoMaxAmount ?? -1),
47
48
  boardingExitDelay: BigInt(fromServer.boardingExitDelay ?? 0),
49
+ checkpointExitClosure: fromServer.checkpointTapscript ?? "",
48
50
  marketHour: "marketHour" in fromServer && fromServer.marketHour != null
49
51
  ? {
50
52
  nextStartTime: BigInt(fromServer.marketHour.nextStartTime ?? 0),
@@ -219,39 +221,21 @@ class RestArkProvider {
219
221
  : "";
220
222
  while (!signal?.aborted) {
221
223
  try {
222
- const response = await fetch(url + queryParams, {
223
- headers: {
224
- Accept: "application/json",
225
- },
226
- signal,
227
- });
228
- if (!response.ok) {
229
- throw new Error(`Unexpected status ${response.status} when fetching event stream`);
230
- }
231
- if (!response.body) {
232
- throw new Error("Response body is null");
233
- }
234
- const reader = response.body.getReader();
235
- const decoder = new TextDecoder();
236
- let buffer = "";
237
- while (!signal?.aborted) {
238
- const { done, value } = await reader.read();
239
- if (done) {
240
- break;
241
- }
242
- // Append new data to buffer and split by newlines
243
- buffer += decoder.decode(value, { stream: true });
244
- const lines = buffer.split("\n");
245
- // Process all complete lines
246
- for (let i = 0; i < lines.length - 1; i++) {
247
- const line = lines[i].trim();
248
- if (!line)
249
- continue;
224
+ const eventSource = new EventSource(url + queryParams);
225
+ // Set up abort handling
226
+ const abortHandler = () => {
227
+ eventSource.close();
228
+ };
229
+ signal?.addEventListener("abort", abortHandler);
230
+ try {
231
+ for await (const event of (0, utils_1.eventSourceIterator)(eventSource)) {
232
+ if (signal?.aborted)
233
+ break;
250
234
  try {
251
- const data = JSON.parse(line);
252
- const event = this.parseSettlementEvent(data.result);
253
- if (event) {
254
- yield event;
235
+ const data = JSON.parse(event.data);
236
+ const settlementEvent = this.parseSettlementEvent(data);
237
+ if (settlementEvent) {
238
+ yield settlementEvent;
255
239
  }
256
240
  }
257
241
  catch (err) {
@@ -259,8 +243,10 @@ class RestArkProvider {
259
243
  throw err;
260
244
  }
261
245
  }
262
- // Keep the last partial line in the buffer
263
- buffer = lines[lines.length - 1];
246
+ }
247
+ finally {
248
+ signal?.removeEventListener("abort", abortHandler);
249
+ eventSource.close();
264
250
  }
265
251
  }
266
252
  catch (error) {
@@ -268,7 +254,6 @@ class RestArkProvider {
268
254
  break;
269
255
  }
270
256
  // ignore timeout errors, they're expected when the server is not sending anything for 5 min
271
- // these timeouts are set by builtin fetch function
272
257
  if (isFetchTimeoutError(error)) {
273
258
  console.debug("Timeout error ignored");
274
259
  continue;
@@ -282,42 +267,32 @@ class RestArkProvider {
282
267
  const url = `${this.serverUrl}/v1/txs`;
283
268
  while (!signal?.aborted) {
284
269
  try {
285
- const response = await fetch(url, {
286
- headers: {
287
- Accept: "application/json",
288
- },
289
- signal,
290
- });
291
- if (!response.ok) {
292
- throw new Error(`Unexpected status ${response.status} when fetching transaction stream`);
293
- }
294
- if (!response.body) {
295
- throw new Error("Response body is null");
296
- }
297
- const reader = response.body.getReader();
298
- const decoder = new TextDecoder();
299
- let buffer = "";
300
- while (!signal?.aborted) {
301
- const { done, value } = await reader.read();
302
- if (done) {
303
- break;
304
- }
305
- // Append new data to buffer and split by newlines
306
- buffer += decoder.decode(value, { stream: true });
307
- const lines = buffer.split("\n");
308
- // Process all complete lines
309
- for (let i = 0; i < lines.length - 1; i++) {
310
- const line = lines[i].trim();
311
- if (!line)
312
- continue;
313
- const data = JSON.parse(line);
314
- const txNotification = this.parseTransactionNotification(data.result);
315
- if (txNotification) {
316
- yield txNotification;
270
+ const eventSource = new EventSource(url);
271
+ // Set up abort handling
272
+ const abortHandler = () => {
273
+ eventSource.close();
274
+ };
275
+ signal?.addEventListener("abort", abortHandler);
276
+ try {
277
+ for await (const event of (0, utils_1.eventSourceIterator)(eventSource)) {
278
+ if (signal?.aborted)
279
+ break;
280
+ try {
281
+ const data = JSON.parse(event.data);
282
+ const txNotification = this.parseTransactionNotification(data);
283
+ if (txNotification) {
284
+ yield txNotification;
285
+ }
286
+ }
287
+ catch (err) {
288
+ console.error("Failed to parse transaction notification:", err);
289
+ throw err;
317
290
  }
318
291
  }
319
- // Keep the last partial line in the buffer
320
- buffer = lines[lines.length - 1];
292
+ }
293
+ finally {
294
+ signal?.removeEventListener("abort", abortHandler);
295
+ eventSource.close();
321
296
  }
322
297
  }
323
298
  catch (error) {
@@ -325,12 +300,11 @@ class RestArkProvider {
325
300
  break;
326
301
  }
327
302
  // ignore timeout errors, they're expected when the server is not sending anything for 5 min
328
- // these timeouts are set by builtin fetch function
329
303
  if (isFetchTimeoutError(error)) {
330
304
  console.debug("Timeout error ignored");
331
305
  continue;
332
306
  }
333
- console.error("Address subscription error:", error);
307
+ console.error("Transaction stream error:", error);
334
308
  throw error;
335
309
  }
336
310
  }
@@ -413,6 +387,10 @@ class RestArkProvider {
413
387
  signature: data.treeSignature.signature,
414
388
  };
415
389
  }
390
+ // Skip heartbeat events
391
+ if (data.heartbeat) {
392
+ return null;
393
+ }
416
394
  console.warn("Unknown event type:", data);
417
395
  return null;
418
396
  }
@@ -439,6 +417,10 @@ class RestArkProvider {
439
417
  },
440
418
  };
441
419
  }
420
+ // Skip heartbeat events
421
+ if (data.heartbeat) {
422
+ return null;
423
+ }
442
424
  console.warn("Unknown transaction notification type:", data);
443
425
  return null;
444
426
  }
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RestIndexerProvider = exports.ChainTxType = exports.IndexerTxType = void 0;
4
4
  const ark_1 = require("./ark");
5
+ const utils_1 = require("./utils");
5
6
  var IndexerTxType;
6
7
  (function (IndexerTxType) {
7
8
  IndexerTxType[IndexerTxType["INDEXER_TX_TYPE_UNSPECIFIED"] = 0] = "INDEXER_TX_TYPE_UNSPECIFIED";
@@ -30,7 +31,7 @@ class RestIndexerProvider {
30
31
  this.serverUrl = serverUrl;
31
32
  }
32
33
  async getVtxoTree(batchOutpoint, opts) {
33
- let url = `${this.serverUrl}/v1/batch/${batchOutpoint.txid}/${batchOutpoint.vout}/tree`;
34
+ let url = `${this.serverUrl}/v1/indexer/batch/${batchOutpoint.txid}/${batchOutpoint.vout}/tree`;
34
35
  const params = new URLSearchParams();
35
36
  if (opts) {
36
37
  if (opts.pageIndex !== undefined)
@@ -58,7 +59,7 @@ class RestIndexerProvider {
58
59
  return data;
59
60
  }
60
61
  async getVtxoTreeLeaves(batchOutpoint, opts) {
61
- let url = `${this.serverUrl}/v1/batch/${batchOutpoint.txid}/${batchOutpoint.vout}/tree/leaves`;
62
+ let url = `${this.serverUrl}/v1/indexer/batch/${batchOutpoint.txid}/${batchOutpoint.vout}/tree/leaves`;
62
63
  const params = new URLSearchParams();
63
64
  if (opts) {
64
65
  if (opts.pageIndex !== undefined)
@@ -80,7 +81,7 @@ class RestIndexerProvider {
80
81
  return data;
81
82
  }
82
83
  async getBatchSweepTransactions(batchOutpoint) {
83
- const url = `${this.serverUrl}/v1/batch/${batchOutpoint.txid}/${batchOutpoint.vout}/sweepTxs`;
84
+ const url = `${this.serverUrl}/v1/indexer/batch/${batchOutpoint.txid}/${batchOutpoint.vout}/sweepTxs`;
84
85
  const res = await fetch(url);
85
86
  if (!res.ok) {
86
87
  throw new Error(`Failed to fetch batch sweep transactions: ${res.statusText}`);
@@ -92,7 +93,7 @@ class RestIndexerProvider {
92
93
  return data;
93
94
  }
94
95
  async getCommitmentTx(txid) {
95
- const url = `${this.serverUrl}/v1/commitmentTx/${txid}`;
96
+ const url = `${this.serverUrl}/v1/indexer/commitmentTx/${txid}`;
96
97
  const res = await fetch(url);
97
98
  if (!res.ok) {
98
99
  throw new Error(`Failed to fetch commitment tx: ${res.statusText}`);
@@ -104,7 +105,7 @@ class RestIndexerProvider {
104
105
  return data;
105
106
  }
106
107
  async getCommitmentTxConnectors(txid, opts) {
107
- let url = `${this.serverUrl}/v1/commitmentTx/${txid}/connectors`;
108
+ let url = `${this.serverUrl}/v1/indexer/commitmentTx/${txid}/connectors`;
108
109
  const params = new URLSearchParams();
109
110
  if (opts) {
110
111
  if (opts.pageIndex !== undefined)
@@ -132,7 +133,7 @@ class RestIndexerProvider {
132
133
  return data;
133
134
  }
134
135
  async getCommitmentTxForfeitTxs(txid, opts) {
135
- let url = `${this.serverUrl}/v1/commitmentTx/${txid}/forfeitTxs`;
136
+ let url = `${this.serverUrl}/v1/indexer/commitmentTx/${txid}/forfeitTxs`;
136
137
  const params = new URLSearchParams();
137
138
  if (opts) {
138
139
  if (opts.pageIndex !== undefined)
@@ -154,47 +155,41 @@ class RestIndexerProvider {
154
155
  return data;
155
156
  }
156
157
  async *getSubscription(subscriptionId, abortSignal) {
157
- const url = `${this.serverUrl}/v1/script/subscription/${subscriptionId}`;
158
- while (!abortSignal.aborted) {
158
+ const url = `${this.serverUrl}/v1/indexer/script/subscription/${subscriptionId}`;
159
+ while (!abortSignal?.aborted) {
159
160
  try {
160
- const res = await fetch(url, {
161
- headers: {
162
- Accept: "application/json",
163
- },
164
- });
165
- if (!res.ok) {
166
- throw new Error(`Unexpected status ${res.status} when subscribing to address updates`);
167
- }
168
- if (!res.body) {
169
- throw new Error("Response body is null");
170
- }
171
- const reader = res.body.getReader();
172
- const decoder = new TextDecoder();
173
- let buffer = "";
174
- while (!abortSignal.aborted) {
175
- const { done, value } = await reader.read();
176
- if (done) {
177
- break;
178
- }
179
- buffer += decoder.decode(value, { stream: true });
180
- const lines = buffer.split("\n");
181
- for (let i = 0; i < lines.length - 1; i++) {
182
- const line = lines[i].trim();
183
- if (!line)
184
- continue;
185
- const data = JSON.parse(line);
186
- if ("result" in data) {
187
- yield {
188
- txid: data.result.txid,
189
- scripts: data.result.scripts || [],
190
- newVtxos: (data.result.newVtxos || []).map(convertVtxo),
191
- spentVtxos: (data.result.spentVtxos || []).map(convertVtxo),
192
- tx: data.result.tx,
193
- checkpointTxs: data.result.checkpointTxs,
194
- };
161
+ const eventSource = new EventSource(url);
162
+ // Set up abort handling
163
+ const abortHandler = () => {
164
+ eventSource.close();
165
+ };
166
+ abortSignal?.addEventListener("abort", abortHandler);
167
+ try {
168
+ for await (const event of (0, utils_1.eventSourceIterator)(eventSource)) {
169
+ if (abortSignal?.aborted)
170
+ break;
171
+ try {
172
+ const data = JSON.parse(event.data);
173
+ if (data.event) {
174
+ yield {
175
+ txid: data.event.txid,
176
+ scripts: data.event.scripts || [],
177
+ newVtxos: (data.event.newVtxos || []).map(convertVtxo),
178
+ spentVtxos: (data.event.spentVtxos || []).map(convertVtxo),
179
+ tx: data.event.tx,
180
+ checkpointTxs: data.event.checkpointTxs,
181
+ };
182
+ }
183
+ }
184
+ catch (err) {
185
+ console.error("Failed to parse subscription event:", err);
186
+ throw err;
195
187
  }
196
188
  }
197
- buffer = lines[lines.length - 1];
189
+ }
190
+ finally {
191
+ abortSignal?.removeEventListener("abort", abortHandler);
192
+ eventSource.close();
198
193
  }
199
194
  }
200
195
  catch (error) {
@@ -202,7 +197,6 @@ class RestIndexerProvider {
202
197
  break;
203
198
  }
204
199
  // ignore timeout errors, they're expected when the server is not sending anything for 5 min
205
- // these timeouts are set by builtin fetch function
206
200
  if ((0, ark_1.isFetchTimeoutError)(error)) {
207
201
  console.debug("Timeout error ignored");
208
202
  continue;
@@ -213,7 +207,7 @@ class RestIndexerProvider {
213
207
  }
214
208
  }
215
209
  async getVirtualTxs(txids, opts) {
216
- let url = `${this.serverUrl}/v1/virtualTx/${txids.join(",")}`;
210
+ let url = `${this.serverUrl}/v1/indexer/virtualTx/${txids.join(",")}`;
217
211
  const params = new URLSearchParams();
218
212
  if (opts) {
219
213
  if (opts.pageIndex !== undefined)
@@ -235,7 +229,7 @@ class RestIndexerProvider {
235
229
  return data;
236
230
  }
237
231
  async getVtxoChain(vtxoOutpoint, opts) {
238
- let url = `${this.serverUrl}/v1/vtxo/${vtxoOutpoint.txid}/${vtxoOutpoint.vout}/chain`;
232
+ let url = `${this.serverUrl}/v1/indexer/vtxo/${vtxoOutpoint.txid}/${vtxoOutpoint.vout}/chain`;
239
233
  const params = new URLSearchParams();
240
234
  if (opts) {
241
235
  if (opts.pageIndex !== undefined)
@@ -264,7 +258,7 @@ class RestIndexerProvider {
264
258
  if (!opts?.scripts && !opts?.outpoints) {
265
259
  throw new Error("Either scripts or outpoints must be provided");
266
260
  }
267
- let url = `${this.serverUrl}/v1/vtxos`;
261
+ let url = `${this.serverUrl}/v1/indexer/vtxos`;
268
262
  const params = new URLSearchParams();
269
263
  // Handle scripts with multi collection format
270
264
  if (opts?.scripts && opts.scripts.length > 0) {
@@ -307,7 +301,7 @@ class RestIndexerProvider {
307
301
  };
308
302
  }
309
303
  async subscribeForScripts(scripts, subscriptionId) {
310
- const url = `${this.serverUrl}/v1/script/subscribe`;
304
+ const url = `${this.serverUrl}/v1/indexer/script/subscribe`;
311
305
  const res = await fetch(url, {
312
306
  headers: {
313
307
  "Content-Type": "application/json",
@@ -325,7 +319,7 @@ class RestIndexerProvider {
325
319
  return data.subscriptionId;
326
320
  }
327
321
  async unsubscribeForScripts(subscriptionId, scripts) {
328
- const url = `${this.serverUrl}/v1/script/unsubscribe`;
322
+ const url = `${this.serverUrl}/v1/indexer/script/unsubscribe`;
329
323
  const res = await fetch(url, {
330
324
  headers: {
331
325
  "Content-Type": "application/json",
@@ -442,7 +436,7 @@ var Response;
442
436
  return (typeof data === "object" &&
443
437
  isOutpoint(data.outpoint) &&
444
438
  typeof data.createdAt === "string" &&
445
- typeof data.expiresAt === "string" &&
439
+ (data.expiresAt === null || typeof data.expiresAt === "string") &&
446
440
  typeof data.amount === "string" &&
447
441
  typeof data.script === "string" &&
448
442
  typeof data.isPreconfirmed === "boolean" &&