@arkade-os/sdk 0.3.13 → 0.4.0-next.1

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 (270) hide show
  1. package/README.md +586 -54
  2. package/dist/cjs/asset/assetGroup.js +141 -0
  3. package/dist/cjs/asset/assetId.js +88 -0
  4. package/dist/cjs/asset/assetInput.js +204 -0
  5. package/dist/cjs/asset/assetOutput.js +159 -0
  6. package/dist/cjs/asset/assetRef.js +82 -0
  7. package/dist/cjs/asset/index.js +24 -0
  8. package/dist/cjs/asset/metadata.js +172 -0
  9. package/dist/cjs/asset/packet.js +164 -0
  10. package/dist/cjs/asset/types.js +25 -0
  11. package/dist/cjs/asset/utils.js +105 -0
  12. package/dist/cjs/bip322/index.js +270 -0
  13. package/dist/cjs/contracts/arkcontract.js +148 -0
  14. package/dist/cjs/contracts/contractManager.js +436 -0
  15. package/dist/cjs/contracts/contractWatcher.js +567 -0
  16. package/dist/cjs/contracts/handlers/default.js +85 -0
  17. package/dist/cjs/contracts/handlers/delegate.js +89 -0
  18. package/dist/cjs/contracts/handlers/helpers.js +105 -0
  19. package/dist/cjs/contracts/handlers/index.js +19 -0
  20. package/dist/cjs/contracts/handlers/registry.js +89 -0
  21. package/dist/cjs/contracts/handlers/vhtlc.js +193 -0
  22. package/dist/cjs/contracts/index.js +41 -0
  23. package/dist/cjs/contracts/types.js +2 -0
  24. package/dist/cjs/forfeit.js +12 -8
  25. package/dist/cjs/identity/index.js +1 -0
  26. package/dist/cjs/identity/seedIdentity.js +255 -0
  27. package/dist/cjs/index.js +72 -14
  28. package/dist/cjs/intent/index.js +47 -11
  29. package/dist/cjs/providers/ark.js +7 -0
  30. package/dist/cjs/providers/delegator.js +66 -0
  31. package/dist/cjs/providers/expoIndexer.js +5 -0
  32. package/dist/cjs/providers/indexer.js +68 -1
  33. package/dist/cjs/providers/utils.js +1 -0
  34. package/dist/cjs/repositories/contractRepository.js +0 -103
  35. package/dist/cjs/repositories/inMemory/contractRepository.js +55 -0
  36. package/dist/cjs/repositories/inMemory/walletRepository.js +80 -0
  37. package/dist/cjs/repositories/index.js +16 -0
  38. package/dist/cjs/repositories/indexedDB/contractRepository.js +187 -0
  39. package/dist/cjs/repositories/indexedDB/db.js +19 -0
  40. package/dist/cjs/repositories/indexedDB/manager.js +97 -0
  41. package/dist/cjs/repositories/indexedDB/schema.js +159 -0
  42. package/dist/cjs/repositories/indexedDB/walletRepository.js +338 -0
  43. package/dist/cjs/repositories/indexedDB/websqlAdapter.js +144 -0
  44. package/dist/cjs/repositories/migrations/contractRepositoryImpl.js +127 -0
  45. package/dist/cjs/repositories/migrations/fromStorageAdapter.js +66 -0
  46. package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +180 -0
  47. package/dist/cjs/repositories/realm/contractRepository.js +120 -0
  48. package/dist/cjs/repositories/realm/index.js +9 -0
  49. package/dist/cjs/repositories/realm/schemas.js +108 -0
  50. package/dist/cjs/repositories/realm/types.js +7 -0
  51. package/dist/cjs/repositories/realm/walletRepository.js +273 -0
  52. package/dist/cjs/repositories/serialization.js +49 -0
  53. package/dist/cjs/repositories/sqlite/contractRepository.js +139 -0
  54. package/dist/cjs/repositories/sqlite/index.js +7 -0
  55. package/dist/cjs/repositories/sqlite/types.js +2 -0
  56. package/dist/cjs/repositories/sqlite/walletRepository.js +328 -0
  57. package/dist/cjs/repositories/walletRepository.js +0 -169
  58. package/dist/cjs/script/base.js +54 -0
  59. package/dist/cjs/script/delegate.js +49 -0
  60. package/dist/cjs/storage/asyncStorage.js +4 -1
  61. package/dist/cjs/storage/fileSystem.js +3 -0
  62. package/dist/cjs/storage/inMemory.js +3 -0
  63. package/dist/cjs/storage/indexedDB.js +5 -1
  64. package/dist/cjs/storage/localStorage.js +3 -0
  65. package/dist/cjs/utils/arkTransaction.js +16 -0
  66. package/dist/cjs/utils/transactionHistory.js +50 -0
  67. package/dist/cjs/wallet/asset-manager.js +338 -0
  68. package/dist/cjs/wallet/asset.js +117 -0
  69. package/dist/cjs/wallet/batch.js +1 -1
  70. package/dist/cjs/wallet/delegator.js +235 -0
  71. package/dist/cjs/wallet/expo/background.js +133 -0
  72. package/dist/cjs/wallet/expo/index.js +9 -0
  73. package/dist/cjs/wallet/expo/wallet.js +231 -0
  74. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +568 -0
  75. package/dist/cjs/wallet/serviceWorker/wallet.js +383 -102
  76. package/dist/cjs/wallet/utils.js +58 -0
  77. package/dist/cjs/wallet/validation.js +151 -0
  78. package/dist/cjs/wallet/vtxo-manager.js +8 -1
  79. package/dist/cjs/wallet/wallet.js +702 -260
  80. package/dist/cjs/worker/browser/service-worker-manager.js +82 -0
  81. package/dist/cjs/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  82. package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +78 -0
  83. package/dist/cjs/worker/expo/index.js +12 -0
  84. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +61 -0
  85. package/dist/cjs/worker/expo/processors/index.js +6 -0
  86. package/dist/cjs/worker/expo/taskQueue.js +41 -0
  87. package/dist/cjs/worker/expo/taskRunner.js +57 -0
  88. package/dist/cjs/worker/messageBus.js +252 -0
  89. package/dist/esm/asset/assetGroup.js +137 -0
  90. package/dist/esm/asset/assetId.js +84 -0
  91. package/dist/esm/asset/assetInput.js +199 -0
  92. package/dist/esm/asset/assetOutput.js +154 -0
  93. package/dist/esm/asset/assetRef.js +78 -0
  94. package/dist/esm/asset/index.js +8 -0
  95. package/dist/esm/asset/metadata.js +167 -0
  96. package/dist/esm/asset/packet.js +159 -0
  97. package/dist/esm/asset/types.js +22 -0
  98. package/dist/esm/asset/utils.js +99 -0
  99. package/dist/esm/bip322/index.js +267 -0
  100. package/dist/esm/contracts/arkcontract.js +141 -0
  101. package/dist/esm/contracts/contractManager.js +432 -0
  102. package/dist/esm/contracts/contractWatcher.js +563 -0
  103. package/dist/esm/contracts/handlers/default.js +82 -0
  104. package/dist/esm/contracts/handlers/delegate.js +86 -0
  105. package/dist/esm/contracts/handlers/helpers.js +66 -0
  106. package/dist/esm/contracts/handlers/index.js +12 -0
  107. package/dist/esm/contracts/handlers/registry.js +86 -0
  108. package/dist/esm/contracts/handlers/vhtlc.js +190 -0
  109. package/dist/esm/contracts/index.js +13 -0
  110. package/dist/esm/contracts/types.js +1 -0
  111. package/dist/esm/forfeit.js +11 -8
  112. package/dist/esm/identity/index.js +1 -0
  113. package/dist/esm/identity/seedIdentity.js +249 -0
  114. package/dist/esm/index.js +28 -15
  115. package/dist/esm/intent/index.js +44 -9
  116. package/dist/esm/providers/ark.js +7 -0
  117. package/dist/esm/providers/delegator.js +62 -0
  118. package/dist/esm/providers/expoIndexer.js +5 -0
  119. package/dist/esm/providers/indexer.js +68 -1
  120. package/dist/esm/providers/utils.js +1 -0
  121. package/dist/esm/repositories/contractRepository.js +1 -101
  122. package/dist/esm/repositories/inMemory/contractRepository.js +51 -0
  123. package/dist/esm/repositories/inMemory/walletRepository.js +76 -0
  124. package/dist/esm/repositories/index.js +8 -0
  125. package/dist/esm/repositories/indexedDB/contractRepository.js +183 -0
  126. package/dist/esm/repositories/indexedDB/db.js +4 -0
  127. package/dist/esm/repositories/indexedDB/manager.js +92 -0
  128. package/dist/esm/repositories/indexedDB/schema.js +155 -0
  129. package/dist/esm/repositories/indexedDB/walletRepository.js +334 -0
  130. package/dist/esm/repositories/indexedDB/websqlAdapter.js +138 -0
  131. package/dist/esm/repositories/migrations/contractRepositoryImpl.js +121 -0
  132. package/dist/esm/repositories/migrations/fromStorageAdapter.js +58 -0
  133. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +176 -0
  134. package/dist/esm/repositories/realm/contractRepository.js +116 -0
  135. package/dist/esm/repositories/realm/index.js +3 -0
  136. package/dist/esm/repositories/realm/schemas.js +105 -0
  137. package/dist/esm/repositories/realm/types.js +6 -0
  138. package/dist/esm/repositories/realm/walletRepository.js +269 -0
  139. package/dist/esm/repositories/serialization.js +40 -0
  140. package/dist/esm/repositories/sqlite/contractRepository.js +135 -0
  141. package/dist/esm/repositories/sqlite/index.js +2 -0
  142. package/dist/esm/repositories/sqlite/types.js +1 -0
  143. package/dist/esm/repositories/sqlite/walletRepository.js +324 -0
  144. package/dist/esm/repositories/walletRepository.js +1 -167
  145. package/dist/esm/script/base.js +21 -1
  146. package/dist/esm/script/delegate.js +46 -0
  147. package/dist/esm/storage/asyncStorage.js +4 -1
  148. package/dist/esm/storage/fileSystem.js +3 -0
  149. package/dist/esm/storage/inMemory.js +3 -0
  150. package/dist/esm/storage/indexedDB.js +5 -1
  151. package/dist/esm/storage/localStorage.js +3 -0
  152. package/dist/esm/utils/arkTransaction.js +15 -0
  153. package/dist/esm/utils/transactionHistory.js +50 -0
  154. package/dist/esm/wallet/asset-manager.js +333 -0
  155. package/dist/esm/wallet/asset.js +111 -0
  156. package/dist/esm/wallet/batch.js +1 -1
  157. package/dist/esm/wallet/delegator.js +231 -0
  158. package/dist/esm/wallet/expo/background.js +128 -0
  159. package/dist/esm/wallet/expo/index.js +2 -0
  160. package/dist/esm/wallet/expo/wallet.js +194 -0
  161. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +564 -0
  162. package/dist/esm/wallet/serviceWorker/wallet.js +382 -101
  163. package/dist/esm/wallet/utils.js +54 -0
  164. package/dist/esm/wallet/validation.js +139 -0
  165. package/dist/esm/wallet/vtxo-manager.js +8 -1
  166. package/dist/esm/wallet/wallet.js +704 -229
  167. package/dist/esm/worker/browser/service-worker-manager.js +76 -0
  168. package/dist/esm/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  169. package/dist/esm/worker/expo/asyncStorageTaskQueue.js +74 -0
  170. package/dist/esm/worker/expo/index.js +4 -0
  171. package/dist/esm/worker/expo/processors/contractPollProcessor.js +58 -0
  172. package/dist/esm/worker/expo/processors/index.js +1 -0
  173. package/dist/esm/worker/expo/taskQueue.js +37 -0
  174. package/dist/esm/worker/expo/taskRunner.js +54 -0
  175. package/dist/esm/worker/messageBus.js +248 -0
  176. package/dist/types/asset/assetGroup.d.ts +28 -0
  177. package/dist/types/asset/assetId.d.ts +19 -0
  178. package/dist/types/asset/assetInput.d.ts +46 -0
  179. package/dist/types/asset/assetOutput.d.ts +39 -0
  180. package/dist/types/asset/assetRef.d.ts +25 -0
  181. package/dist/types/asset/index.d.ts +8 -0
  182. package/dist/types/asset/metadata.d.ts +37 -0
  183. package/dist/types/asset/packet.d.ts +27 -0
  184. package/dist/types/asset/types.d.ts +18 -0
  185. package/dist/types/asset/utils.d.ts +21 -0
  186. package/dist/types/bip322/index.d.ts +55 -0
  187. package/dist/types/contracts/arkcontract.d.ts +101 -0
  188. package/dist/types/contracts/contractManager.d.ts +331 -0
  189. package/dist/types/contracts/contractWatcher.d.ts +192 -0
  190. package/dist/types/contracts/handlers/default.d.ts +19 -0
  191. package/dist/types/contracts/handlers/delegate.d.ts +21 -0
  192. package/dist/types/contracts/handlers/helpers.d.ts +18 -0
  193. package/dist/types/contracts/handlers/index.d.ts +7 -0
  194. package/dist/types/contracts/handlers/registry.d.ts +65 -0
  195. package/dist/types/contracts/handlers/vhtlc.d.ts +32 -0
  196. package/dist/types/contracts/index.d.ts +14 -0
  197. package/dist/types/contracts/types.d.ts +222 -0
  198. package/dist/types/forfeit.d.ts +2 -1
  199. package/dist/types/identity/index.d.ts +1 -0
  200. package/dist/types/identity/seedIdentity.d.ts +128 -0
  201. package/dist/types/index.d.ts +22 -12
  202. package/dist/types/intent/index.d.ts +15 -1
  203. package/dist/types/providers/ark.d.ts +11 -2
  204. package/dist/types/providers/delegator.d.ts +29 -0
  205. package/dist/types/providers/indexer.d.ts +11 -1
  206. package/dist/types/repositories/contractRepository.d.ts +30 -19
  207. package/dist/types/repositories/inMemory/contractRepository.d.ts +17 -0
  208. package/dist/types/repositories/inMemory/walletRepository.d.ts +26 -0
  209. package/dist/types/repositories/index.d.ts +7 -0
  210. package/dist/types/repositories/indexedDB/contractRepository.d.ts +21 -0
  211. package/dist/types/repositories/indexedDB/db.d.ts +4 -0
  212. package/dist/types/repositories/indexedDB/manager.d.ts +22 -0
  213. package/dist/types/repositories/indexedDB/schema.d.ts +8 -0
  214. package/dist/types/repositories/indexedDB/walletRepository.d.ts +25 -0
  215. package/dist/types/repositories/indexedDB/websqlAdapter.d.ts +49 -0
  216. package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +24 -0
  217. package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +19 -0
  218. package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +27 -0
  219. package/dist/types/repositories/realm/contractRepository.d.ts +24 -0
  220. package/dist/types/repositories/realm/index.d.ts +4 -0
  221. package/dist/types/repositories/realm/schemas.d.ts +208 -0
  222. package/dist/types/repositories/realm/types.d.ts +16 -0
  223. package/dist/types/repositories/realm/walletRepository.d.ts +31 -0
  224. package/dist/types/repositories/serialization.d.ts +40 -0
  225. package/dist/types/repositories/sqlite/contractRepository.d.ts +33 -0
  226. package/dist/types/repositories/sqlite/index.d.ts +3 -0
  227. package/dist/types/repositories/sqlite/types.d.ts +18 -0
  228. package/dist/types/repositories/sqlite/walletRepository.d.ts +40 -0
  229. package/dist/types/repositories/walletRepository.d.ts +13 -24
  230. package/dist/types/script/base.d.ts +1 -0
  231. package/dist/types/script/delegate.d.ts +36 -0
  232. package/dist/types/storage/asyncStorage.d.ts +4 -0
  233. package/dist/types/storage/fileSystem.d.ts +3 -0
  234. package/dist/types/storage/inMemory.d.ts +3 -0
  235. package/dist/types/storage/index.d.ts +3 -0
  236. package/dist/types/storage/indexedDB.d.ts +3 -0
  237. package/dist/types/storage/localStorage.d.ts +3 -0
  238. package/dist/types/utils/arkTransaction.d.ts +6 -0
  239. package/dist/types/wallet/asset-manager.d.ts +78 -0
  240. package/dist/types/wallet/asset.d.ts +21 -0
  241. package/dist/types/wallet/batch.d.ts +1 -1
  242. package/dist/types/wallet/delegator.d.ts +24 -0
  243. package/dist/types/wallet/expo/background.d.ts +66 -0
  244. package/dist/types/wallet/expo/index.d.ts +4 -0
  245. package/dist/types/wallet/expo/wallet.d.ts +97 -0
  246. package/dist/types/wallet/index.d.ts +75 -2
  247. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +366 -0
  248. package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -11
  249. package/dist/types/wallet/utils.d.ts +12 -1
  250. package/dist/types/wallet/validation.d.ts +24 -0
  251. package/dist/types/wallet/wallet.d.ts +111 -17
  252. package/dist/types/worker/browser/service-worker-manager.d.ts +21 -0
  253. package/dist/types/{wallet/serviceWorker → worker/browser}/utils.d.ts +2 -1
  254. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +46 -0
  255. package/dist/types/worker/expo/index.d.ts +7 -0
  256. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +14 -0
  257. package/dist/types/worker/expo/processors/index.d.ts +1 -0
  258. package/dist/types/worker/expo/taskQueue.d.ts +50 -0
  259. package/dist/types/worker/expo/taskRunner.d.ts +42 -0
  260. package/dist/types/worker/messageBus.d.ts +109 -0
  261. package/package.json +69 -11
  262. package/dist/cjs/wallet/serviceWorker/request.js +0 -78
  263. package/dist/cjs/wallet/serviceWorker/response.js +0 -222
  264. package/dist/cjs/wallet/serviceWorker/worker.js +0 -655
  265. package/dist/esm/wallet/serviceWorker/request.js +0 -75
  266. package/dist/esm/wallet/serviceWorker/response.js +0 -219
  267. package/dist/esm/wallet/serviceWorker/worker.js +0 -651
  268. package/dist/types/wallet/serviceWorker/request.d.ts +0 -74
  269. package/dist/types/wallet/serviceWorker/response.d.ts +0 -123
  270. package/dist/types/wallet/serviceWorker/worker.d.ts +0 -53
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BIP322 = void 0;
4
+ const btc_signer_1 = require("@scure/btc-signer");
5
+ const utils_js_1 = require("@scure/btc-signer/utils.js");
6
+ const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
7
+ const utils_js_2 = require("@noble/curves/utils.js");
8
+ const base_1 = require("@scure/base");
9
+ const transaction_1 = require("../utils/transaction");
10
+ const intent_1 = require("../intent");
11
+ const TAG_BIP322 = "BIP0322-signed-message";
12
+ /**
13
+ * BIP-322 simple message signing and verification.
14
+ *
15
+ * Supports P2TR (Taproot) signing and verification, P2WPKH verification,
16
+ * and legacy P2PKH verification (Bitcoin Core signmessage format).
17
+ *
18
+ * Reuses the same toSpend/toSign transaction construction as Intent proofs,
19
+ * but with the standard BIP-322 tagged hash ("BIP0322-signed-message")
20
+ * instead of the Ark-specific tag.
21
+ *
22
+ * @see https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Sign a message (P2TR)
27
+ * const signature = await BIP322.sign("Hello Bitcoin!", identity);
28
+ *
29
+ * // Verify a signature (P2TR or P2WPKH)
30
+ * const valid = BIP322.verify("Hello Bitcoin!", signature, "bc1p...");
31
+ * const valid2 = BIP322.verify("Hello Bitcoin!", signature, "bc1q...");
32
+ * ```
33
+ */
34
+ var BIP322;
35
+ (function (BIP322) {
36
+ /**
37
+ * Sign a message using the BIP-322 simple signature scheme.
38
+ *
39
+ * Constructs the standard BIP-322 toSpend and toSign transactions,
40
+ * signs via the Identity interface, and returns the base64-encoded
41
+ * witness stack.
42
+ *
43
+ * @param message - The message to sign
44
+ * @param identity - Identity instance (holds the private key internally)
45
+ * @param network - Optional Bitcoin network for P2TR address derivation
46
+ * @returns Base64-encoded BIP-322 simple signature (witness stack)
47
+ */
48
+ async function sign(message, identity, network) {
49
+ const xOnlyPubKey = await identity.xOnlyPublicKey();
50
+ const payment = (0, btc_signer_1.p2tr)(xOnlyPubKey, undefined, network);
51
+ // Build BIP-322 toSpend using shared construction with BIP-322 tag
52
+ const toSpend = (0, intent_1.craftToSpendTx)(message, payment.script, TAG_BIP322);
53
+ // Build BIP-322 toSign: version 0, single input spending toSpend, OP_RETURN output
54
+ const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
55
+ // Sign with identity (handles P2TR key-spend internally)
56
+ const signed = await identity.sign(toSign, [0]);
57
+ // Finalize and extract witness
58
+ signed.finalizeIdx(0);
59
+ const input = signed.getInput(0);
60
+ if (!input.finalScriptWitness) {
61
+ throw new Error("BIP-322: failed to produce witness after signing");
62
+ }
63
+ return base_1.base64.encode(btc_signer_1.RawWitness.encode(input.finalScriptWitness));
64
+ }
65
+ BIP322.sign = sign;
66
+ /**
67
+ * Verify a BIP-322 signature for a P2TR, P2WPKH, or legacy P2PKH address.
68
+ *
69
+ * For segwit addresses (P2TR, P2WPKH), reconstructs the BIP-322
70
+ * toSpend/toSign transactions and verifies the witness signature.
71
+ *
72
+ * For P2PKH addresses, verifies using the Bitcoin Core legacy
73
+ * `signmessage` format (compact recoverable ECDSA signature).
74
+ *
75
+ * @param message - The original message that was signed
76
+ * @param signature - Base64-encoded signature (BIP-322 witness or legacy compact)
77
+ * @param address - P2TR, P2WPKH, or P2PKH address of the signer
78
+ * @param network - Optional Bitcoin network for address decoding
79
+ * @returns true if the signature is valid
80
+ */
81
+ function verify(message, signature, address, network) {
82
+ let decoded;
83
+ try {
84
+ decoded = (0, btc_signer_1.Address)(network).decode(address);
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ // Legacy P2PKH: signature is base64 of 65 raw bytes, not a witness
90
+ if (decoded.type === "pkh") {
91
+ try {
92
+ return verifyLegacy(message, base_1.base64.decode(signature), decoded.hash);
93
+ }
94
+ catch {
95
+ return false;
96
+ }
97
+ }
98
+ // BIP-322 simple: signature is base64 of RawWitness
99
+ let pkScript;
100
+ let witnessItems;
101
+ try {
102
+ pkScript = btc_signer_1.OutScript.encode(decoded);
103
+ witnessItems = btc_signer_1.RawWitness.decode(base_1.base64.decode(signature));
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ if (witnessItems.length === 0) {
109
+ return false;
110
+ }
111
+ if (decoded.type === "tr") {
112
+ return verifyP2TR(message, witnessItems, pkScript, decoded.pubkey);
113
+ }
114
+ if (decoded.type === "wpkh") {
115
+ return verifyP2WPKH(message, witnessItems, pkScript, decoded.hash);
116
+ }
117
+ throw new Error(`BIP-322 verify: unsupported address type '${decoded.type}'`);
118
+ }
119
+ BIP322.verify = verify;
120
+ })(BIP322 || (exports.BIP322 = BIP322 = {}));
121
+ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
122
+ // P2TR key-spend witness is exactly [schnorr_signature].
123
+ // Multiple items indicates a script-path spend, which BIP-322 simple doesn't cover.
124
+ if (witnessItems.length !== 1) {
125
+ return false;
126
+ }
127
+ const sig = witnessItems[0];
128
+ if (sig.length !== 64 && sig.length !== 65) {
129
+ return false;
130
+ }
131
+ // BIP-322 simple only allows SIGHASH_DEFAULT (64-byte sig) or SIGHASH_ALL (0x01).
132
+ const sighashType = sig.length === 65 ? sig[64] : btc_signer_1.SigHash.DEFAULT;
133
+ if (sighashType !== btc_signer_1.SigHash.DEFAULT && sighashType !== btc_signer_1.SigHash.ALL) {
134
+ return false;
135
+ }
136
+ const toSpend = (0, intent_1.craftToSpendTx)(message, pkScript, TAG_BIP322);
137
+ const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
138
+ const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
139
+ const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
140
+ return secp256k1_js_1.schnorr.verify(rawSig, sighash, pubkey);
141
+ }
142
+ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
143
+ // P2WPKH witness: [der_signature || sighash_byte, compressed_pubkey]
144
+ if (witnessItems.length !== 2) {
145
+ return false;
146
+ }
147
+ const sigWithHash = witnessItems[0];
148
+ const pubkey = witnessItems[1];
149
+ if (pubkey.length !== 33 || sigWithHash.length < 2) {
150
+ return false;
151
+ }
152
+ // Verify the pubkey matches the address hash
153
+ const derived = (0, btc_signer_1.p2wpkh)(pubkey);
154
+ if (!(0, utils_js_2.equalBytes)(derived.hash, addressHash)) {
155
+ return false;
156
+ }
157
+ // Extract sighash type (last byte) and DER signature
158
+ const sighashType = sigWithHash[sigWithHash.length - 1];
159
+ const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
160
+ // Build toSpend and toSign
161
+ const toSpend = (0, intent_1.craftToSpendTx)(message, pkScript, TAG_BIP322);
162
+ const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
163
+ // BIP-143 scriptCode for P2WPKH: equivalent P2PKH script
164
+ const scriptCode = btc_signer_1.OutScript.encode({ type: "pkh", hash: addressHash });
165
+ const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
166
+ return secp256k1_js_1.secp256k1.verify(derSig, sighash, pubkey, {
167
+ prehash: false,
168
+ format: "der",
169
+ });
170
+ }
171
+ /**
172
+ * Verify a legacy Bitcoin Core signmessage signature for a P2PKH address.
173
+ *
174
+ * The signature is 65 bytes: [recovery_flag, r(32), s(32)].
175
+ * The recovery flag encodes both the recovery ID and whether the key is
176
+ * compressed: flag = 27 + recovery_id (+ 4 if compressed).
177
+ */
178
+ function verifyLegacy(message, sigBytes, addressHash) {
179
+ if (sigBytes.length !== 65) {
180
+ return false;
181
+ }
182
+ const flag = sigBytes[0];
183
+ if (flag < 27 || flag > 34) {
184
+ return false;
185
+ }
186
+ const compressed = flag >= 31;
187
+ const recoveryId = compressed ? flag - 31 : flag - 27;
188
+ const compactSig = sigBytes.subarray(1, 65);
189
+ const msgHash = bitcoinMessageHash(message);
190
+ try {
191
+ const sig = secp256k1_js_1.secp256k1.Signature.fromBytes(compactSig, "compact").addRecoveryBit(recoveryId);
192
+ const point = sig.recoverPublicKey(msgHash);
193
+ const pubkeyBytes = point.toBytes(compressed);
194
+ return (0, utils_js_2.equalBytes)((0, utils_js_1.hash160)(pubkeyBytes), addressHash);
195
+ }
196
+ catch {
197
+ return false;
198
+ }
199
+ }
200
+ /**
201
+ * Compute the Bitcoin message hash: SHA256d(magic_prefix + CompactSize(len) + message).
202
+ */
203
+ function bitcoinMessageHash(message) {
204
+ const MAGIC = new TextEncoder().encode("\x18Bitcoin Signed Message:\n");
205
+ const msgBytes = new TextEncoder().encode(message);
206
+ return (0, utils_js_1.sha256x2)((0, utils_js_1.concatBytes)(MAGIC, encodeCompactSize(msgBytes.length), msgBytes));
207
+ }
208
+ function encodeCompactSize(n) {
209
+ if (n < 253)
210
+ return new Uint8Array([n]);
211
+ if (n <= 0xffff) {
212
+ const buf = new Uint8Array(3);
213
+ buf[0] = 253;
214
+ buf[1] = n & 0xff;
215
+ buf[2] = (n >> 8) & 0xff;
216
+ return buf;
217
+ }
218
+ const buf = new Uint8Array(5);
219
+ buf[0] = 254;
220
+ buf[1] = n & 0xff;
221
+ buf[2] = (n >> 8) & 0xff;
222
+ buf[3] = (n >> 16) & 0xff;
223
+ buf[4] = (n >> 24) & 0xff;
224
+ return buf;
225
+ }
226
+ /**
227
+ * Build the BIP-322 "toSign" transaction for P2TR key-spend.
228
+ */
229
+ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
230
+ const tx = new transaction_1.Transaction({ version: 0 });
231
+ tx.addInput({
232
+ txid: toSpend.id,
233
+ index: 0,
234
+ sequence: 0,
235
+ witnessUtxo: {
236
+ script: pkScript,
237
+ amount: 0n,
238
+ },
239
+ tapInternalKey,
240
+ sighashType: btc_signer_1.SigHash.DEFAULT,
241
+ });
242
+ tx.addOutput({
243
+ amount: 0n,
244
+ script: intent_1.OP_RETURN_EMPTY_PKSCRIPT,
245
+ });
246
+ return tx;
247
+ }
248
+ /**
249
+ * Build the BIP-322 "toSign" transaction (generic, no key metadata).
250
+ *
251
+ * Used for P2WPKH verification where the toSign only needs
252
+ * the witnessUtxo, not tapInternalKey.
253
+ */
254
+ function craftBIP322ToSignSimple(toSpend, pkScript) {
255
+ const tx = new transaction_1.Transaction({ version: 0 });
256
+ tx.addInput({
257
+ txid: toSpend.id,
258
+ index: 0,
259
+ sequence: 0,
260
+ witnessUtxo: {
261
+ script: pkScript,
262
+ amount: 0n,
263
+ },
264
+ });
265
+ tx.addOutput({
266
+ amount: 0n,
267
+ script: intent_1.OP_RETURN_EMPTY_PKSCRIPT,
268
+ });
269
+ return tx;
270
+ }
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodeArkContract = encodeArkContract;
4
+ exports.decodeArkContract = decodeArkContract;
5
+ exports.contractFromArkContract = contractFromArkContract;
6
+ exports.contractFromArkContractWithAddress = contractFromArkContractWithAddress;
7
+ exports.isArkContract = isArkContract;
8
+ const base_1 = require("@scure/base");
9
+ const handlers_1 = require("./handlers");
10
+ /**
11
+ * Prefix for arkcontract strings.
12
+ */
13
+ const ARKCONTRACT_PREFIX = "arkcontract";
14
+ /**
15
+ * Encode a contract to the arkcontract string format.
16
+ *
17
+ * Format: arkcontract={type}&{key1}={value1}&{key2}={value2}...
18
+ *
19
+ * This format is compatible with NArk and allows contracts to be
20
+ * shared/imported across different Ark implementations.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const contract: Contract = {
25
+ * type: "vhtlc",
26
+ * params: { sender: "ab12...", receiver: "cd34...", ... },
27
+ * // ...
28
+ * };
29
+ *
30
+ * const encoded = encodeArkContract(contract);
31
+ * // "arkcontract=vhtlc&sender=ab12...&receiver=cd34...&..."
32
+ * ```
33
+ */
34
+ function encodeArkContract(contract) {
35
+ const params = new URLSearchParams();
36
+ // Add contract type first
37
+ params.set(ARKCONTRACT_PREFIX, contract.type);
38
+ // Add all params
39
+ for (const [key, value] of Object.entries(contract.params)) {
40
+ params.set(key, value);
41
+ }
42
+ return params.toString();
43
+ }
44
+ /**
45
+ * Decode an arkcontract string into raw type and data.
46
+ *
47
+ * This is a low-level function that parses the URL-encoded format.
48
+ * For creating typed Contract objects, use `contractFromArkContract`
49
+ * or `contractFromArkContractWithAddress` instead.
50
+ *
51
+ * @param encoded - The arkcontract string
52
+ * @returns Parsed type and key-value data
53
+ * @throws If the string is not a valid arkcontract
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const parsed = decodeArkContract("arkcontract=vhtlc&sender=ab12...");
58
+ * // { type: "vhtlc", data: { sender: "ab12...", ... } }
59
+ * ```
60
+ */
61
+ function decodeArkContract(encoded) {
62
+ const params = new URLSearchParams(encoded);
63
+ // Extract type from the arkcontract key
64
+ const type = params.get(ARKCONTRACT_PREFIX);
65
+ if (!type) {
66
+ throw new Error(`Invalid arkcontract string: missing '${ARKCONTRACT_PREFIX}' key`);
67
+ }
68
+ // Build data object from all other params
69
+ const data = {};
70
+ for (const [key, value] of params.entries()) {
71
+ if (key !== ARKCONTRACT_PREFIX) {
72
+ data[key] = value;
73
+ }
74
+ }
75
+ return { type, data };
76
+ }
77
+ /**
78
+ * Create a Contract from an arkcontract string.
79
+ *
80
+ * This requires a handler to be registered for the contract type.
81
+ *
82
+ * @param encoded - The arkcontract string
83
+ * @param options - Additional options for the contract
84
+ * @returns A Contract object
85
+ * @throws If the string is invalid or no handler exists for the type
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const contract = contractFromArkContract(
90
+ * "arkcontract=vhtlc&sender=ab12...",
91
+ * {
92
+ * label: "Lightning Receive",
93
+ * }
94
+ * );
95
+ * ```
96
+ */
97
+ function contractFromArkContract(encoded, options = {}) {
98
+ const parsed = decodeArkContract(encoded);
99
+ const handler = handlers_1.contractHandlers.get(parsed.type);
100
+ if (!handler) {
101
+ throw new Error(`No handler registered for contract type '${parsed.type}'`);
102
+ }
103
+ // Separate params from runtime data
104
+ // This is type-specific - the handler knows which keys are params
105
+ // For now, we treat all data as params
106
+ const params = parsed.data;
107
+ return {
108
+ label: options.label,
109
+ type: parsed.type,
110
+ params,
111
+ state: options.state || "active",
112
+ createdAt: Date.now(),
113
+ expiresAt: options.expiresAt,
114
+ metadata: options.metadata,
115
+ };
116
+ }
117
+ /**
118
+ * Create a full Contract with derived script and address.
119
+ *
120
+ * @param encoded - The arkcontract string
121
+ * @param serverPubKey - Server public key (for address derivation)
122
+ * @param addressPrefix - Address prefix (e.g., "tark" for testnet)
123
+ * @param options - Additional options
124
+ * @returns A complete Contract object
125
+ */
126
+ function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix, options = {}) {
127
+ const parsed = decodeArkContract(encoded);
128
+ const handler = handlers_1.contractHandlers.getOrThrow(parsed.type);
129
+ const params = parsed.data;
130
+ const vtxoScript = handler.createScript(params);
131
+ return {
132
+ label: options.label,
133
+ type: parsed.type,
134
+ params,
135
+ script: base_1.hex.encode(vtxoScript.pkScript),
136
+ address: vtxoScript.address(addressPrefix, serverPubKey).encode(),
137
+ state: options.state || "active",
138
+ createdAt: Date.now(),
139
+ expiresAt: options.expiresAt,
140
+ metadata: options.metadata,
141
+ };
142
+ }
143
+ /**
144
+ * Check if a string is an arkcontract.
145
+ */
146
+ function isArkContract(str) {
147
+ return str.startsWith(ARKCONTRACT_PREFIX + "=");
148
+ }