@arkade-os/sdk 0.3.0-alpha.8 → 0.3.1-alpha.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.
Files changed (77) hide show
  1. package/README.md +64 -14
  2. package/dist/cjs/arknote/index.js +3 -3
  3. package/dist/cjs/forfeit.js +5 -2
  4. package/dist/cjs/identity/singleKey.js +5 -4
  5. package/dist/cjs/index.js +6 -3
  6. package/dist/cjs/{bip322 → intent}/index.js +37 -55
  7. package/dist/cjs/providers/ark.js +62 -23
  8. package/dist/cjs/providers/expoArk.js +15 -170
  9. package/dist/cjs/providers/expoIndexer.js +22 -111
  10. package/dist/cjs/providers/utils.js +122 -0
  11. package/dist/cjs/script/base.js +1 -2
  12. package/dist/cjs/script/tapscript.js +20 -21
  13. package/dist/cjs/script/vhtlc.js +2 -2
  14. package/dist/cjs/tree/signingSession.js +7 -8
  15. package/dist/cjs/tree/txTree.js +3 -4
  16. package/dist/cjs/tree/validation.js +2 -3
  17. package/dist/cjs/utils/arkTransaction.js +104 -12
  18. package/dist/cjs/utils/unknownFields.js +5 -5
  19. package/dist/cjs/wallet/onchain.js +4 -5
  20. package/dist/cjs/wallet/serviceWorker/utils.js +2 -0
  21. package/dist/cjs/wallet/serviceWorker/wallet.js +4 -8
  22. package/dist/cjs/wallet/serviceWorker/worker.js +23 -18
  23. package/dist/cjs/wallet/unroll.js +6 -7
  24. package/dist/cjs/wallet/vtxo-manager.js +381 -0
  25. package/dist/cjs/wallet/wallet.js +63 -94
  26. package/dist/esm/arknote/index.js +2 -2
  27. package/dist/esm/forfeit.js +4 -1
  28. package/dist/esm/identity/singleKey.js +7 -6
  29. package/dist/esm/index.js +7 -6
  30. package/dist/esm/{bip322 → intent}/index.js +31 -48
  31. package/dist/esm/providers/ark.js +62 -23
  32. package/dist/esm/providers/expoArk.js +15 -137
  33. package/dist/esm/providers/expoIndexer.js +22 -78
  34. package/dist/esm/providers/utils.js +87 -0
  35. package/dist/esm/script/base.js +1 -2
  36. package/dist/esm/script/tapscript.js +1 -2
  37. package/dist/esm/script/vhtlc.js +1 -1
  38. package/dist/esm/tree/signingSession.js +8 -9
  39. package/dist/esm/tree/txTree.js +3 -4
  40. package/dist/esm/tree/validation.js +2 -3
  41. package/dist/esm/utils/arkTransaction.js +95 -4
  42. package/dist/esm/utils/unknownFields.js +1 -1
  43. package/dist/esm/wallet/onchain.js +1 -2
  44. package/dist/esm/wallet/serviceWorker/utils.js +1 -0
  45. package/dist/esm/wallet/serviceWorker/wallet.js +5 -9
  46. package/dist/esm/wallet/serviceWorker/worker.js +23 -18
  47. package/dist/esm/wallet/unroll.js +2 -3
  48. package/dist/esm/wallet/vtxo-manager.js +372 -0
  49. package/dist/esm/wallet/wallet.js +56 -87
  50. package/dist/types/arknote/index.d.ts +1 -1
  51. package/dist/types/forfeit.d.ts +2 -2
  52. package/dist/types/identity/index.d.ts +1 -1
  53. package/dist/types/identity/singleKey.d.ts +1 -1
  54. package/dist/types/index.d.ts +6 -5
  55. package/dist/types/intent/index.d.ts +41 -0
  56. package/dist/types/providers/ark.d.ts +55 -21
  57. package/dist/types/providers/expoIndexer.d.ts +2 -10
  58. package/dist/types/providers/indexer.d.ts +1 -9
  59. package/dist/types/providers/utils.d.ts +18 -0
  60. package/dist/types/script/base.d.ts +3 -2
  61. package/dist/types/tree/signingSession.d.ts +10 -10
  62. package/dist/types/utils/anchor.d.ts +2 -2
  63. package/dist/types/utils/arkTransaction.d.ts +13 -3
  64. package/dist/types/utils/unknownFields.d.ts +2 -2
  65. package/dist/types/wallet/index.d.ts +6 -4
  66. package/dist/types/wallet/onchain.d.ts +1 -1
  67. package/dist/types/wallet/serviceWorker/utils.d.ts +1 -0
  68. package/dist/types/wallet/serviceWorker/wallet.d.ts +2 -2
  69. package/dist/types/wallet/serviceWorker/worker.d.ts +3 -1
  70. package/dist/types/wallet/unroll.d.ts +1 -1
  71. package/dist/types/wallet/vtxo-manager.d.ts +207 -0
  72. package/dist/types/wallet/wallet.d.ts +7 -3
  73. package/package.json +1 -2
  74. package/dist/cjs/bip322/errors.js +0 -13
  75. package/dist/esm/bip322/errors.js +0 -9
  76. package/dist/types/bip322/errors.d.ts +0 -6
  77. package/dist/types/bip322/index.d.ts +0 -57
package/README.md CHANGED
@@ -108,26 +108,76 @@ const settleTxid = await wallet.settle({
108
108
  })
109
109
  ```
110
110
 
111
+ ### VTXO Management (Renewal & Recovery)
112
+
113
+ VTXOs have an expiration time (batch expiry). The SDK provides the `VtxoManager` class to handle both:
114
+
115
+ - **Renewal**: Renew VTXOs before they expire to maintain unilateral control of the funds.
116
+ - **Recovery**: Reclaim swept or expired VTXOs back to the wallet in case renewal window was missed.
117
+
118
+ ```typescript
119
+ import { VtxoManager } from '@arkade-os/sdk'
120
+
121
+ // Create manager with optional renewal configuration
122
+ const manager = new VtxoManager(wallet, {
123
+ enabled: true, // Enable expiration monitoring
124
+ thresholdPercentage: 10 // Alert when 10% of lifetime remains (default)
125
+ })
126
+ ```
127
+
128
+ #### Renewal: Prevent Expiration
129
+
130
+ Renew VTXOs before they expire to keep your liquidity accessible. This settles all VTXOs (including recoverable ones) back to your wallet with a fresh expiration time.
131
+
132
+ ```typescript
133
+ // Check which VTXOs are expiring soon
134
+ const expiringVtxos = await manager.getExpiringVtxos()
135
+ if (expiringVtxos.length > 0) {
136
+ console.log(`${expiringVtxos.length} VTXOs expiring soon`)
137
+
138
+ expiringVtxos.forEach(vtxo => {
139
+ const timeLeft = vtxo.virtualStatus.batchExpiry! - Date.now()
140
+ const hoursLeft = Math.floor(timeLeft / (1000 * 60 * 60))
141
+ console.log(`VTXO ${vtxo.txid} expires in ${hoursLeft} hours`)
142
+ })
143
+
144
+ // Renew all VTXOs to prevent expiration
145
+ const txid = await manager.renewVtxos()
146
+ console.log('Renewed:', txid)
147
+ }
148
+
149
+ // Override threshold percentage (e.g., renew when 5% of time remains)
150
+ const urgentlyExpiring = await manager.getExpiringVtxos(5)
151
+ ```
152
+
153
+
154
+ #### Recovery: Reclaim Swept VTXOs
155
+
156
+ Recover VTXOs that have been swept by the server or consolidate small amounts (subdust).
157
+
158
+ ```typescript
159
+ // Check what's recoverable
160
+ const balance = await manager.getRecoverableBalance()
161
+ console.log(`Recoverable: ${balance.recoverable} sats`)
162
+ console.log(`Subdust: ${balance.subdust} sats`)
163
+ console.log(`Subdust included: ${balance.includesSubdust}`)
164
+ console.log(`VTXO count: ${balance.vtxoCount}`)
165
+
166
+ if (balance.recoverable > 0n) {
167
+ // Recover swept VTXOs and preconfirmed subdust
168
+ const txid = await manager.recoverVtxos((event) => {
169
+ console.log('Settlement event:', event.type)
170
+ })
171
+ console.log('Recovered:', txid)
172
+ }
173
+ ```
174
+
111
175
 
112
176
  ### Transaction History
113
177
 
114
178
  ```typescript
115
179
  // Get transaction history
116
180
  const history = await wallet.getTransactionHistory()
117
- console.log('History:', history)
118
-
119
- // Example history entry:
120
- {
121
- key: {
122
- boardingTxid: '...', // for boarding transactions
123
- commitmentTxid: '...', // for commitment transactions
124
- redeemTxid: '...' // for regular transactions
125
- },
126
- type: TxType.TxReceived, // or TxType.TxSent
127
- amount: 50000,
128
- settled: true,
129
- createdAt: 1234567890
130
- }
131
181
  ```
132
182
 
133
183
  ### Offboarding
@@ -2,9 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ArkNote = void 0;
4
4
  const base_1 = require("@scure/base");
5
- const base_2 = require("../script/base");
6
5
  const utils_js_1 = require("@scure/btc-signer/utils.js");
7
- const script_js_1 = require("@scure/btc-signer/script.js");
6
+ const btc_signer_1 = require("@scure/btc-signer");
7
+ const base_2 = require("../script/base");
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
@@ -85,5 +85,5 @@ function readUInt32BE(array, offset) {
85
85
  return view.getUint32(0, false);
86
86
  }
87
87
  function noteTapscript(preimageHash) {
88
- return script_js_1.Script.encode(["SHA256", preimageHash, "EQUAL"]);
88
+ return btc_signer_1.Script.encode(["SHA256", preimageHash, "EQUAL"]);
89
89
  }
@@ -1,12 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildForfeitTx = buildForfeitTx;
4
- const transaction_js_1 = require("@scure/btc-signer/transaction.js");
4
+ const btc_signer_1 = require("@scure/btc-signer");
5
5
  const anchor_1 = require("./utils/anchor");
6
6
  function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
7
- const tx = new transaction_js_1.Transaction({
7
+ const tx = new btc_signer_1.Transaction({
8
8
  version: 3,
9
9
  lockTime: txLocktime,
10
+ allowUnknownOutputs: true,
11
+ allowUnknown: true,
12
+ allowUnknownInputs: true,
10
13
  });
11
14
  let amount = 0n;
12
15
  for (const input of inputs) {
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SingleKey = void 0;
4
4
  const utils_js_1 = require("@scure/btc-signer/utils.js");
5
- const base_1 = require("@scure/base");
6
5
  const transaction_js_1 = require("@scure/btc-signer/transaction.js");
6
+ const base_1 = require("@scure/base");
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);
@@ -82,9 +82,10 @@ class SingleKey {
82
82
  signerSession() {
83
83
  return signingSession_1.TreeSignerSession.random();
84
84
  }
85
- async signMessage(message) {
86
- const msgBytes = new TextEncoder().encode(message);
87
- return secp256k1_1.schnorr.sign((0, utils_js_1.sha256)(msgBytes), this.key);
85
+ async signMessage(message, signatureType = "schnorr") {
86
+ if (signatureType === "ecdsa")
87
+ return (0, secp256k1_1.sign)(message, this.key, { prehash: false });
88
+ return secp256k1_1.schnorr.sign(message, this.key);
88
89
  }
89
90
  }
90
91
  exports.SingleKey = SingleKey;
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.networks = exports.ArkNote = exports.hasBoardingTxExpired = 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;
3
+ exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.Intent = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.networks = exports.ArkNote = exports.hasBoardingTxExpired = exports.waitForIncomingFunds = exports.verifyTapscriptSignatures = 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.VtxoManager = exports.Ramps = exports.OnchainWallet = exports.SingleKey = exports.Wallet = void 0;
4
4
  const transaction_js_1 = require("@scure/btc-signer/transaction.js");
5
5
  Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_js_1.Transaction; } });
6
6
  const singleKey_1 = require("./identity/singleKey");
@@ -22,6 +22,8 @@ const txTree_1 = require("./tree/txTree");
22
22
  Object.defineProperty(exports, "TxTree", { enumerable: true, get: function () { return txTree_1.TxTree; } });
23
23
  const ramps_1 = require("./wallet/ramps");
24
24
  Object.defineProperty(exports, "Ramps", { enumerable: true, get: function () { return ramps_1.Ramps; } });
25
+ const vtxo_manager_1 = require("./wallet/vtxo-manager");
26
+ Object.defineProperty(exports, "VtxoManager", { enumerable: true, get: function () { return vtxo_manager_1.VtxoManager; } });
25
27
  const wallet_3 = require("./wallet/serviceWorker/wallet");
26
28
  Object.defineProperty(exports, "ServiceWorkerWallet", { enumerable: true, get: function () { return wallet_3.ServiceWorkerWallet; } });
27
29
  const onchain_1 = require("./wallet/onchain");
@@ -50,6 +52,7 @@ Object.defineProperty(exports, "MultisigTapscript", { enumerable: true, get: fun
50
52
  const arkTransaction_1 = require("./utils/arkTransaction");
51
53
  Object.defineProperty(exports, "hasBoardingTxExpired", { enumerable: true, get: function () { return arkTransaction_1.hasBoardingTxExpired; } });
52
54
  Object.defineProperty(exports, "buildOffchainTx", { enumerable: true, get: function () { return arkTransaction_1.buildOffchainTx; } });
55
+ Object.defineProperty(exports, "verifyTapscriptSignatures", { enumerable: true, get: function () { return arkTransaction_1.verifyTapscriptSignatures; } });
53
56
  const unknownFields_1 = require("./utils/unknownFields");
54
57
  Object.defineProperty(exports, "VtxoTaprootTree", { enumerable: true, get: function () { return unknownFields_1.VtxoTaprootTree; } });
55
58
  Object.defineProperty(exports, "ConditionWitness", { enumerable: true, get: function () { return unknownFields_1.ConditionWitness; } });
@@ -59,8 +62,8 @@ Object.defineProperty(exports, "ArkPsbtFieldKey", { enumerable: true, get: funct
59
62
  Object.defineProperty(exports, "ArkPsbtFieldKeyType", { enumerable: true, get: function () { return unknownFields_1.ArkPsbtFieldKeyType; } });
60
63
  Object.defineProperty(exports, "CosignerPublicKey", { enumerable: true, get: function () { return unknownFields_1.CosignerPublicKey; } });
61
64
  Object.defineProperty(exports, "VtxoTreeExpiry", { enumerable: true, get: function () { return unknownFields_1.VtxoTreeExpiry; } });
62
- const bip322_1 = require("./bip322");
63
- Object.defineProperty(exports, "BIP322", { enumerable: true, get: function () { return bip322_1.BIP322; } });
65
+ const intent_1 = require("./intent");
66
+ Object.defineProperty(exports, "Intent", { enumerable: true, get: function () { return intent_1.Intent; } });
64
67
  const arknote_1 = require("./arknote");
65
68
  Object.defineProperty(exports, "ArkNote", { enumerable: true, get: function () { return arknote_1.ArkNote; } });
66
69
  const networks_1 = require("./networks");
@@ -1,26 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BIP322 = void 0;
4
- exports.craftToSpendTx = craftToSpendTx;
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");
8
- const errors_1 = require("./errors");
3
+ exports.Intent = void 0;
4
+ const btc_signer_1 = require("@scure/btc-signer");
9
5
  const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
10
- const base_1 = require("@scure/base");
11
6
  /**
12
- * BIP-322 signature implementation for Bitcoin message signing.
7
+ * Intent proof implementation for Bitcoin message signing.
13
8
  *
14
- * BIP-322 defines a standard for signing Bitcoin messages as well as proving
9
+ * Intent proof defines a standard for signing Bitcoin messages as well as proving
15
10
  * ownership of coins. This namespace provides utilities for creating and
16
- * validating BIP-322.
11
+ * validating Intent proof.
17
12
  *
13
+ * it is greatly inspired by BIP322.
18
14
  * @see https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
19
15
  *
20
16
  * @example
21
17
  * ```typescript
22
- * // Create a BIP-322 proof
23
- * const proof = BIP322.create(
18
+ * // Create a Intent proof
19
+ * const proof = Intent.create(
24
20
  * "Hello Bitcoin!",
25
21
  * [input],
26
22
  * [output]
@@ -29,65 +25,46 @@ const base_1 = require("@scure/base");
29
25
  * // Sign the proof
30
26
  * const signedProof = await identity.sign(proof);
31
27
  *
32
- * // Extract the signature
33
- * const signature = BIP322.signature(signedProof);
34
- * ```
35
28
  */
36
- var BIP322;
37
- (function (BIP322) {
29
+ var Intent;
30
+ (function (Intent) {
38
31
  /**
39
- * Creates a new BIP-322 "full" proof of funds unsigned transaction.
32
+ * Creates a new Intent proof unsigned transaction.
40
33
  *
41
34
  * This function constructs a special transaction that can be signed to prove
42
35
  * ownership of VTXOs and UTXOs. The proof includes the message to be
43
36
  * signed and the inputs/outputs that demonstrate ownership.
44
37
  *
45
- * @param message - The BIP-322 message to be signed
38
+ * @param message - The Intent message to be signed
46
39
  * @param inputs - Array of transaction inputs to prove ownership of
47
40
  * @param outputs - Optional array of transaction outputs
48
- * @returns An unsigned BIP-322 proof transaction
41
+ * @returns An unsigned Intent proof transaction
49
42
  */
50
43
  function create(message, inputs, outputs = []) {
51
44
  if (inputs.length == 0)
52
- throw errors_1.ErrMissingInputs;
45
+ throw new Error("intent proof requires at least one input");
53
46
  if (!validateInputs(inputs))
54
- throw errors_1.ErrMissingData;
47
+ throw new Error("invalid inputs");
55
48
  if (!validateOutputs(outputs))
56
- throw errors_1.ErrMissingData;
49
+ throw new Error("invalid outputs");
57
50
  // create the initial transaction to spend
58
51
  const toSpend = craftToSpendTx(message, inputs[0].witnessUtxo.script);
59
52
  // create the transaction to sign
60
53
  return craftToSignTx(toSpend, inputs, outputs);
61
54
  }
62
- BIP322.create = create;
63
- /**
64
- * Finalizes and extracts the FullProof transaction into a BIP-322 signature.
65
- *
66
- * This function takes a signed proof transaction and converts it into a
67
- * base64-encoded signature string. If the proof's inputs have special
68
- * spending conditions, a custom finalizer can be provided.
69
- *
70
- * @param signedProof - The signed BIP-322 proof transaction
71
- * @param finalizer - Optional custom finalizer function
72
- * @returns Base64-encoded BIP-322 signature
73
- */
74
- function signature(signedProof, finalizer = (tx) => tx.finalize()) {
75
- finalizer(signedProof);
76
- return base_1.base64.encode(signedProof.extract());
77
- }
78
- BIP322.signature = signature;
79
- })(BIP322 || (exports.BIP322 = BIP322 = {}));
80
- const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([script_js_1.OP.RETURN]);
55
+ Intent.create = create;
56
+ })(Intent || (exports.Intent = Intent = {}));
57
+ const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([btc_signer_1.OP.RETURN]);
81
58
  const ZERO_32 = new Uint8Array(32).fill(0);
82
59
  const MAX_INDEX = 0xffffffff;
83
- const TAG_BIP322 = "BIP0322-signed-message";
60
+ const TAG_INTENT_PROOF = "ark-intent-proof-message";
84
61
  function validateInput(input) {
85
62
  if (input.index === undefined)
86
- throw errors_1.ErrMissingData;
63
+ throw new Error("intent proof input requires index");
87
64
  if (input.txid === undefined)
88
- throw errors_1.ErrMissingData;
65
+ throw new Error("intent proof input requires txid");
89
66
  if (input.witnessUtxo === undefined)
90
- throw errors_1.ErrMissingWitnessUtxo;
67
+ throw new Error("intent proof input requires witness utxo");
91
68
  return true;
92
69
  }
93
70
  function validateInputs(inputs) {
@@ -96,9 +73,9 @@ function validateInputs(inputs) {
96
73
  }
97
74
  function validateOutput(output) {
98
75
  if (output.amount === undefined)
99
- throw errors_1.ErrMissingData;
76
+ throw new Error("intent proof output requires amount");
100
77
  if (output.script === undefined)
101
- throw errors_1.ErrMissingData;
78
+ throw new Error("intent proof output requires script");
102
79
  return true;
103
80
  }
104
81
  function validateOutputs(outputs) {
@@ -108,7 +85,7 @@ function validateOutputs(outputs) {
108
85
  // craftToSpendTx creates the initial transaction that will be spent in the proof
109
86
  function craftToSpendTx(message, pkScript) {
110
87
  const messageHash = hashMessage(message);
111
- const tx = new transaction_js_1.Transaction({
88
+ const tx = new btc_signer_1.Transaction({
112
89
  version: 0,
113
90
  allowUnknownOutputs: true,
114
91
  allowUnknown: true,
@@ -126,14 +103,14 @@ function craftToSpendTx(message, pkScript) {
126
103
  script: pkScript,
127
104
  });
128
105
  tx.updateInput(0, {
129
- finalScriptSig: script_js_2.Script.encode(["OP_0", messageHash]),
106
+ finalScriptSig: btc_signer_1.Script.encode(["OP_0", messageHash]),
130
107
  });
131
108
  return tx;
132
109
  }
133
110
  // craftToSignTx creates the transaction that will be signed for the proof
134
111
  function craftToSignTx(toSpend, inputs, outputs) {
135
112
  const firstInput = inputs[0];
136
- const tx = new transaction_js_1.Transaction({
113
+ const tx = new btc_signer_1.Transaction({
137
114
  version: 2,
138
115
  allowUnknownOutputs: outputs.length === 0,
139
116
  allowUnknown: true,
@@ -149,14 +126,19 @@ function craftToSignTx(toSpend, inputs, outputs) {
149
126
  script: firstInput.witnessUtxo.script,
150
127
  amount: 0n,
151
128
  },
152
- sighashType: transaction_js_1.SigHash.ALL,
129
+ sighashType: btc_signer_1.SigHash.ALL,
153
130
  });
154
131
  // add other inputs
155
- for (const input of inputs) {
132
+ for (const [i, input] of inputs.entries()) {
156
133
  tx.addInput({
157
134
  ...input,
158
- sighashType: transaction_js_1.SigHash.ALL,
135
+ sighashType: btc_signer_1.SigHash.ALL,
159
136
  });
137
+ if (input.unknown?.length) {
138
+ tx.updateInput(i + 1, {
139
+ unknown: input.unknown,
140
+ });
141
+ }
160
142
  }
161
143
  // add the special OP_RETURN output if no outputs are provided
162
144
  if (outputs.length === 0) {
@@ -176,5 +158,5 @@ function craftToSignTx(toSpend, inputs, outputs) {
176
158
  return tx;
177
159
  }
178
160
  function hashMessage(message) {
179
- return secp256k1_js_1.schnorr.utils.taggedHash(TAG_BIP322, new TextEncoder().encode(message));
161
+ return secp256k1_js_1.schnorr.utils.taggedHash(TAG_INTENT_PROOF, new TextEncoder().encode(message));
180
162
  }
@@ -36,25 +36,36 @@ class RestArkProvider {
36
36
  }
37
37
  const fromServer = await response.json();
38
38
  return {
39
- ...fromServer,
40
- vtxoTreeExpiry: BigInt(fromServer.vtxoTreeExpiry ?? 0),
41
- unilateralExitDelay: BigInt(fromServer.unilateralExitDelay ?? 0),
42
- roundInterval: BigInt(fromServer.roundInterval ?? 0),
43
- dust: BigInt(fromServer.dust ?? 0),
44
- utxoMinAmount: BigInt(fromServer.utxoMinAmount ?? 0),
45
- utxoMaxAmount: BigInt(fromServer.utxoMaxAmount ?? -1),
46
- vtxoMinAmount: BigInt(fromServer.vtxoMinAmount ?? 0),
47
- vtxoMaxAmount: BigInt(fromServer.vtxoMaxAmount ?? -1),
48
39
  boardingExitDelay: BigInt(fromServer.boardingExitDelay ?? 0),
49
- checkpointExitClosure: fromServer.checkpointTapscript ?? "",
50
- marketHour: "marketHour" in fromServer && fromServer.marketHour != null
40
+ checkpointTapscript: fromServer.checkpointTapscript ?? "",
41
+ deprecatedSigners: fromServer.deprecatedSigners?.map((signer) => ({
42
+ cutoffDate: BigInt(signer.cutoffDate ?? 0),
43
+ pubkey: signer.pubkey ?? "",
44
+ })) ?? [],
45
+ digest: fromServer.digest ?? "",
46
+ dust: BigInt(fromServer.dust ?? 0),
47
+ fees: fromServer.fees,
48
+ forfeitAddress: fromServer.forfeitAddress ?? "",
49
+ forfeitPubkey: fromServer.forfeitPubkey ?? "",
50
+ network: fromServer.network ?? "",
51
+ scheduledSession: "scheduledSession" in fromServer &&
52
+ fromServer.scheduledSession != null
51
53
  ? {
52
- nextStartTime: BigInt(fromServer.marketHour.nextStartTime ?? 0),
53
- nextEndTime: BigInt(fromServer.marketHour.nextEndTime ?? 0),
54
- period: BigInt(fromServer.marketHour.period ?? 0),
55
- roundInterval: BigInt(fromServer.marketHour.roundInterval ?? 0),
54
+ duration: BigInt(fromServer.scheduledSession.duration ?? 0),
55
+ nextStartTime: BigInt(fromServer.scheduledSession.nextStartTime ?? 0),
56
+ nextEndTime: BigInt(fromServer.scheduledSession.nextEndTime ?? 0),
57
+ period: BigInt(fromServer.scheduledSession.period ?? 0),
56
58
  }
57
59
  : undefined,
60
+ serviceStatus: fromServer.serviceStatus ?? {},
61
+ sessionDuration: BigInt(fromServer.sessionDuration ?? 0),
62
+ signerPubkey: fromServer.signerPubkey ?? "",
63
+ unilateralExitDelay: BigInt(fromServer.unilateralExitDelay ?? 0),
64
+ utxoMaxAmount: BigInt(fromServer.utxoMaxAmount ?? -1),
65
+ utxoMinAmount: BigInt(fromServer.utxoMinAmount ?? 0),
66
+ version: fromServer.version ?? "",
67
+ vtxoMaxAmount: BigInt(fromServer.vtxoMaxAmount ?? -1),
68
+ vtxoMinAmount: BigInt(fromServer.vtxoMinAmount ?? 0),
58
69
  };
59
70
  }
60
71
  async submitTx(signedArkTx, checkpointTxs) {
@@ -65,8 +76,8 @@ class RestArkProvider {
65
76
  "Content-Type": "application/json",
66
77
  },
67
78
  body: JSON.stringify({
68
- signedArkTx: signedArkTx,
69
- checkpointTxs: checkpointTxs,
79
+ signedArkTx,
80
+ checkpointTxs,
70
81
  }),
71
82
  });
72
83
  if (!response.ok) {
@@ -115,7 +126,7 @@ class RestArkProvider {
115
126
  },
116
127
  body: JSON.stringify({
117
128
  intent: {
118
- signature: intent.signature,
129
+ proof: intent.proof,
119
130
  message: intent.message,
120
131
  },
121
132
  }),
@@ -136,7 +147,7 @@ class RestArkProvider {
136
147
  },
137
148
  body: JSON.stringify({
138
149
  proof: {
139
- signature: intent.signature,
150
+ proof: intent.proof,
140
151
  message: intent.message,
141
152
  },
142
153
  }),
@@ -309,6 +320,31 @@ class RestArkProvider {
309
320
  }
310
321
  }
311
322
  }
323
+ async getPendingTxs(intent) {
324
+ const url = `${this.serverUrl}/v1/tx/pending`;
325
+ const response = await fetch(url, {
326
+ method: "POST",
327
+ headers: {
328
+ "Content-Type": "application/json",
329
+ },
330
+ body: JSON.stringify({ intent }),
331
+ });
332
+ if (!response.ok) {
333
+ const errorText = await response.text();
334
+ try {
335
+ const grpcError = JSON.parse(errorText);
336
+ // gRPC errors usually have a message and code field
337
+ throw new Error(`Failed to get pending transactions: ${grpcError.message || grpcError.error || errorText}`);
338
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
339
+ }
340
+ catch (_) {
341
+ // If JSON parse fails, use the raw error text
342
+ throw new Error(`Failed to get pending transactions: ${errorText}`);
343
+ }
344
+ }
345
+ const data = await response.json();
346
+ return data.pendingTxs;
347
+ }
312
348
  parseSettlementEvent(data) {
313
349
  // Check for BatchStarted event
314
350
  if (data.batchStarted) {
@@ -387,6 +423,10 @@ class RestArkProvider {
387
423
  signature: data.treeSignature.signature,
388
424
  };
389
425
  }
426
+ // TODO: Handle TreeNoncesEvent when implemented server-side
427
+ if (data.treeNonces) {
428
+ return null;
429
+ }
390
430
  // Skip heartbeat events
391
431
  if (data.heartbeat) {
392
432
  return null;
@@ -431,17 +471,16 @@ function encodeMusig2Nonces(nonces) {
431
471
  for (const [txid, nonce] of nonces) {
432
472
  noncesObject[txid] = base_1.hex.encode(nonce.pubNonce);
433
473
  }
434
- return JSON.stringify(noncesObject);
474
+ return noncesObject;
435
475
  }
436
476
  function encodeMusig2Signatures(signatures) {
437
477
  const sigObject = {};
438
478
  for (const [txid, sig] of signatures) {
439
479
  sigObject[txid] = base_1.hex.encode(sig.encode());
440
480
  }
441
- return JSON.stringify(sigObject);
481
+ return sigObject;
442
482
  }
443
- function decodeMusig2Nonces(str) {
444
- const noncesObject = JSON.parse(str);
483
+ function decodeMusig2Nonces(noncesObject) {
445
484
  return new Map(Object.entries(noncesObject).map(([txid, nonce]) => {
446
485
  if (typeof nonce !== "string") {
447
486
  throw new Error("invalid nonce");