@bsv/sdk 1.1.33 → 1.2.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 (214) hide show
  1. package/dist/cjs/mod.js +4 -0
  2. package/dist/cjs/mod.js.map +1 -1
  3. package/dist/cjs/package.json +4 -3
  4. package/dist/cjs/src/auth/Certificate.js +163 -0
  5. package/dist/cjs/src/auth/Certificate.js.map +1 -0
  6. package/dist/cjs/src/auth/index.js +9 -0
  7. package/dist/cjs/src/auth/index.js.map +1 -0
  8. package/dist/cjs/src/compat/BSM.js +17 -7
  9. package/dist/cjs/src/compat/BSM.js.map +1 -1
  10. package/dist/cjs/src/compat/ECIES.js +17 -7
  11. package/dist/cjs/src/compat/ECIES.js.map +1 -1
  12. package/dist/cjs/src/compat/HD.js +17 -7
  13. package/dist/cjs/src/compat/HD.js.map +1 -1
  14. package/dist/cjs/src/compat/Mnemonic.js +17 -7
  15. package/dist/cjs/src/compat/Mnemonic.js.map +1 -1
  16. package/dist/cjs/src/compat/index.js +17 -7
  17. package/dist/cjs/src/compat/index.js.map +1 -1
  18. package/dist/cjs/src/messages/index.js +17 -7
  19. package/dist/cjs/src/messages/index.js.map +1 -1
  20. package/dist/cjs/src/overlay-tools/LookupResolver.js +170 -0
  21. package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -0
  22. package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js +69 -0
  23. package/dist/cjs/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -0
  24. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js +336 -0
  25. package/dist/cjs/src/overlay-tools/SHIPBroadcaster.js.map +1 -0
  26. package/dist/cjs/src/overlay-tools/index.js +29 -0
  27. package/dist/cjs/src/overlay-tools/index.js.map +1 -0
  28. package/dist/cjs/src/primitives/PrivateKey.js +17 -7
  29. package/dist/cjs/src/primitives/PrivateKey.js.map +1 -1
  30. package/dist/cjs/src/primitives/TransactionSignature.js +17 -7
  31. package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
  32. package/dist/cjs/src/primitives/index.js +17 -7
  33. package/dist/cjs/src/primitives/index.js.map +1 -1
  34. package/dist/cjs/src/script/Spend.js +17 -7
  35. package/dist/cjs/src/script/Spend.js.map +1 -1
  36. package/dist/cjs/src/script/templates/PushDrop.js +218 -0
  37. package/dist/cjs/src/script/templates/PushDrop.js.map +1 -0
  38. package/dist/cjs/src/script/templates/index.js +3 -1
  39. package/dist/cjs/src/script/templates/index.js.map +1 -1
  40. package/dist/cjs/src/transaction/http/DefaultHttpClient.js +1 -1
  41. package/dist/cjs/src/transaction/http/DefaultHttpClient.js.map +1 -1
  42. package/dist/cjs/src/wallet/CachedKeyDeriver.js +177 -0
  43. package/dist/cjs/src/wallet/CachedKeyDeriver.js.map +1 -0
  44. package/dist/cjs/src/wallet/KeyDeriver.js +174 -0
  45. package/dist/cjs/src/wallet/KeyDeriver.js.map +1 -0
  46. package/dist/cjs/src/wallet/ProtoWallet.js +245 -0
  47. package/dist/cjs/src/wallet/ProtoWallet.js.map +1 -0
  48. package/dist/cjs/src/wallet/Wallet.interfaces.js +3 -0
  49. package/dist/cjs/src/wallet/Wallet.interfaces.js.map +1 -0
  50. package/dist/cjs/src/wallet/WalletClient.js +181 -0
  51. package/dist/cjs/src/wallet/WalletClient.js.map +1 -0
  52. package/dist/cjs/src/wallet/WalletError.js +28 -0
  53. package/dist/cjs/src/wallet/WalletError.js.map +1 -0
  54. package/dist/cjs/src/wallet/index.js +34 -0
  55. package/dist/cjs/src/wallet/index.js.map +1 -0
  56. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js +45 -0
  57. package/dist/cjs/src/wallet/substrates/HTTPWalletWire.js.map +1 -0
  58. package/dist/cjs/src/wallet/substrates/WalletWire.js +3 -0
  59. package/dist/cjs/src/wallet/substrates/WalletWire.js.map +1 -0
  60. package/dist/cjs/src/wallet/substrates/WalletWireCalls.js +36 -0
  61. package/dist/cjs/src/wallet/substrates/WalletWireCalls.js.map +1 -0
  62. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +1821 -0
  63. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -0
  64. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +1305 -0
  65. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -0
  66. package/dist/cjs/src/wallet/substrates/XDM.js +130 -0
  67. package/dist/cjs/src/wallet/substrates/XDM.js.map +1 -0
  68. package/dist/cjs/src/wallet/substrates/index.js +33 -0
  69. package/dist/cjs/src/wallet/substrates/index.js.map +1 -0
  70. package/dist/cjs/src/wallet/substrates/window.CWI.js +102 -0
  71. package/dist/cjs/src/wallet/substrates/window.CWI.js.map +1 -0
  72. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  73. package/dist/esm/mod.js +4 -0
  74. package/dist/esm/mod.js.map +1 -1
  75. package/dist/esm/src/auth/Certificate.js +185 -0
  76. package/dist/esm/src/auth/Certificate.js.map +1 -0
  77. package/dist/esm/src/auth/index.js +2 -0
  78. package/dist/esm/src/auth/index.js.map +1 -0
  79. package/dist/esm/src/overlay-tools/LookupResolver.js +167 -0
  80. package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -0
  81. package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js +64 -0
  82. package/dist/esm/src/overlay-tools/OverlayAdminTokenTemplate.js.map +1 -0
  83. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js +335 -0
  84. package/dist/esm/src/overlay-tools/SHIPBroadcaster.js.map +1 -0
  85. package/dist/esm/src/overlay-tools/index.js +6 -0
  86. package/dist/esm/src/overlay-tools/index.js.map +1 -0
  87. package/dist/esm/src/script/templates/PushDrop.js +215 -0
  88. package/dist/esm/src/script/templates/PushDrop.js.map +1 -0
  89. package/dist/esm/src/script/templates/index.js +1 -0
  90. package/dist/esm/src/script/templates/index.js.map +1 -1
  91. package/dist/esm/src/transaction/http/DefaultHttpClient.js +1 -1
  92. package/dist/esm/src/transaction/http/DefaultHttpClient.js.map +1 -1
  93. package/dist/esm/src/wallet/CachedKeyDeriver.js +174 -0
  94. package/dist/esm/src/wallet/CachedKeyDeriver.js.map +1 -0
  95. package/dist/esm/src/wallet/KeyDeriver.js +172 -0
  96. package/dist/esm/src/wallet/KeyDeriver.js.map +1 -0
  97. package/dist/esm/src/wallet/ProtoWallet.js +207 -0
  98. package/dist/esm/src/wallet/ProtoWallet.js.map +1 -0
  99. package/dist/esm/src/wallet/Wallet.interfaces.js +2 -0
  100. package/dist/esm/src/wallet/Wallet.interfaces.js.map +1 -0
  101. package/dist/esm/src/wallet/WalletClient.js +177 -0
  102. package/dist/esm/src/wallet/WalletClient.js.map +1 -0
  103. package/dist/esm/src/wallet/WalletError.js +25 -0
  104. package/dist/esm/src/wallet/WalletError.js.map +1 -0
  105. package/dist/esm/src/wallet/index.js +9 -0
  106. package/dist/esm/src/wallet/index.js.map +1 -0
  107. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js +42 -0
  108. package/dist/esm/src/wallet/substrates/HTTPWalletWire.js.map +1 -0
  109. package/dist/esm/src/wallet/substrates/WalletWire.js +2 -0
  110. package/dist/esm/src/wallet/substrates/WalletWire.js.map +1 -0
  111. package/dist/esm/src/wallet/substrates/WalletWireCalls.js +34 -0
  112. package/dist/esm/src/wallet/substrates/WalletWireCalls.js.map +1 -0
  113. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +1816 -0
  114. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -0
  115. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +1300 -0
  116. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -0
  117. package/dist/esm/src/wallet/substrates/XDM.js +128 -0
  118. package/dist/esm/src/wallet/substrates/XDM.js.map +1 -0
  119. package/dist/esm/src/wallet/substrates/index.js +8 -0
  120. package/dist/esm/src/wallet/substrates/index.js.map +1 -0
  121. package/dist/esm/src/wallet/substrates/window.CWI.js +100 -0
  122. package/dist/esm/src/wallet/substrates/window.CWI.js.map +1 -0
  123. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  124. package/dist/types/mod.d.ts +4 -0
  125. package/dist/types/mod.d.ts.map +1 -1
  126. package/dist/types/src/auth/Certificate.d.ts +76 -0
  127. package/dist/types/src/auth/Certificate.d.ts.map +1 -0
  128. package/dist/types/src/auth/index.d.ts +2 -0
  129. package/dist/types/src/auth/index.d.ts.map +1 -0
  130. package/dist/types/src/overlay-tools/LookupResolver.d.ts +71 -0
  131. package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -0
  132. package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts +44 -0
  133. package/dist/types/src/overlay-tools/OverlayAdminTokenTemplate.d.ts.map +1 -0
  134. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts +90 -0
  135. package/dist/types/src/overlay-tools/SHIPBroadcaster.d.ts.map +1 -0
  136. package/dist/types/src/overlay-tools/index.d.ts +6 -0
  137. package/dist/types/src/overlay-tools/index.d.ts.map +1 -0
  138. package/dist/types/src/script/templates/PushDrop.d.ts +53 -0
  139. package/dist/types/src/script/templates/PushDrop.d.ts.map +1 -0
  140. package/dist/types/src/script/templates/index.d.ts +1 -0
  141. package/dist/types/src/script/templates/index.d.ts.map +1 -1
  142. package/dist/types/src/wallet/CachedKeyDeriver.d.ts +92 -0
  143. package/dist/types/src/wallet/CachedKeyDeriver.d.ts.map +1 -0
  144. package/dist/types/src/wallet/KeyDeriver.d.ts +72 -0
  145. package/dist/types/src/wallet/KeyDeriver.d.ts.map +1 -0
  146. package/dist/types/src/wallet/ProtoWallet.d.ts +415 -0
  147. package/dist/types/src/wallet/ProtoWallet.d.ts.map +1 -0
  148. package/dist/types/src/wallet/Wallet.interfaces.d.ts +996 -0
  149. package/dist/types/src/wallet/Wallet.interfaces.d.ts.map +1 -0
  150. package/dist/types/src/wallet/WalletClient.d.ts +182 -0
  151. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -0
  152. package/dist/types/src/wallet/WalletError.d.ts +14 -0
  153. package/dist/types/src/wallet/WalletError.d.ts.map +1 -0
  154. package/dist/types/src/wallet/index.d.ts +9 -0
  155. package/dist/types/src/wallet/index.d.ts.map +1 -0
  156. package/dist/types/src/wallet/substrates/HTTPWalletWire.d.ts +9 -0
  157. package/dist/types/src/wallet/substrates/HTTPWalletWire.d.ts.map +1 -0
  158. package/dist/types/src/wallet/substrates/WalletWire.d.ts +7 -0
  159. package/dist/types/src/wallet/substrates/WalletWire.d.ts.map +1 -0
  160. package/dist/types/src/wallet/substrates/WalletWireCalls.d.ts +33 -0
  161. package/dist/types/src/wallet/substrates/WalletWireCalls.d.ts.map +1 -0
  162. package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts +18 -0
  163. package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts.map +1 -0
  164. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts +196 -0
  165. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -0
  166. package/dist/types/src/wallet/substrates/XDM.d.ts +412 -0
  167. package/dist/types/src/wallet/substrates/XDM.d.ts.map +1 -0
  168. package/dist/types/src/wallet/substrates/index.d.ts +8 -0
  169. package/dist/types/src/wallet/substrates/index.d.ts.map +1 -0
  170. package/dist/types/src/wallet/substrates/window.CWI.d.ts +410 -0
  171. package/dist/types/src/wallet/substrates/window.CWI.d.ts.map +1 -0
  172. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  173. package/dist/umd/bundle.js +1 -1
  174. package/docs/overlay-tools.md +551 -0
  175. package/docs/script.md +135 -0
  176. package/docs/totp.md +119 -0
  177. package/docs/wallet-substrates.md +10 -0
  178. package/docs/wallet.md +4182 -0
  179. package/mod.ts +5 -1
  180. package/package.json +44 -3
  181. package/src/auth/Certificate.ts +233 -0
  182. package/src/auth/__tests/Certificate.test.ts +282 -0
  183. package/src/auth/index.ts +1 -0
  184. package/src/overlay-tools/LookupResolver.ts +228 -0
  185. package/src/overlay-tools/OverlayAdminTokenTemplate.ts +79 -0
  186. package/src/overlay-tools/SHIPBroadcaster.ts +405 -0
  187. package/src/overlay-tools/__tests/LookupResolver.test.ts +1403 -0
  188. package/src/overlay-tools/__tests/OverlayAdminTokenTemplate.test.ts +69 -0
  189. package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +904 -0
  190. package/src/overlay-tools/index.ts +5 -0
  191. package/src/script/templates/PushDrop.ts +246 -0
  192. package/src/script/templates/__tests/PushDrop.test.ts +158 -0
  193. package/src/script/templates/index.ts +1 -0
  194. package/src/transaction/http/DefaultHttpClient.ts +1 -1
  195. package/src/wallet/CachedKeyDeriver.ts +193 -0
  196. package/src/wallet/KeyDeriver.ts +178 -0
  197. package/src/wallet/ProtoWallet.ts +732 -0
  198. package/src/wallet/Wallet.interfaces.ts +1170 -0
  199. package/src/wallet/WalletClient.ts +201 -0
  200. package/src/wallet/WalletError.ts +27 -0
  201. package/src/wallet/__tests/CachedKeyDeriver.test.ts +322 -0
  202. package/src/wallet/__tests/KeyDeriver.test.ts +118 -0
  203. package/src/wallet/__tests/ProtoWallet.test.ts +543 -0
  204. package/src/wallet/index.ts +8 -0
  205. package/src/wallet/substrates/HTTPWalletWire.ts +47 -0
  206. package/src/wallet/substrates/WalletWire.ts +6 -0
  207. package/src/wallet/substrates/WalletWireCalls.ts +34 -0
  208. package/src/wallet/substrates/WalletWireProcessor.ts +2046 -0
  209. package/src/wallet/substrates/WalletWireTransceiver.ts +1454 -0
  210. package/src/wallet/substrates/XDM.ts +157 -0
  211. package/src/wallet/substrates/__tests/WalletWire.integration.test.ts +2194 -0
  212. package/src/wallet/substrates/__tests/XDM.test.ts +659 -0
  213. package/src/wallet/substrates/index.ts +7 -0
  214. package/src/wallet/substrates/window.CWI.ts +133 -0
@@ -0,0 +1,1454 @@
1
+ import { AcquireCertificateArgs, AcquireCertificateResult, AtomicBEEF, Base64String, BasketStringUnder300Bytes, BEEF, BooleanDefaultFalse, BooleanDefaultTrue, Byte, CertificateFieldNameUnder50Bytes, CreateActionArgs, CreateActionResult, DescriptionString5to50Bytes, DiscoverCertificatesResult, EntityIconURLStringMax500Bytes, EntityNameStringMax100Bytes, HexString, InternalizeActionArgs, ISOTimestampString, KeyIDStringUnder800Bytes, LabelStringUnder300Bytes, ListActionsArgs, ListActionsResult, ListCertificatesResult, ListOutputsArgs, ListOutputsResult, OriginatorDomainNameStringUnder250Bytes, OutpointString, OutputTagStringUnder300Bytes, PositiveInteger, PositiveIntegerDefault10Max10000, PositiveIntegerMax10, PositiveIntegerOrZero, ProtocolString5To400Bytes, ProveCertificateArgs, ProveCertificateResult, PubKeyHex, SatoshiValue, SignActionArgs, SignActionResult, TXIDHexString, VersionString7To30Bytes, Wallet } from '../Wallet.interfaces.js'
2
+ import WalletWire from './WalletWire.js'
3
+ import Certificate from '../../auth/Certificate.js'
4
+ import { Utils } from '../../primitives/index.js'
5
+ import calls, { CallType } from './WalletWireCalls.js'
6
+ import { WalletError } from '../WalletError.js'
7
+
8
+ /**
9
+ * A way to make remote calls to a wallet over a wallet wire.
10
+ */
11
+ export default class WalletWireTransceiver implements Wallet {
12
+ wire: WalletWire
13
+
14
+ constructor(wire: WalletWire) {
15
+ this.wire = wire
16
+ }
17
+
18
+ private async transmit(call: CallType, originator: OriginatorDomainNameStringUnder250Bytes = '', params: number[] = []): Promise<number[]> {
19
+ const frameWriter = new Utils.Writer()
20
+ frameWriter.writeUInt8(calls[call])
21
+ const originatorArray = Utils.toArray(originator, 'utf8')
22
+ frameWriter.writeUInt8(originatorArray.length)
23
+ frameWriter.write(originatorArray)
24
+ if (params.length > 0) {
25
+ frameWriter.write(params)
26
+ }
27
+ const frame = frameWriter.toArray()
28
+ const result = await this.wire.transmitToWallet(frame)
29
+ const resultReader = new Utils.Reader(result)
30
+ const errorByte = resultReader.readUInt8()
31
+ if (errorByte === 0) {
32
+ const resultFrame = resultReader.read()
33
+ return resultFrame
34
+ } else {
35
+ // Deserialize the error message length
36
+ const errorMessageLength = resultReader.readVarIntNum()
37
+ const errorMessageBytes = resultReader.read(errorMessageLength)
38
+ const errorMessage = Utils.toUTF8(errorMessageBytes)
39
+
40
+ // Deserialize the stack trace length
41
+ const stackTraceLength = resultReader.readVarIntNum()
42
+ const stackTraceBytes = resultReader.read(stackTraceLength)
43
+ const stackTrace = Utils.toUTF8(stackTraceBytes)
44
+
45
+ // Construct a custom wallet error
46
+ const e = new WalletError(errorMessage, errorByte, stackTrace)
47
+ throw e
48
+ }
49
+ }
50
+
51
+ async createAction(args: CreateActionArgs, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<CreateActionResult> {
52
+ const paramWriter = new Utils.Writer()
53
+
54
+ // Serialize description
55
+ const descriptionBytes = Utils.toArray(args.description, 'utf8')
56
+ paramWriter.writeVarIntNum(descriptionBytes.length)
57
+ paramWriter.write(descriptionBytes)
58
+
59
+ // input BEEF
60
+ if (args.inputBEEF) {
61
+ paramWriter.writeVarIntNum(args.inputBEEF.length)
62
+ paramWriter.write(args.inputBEEF)
63
+ } else {
64
+ paramWriter.writeVarIntNum(-1)
65
+ }
66
+
67
+ // Serialize inputs
68
+ if (args.inputs) {
69
+ paramWriter.writeVarIntNum(args.inputs.length)
70
+ for (const input of args.inputs) {
71
+ // outpoint
72
+ paramWriter.write(this.encodeOutpoint(input.outpoint))
73
+
74
+ // unlockingScript / unlockingScriptLength
75
+ if (input.unlockingScript) {
76
+ const unlockingScriptBytes = Utils.toArray(input.unlockingScript, 'hex')
77
+ paramWriter.writeVarIntNum(unlockingScriptBytes.length)
78
+ paramWriter.write(unlockingScriptBytes)
79
+ } else {
80
+ paramWriter.writeVarIntNum(-1)
81
+ paramWriter.writeVarIntNum(input.unlockingScriptLength)
82
+ }
83
+
84
+ // inputDescription
85
+ const inputDescriptionBytes = Utils.toArray(input.inputDescription, 'utf8')
86
+ paramWriter.writeVarIntNum(inputDescriptionBytes.length)
87
+ paramWriter.write(inputDescriptionBytes)
88
+
89
+ // sequenceNumber
90
+ if (typeof input.sequenceNumber === 'number') {
91
+ paramWriter.writeVarIntNum(input.sequenceNumber)
92
+ } else {
93
+ paramWriter.writeVarIntNum(-1)
94
+ }
95
+ }
96
+ } else {
97
+ paramWriter.writeVarIntNum(-1)
98
+ }
99
+
100
+ // Serialize outputs
101
+ if (args.outputs) {
102
+ paramWriter.writeVarIntNum(args.outputs.length)
103
+ for (const output of args.outputs) {
104
+ // lockingScript
105
+ const lockingScriptBytes = Utils.toArray(output.lockingScript, 'hex')
106
+ paramWriter.writeVarIntNum(lockingScriptBytes.length)
107
+ paramWriter.write(lockingScriptBytes)
108
+
109
+ // satoshis
110
+ paramWriter.writeVarIntNum(output.satoshis)
111
+
112
+ // outputDescription
113
+ const outputDescriptionBytes = Utils.toArray(output.outputDescription, 'utf8')
114
+ paramWriter.writeVarIntNum(outputDescriptionBytes.length)
115
+ paramWriter.write(outputDescriptionBytes)
116
+
117
+ // basket
118
+ if (output.basket) {
119
+ const basketBytes = Utils.toArray(output.basket, 'utf8')
120
+ paramWriter.writeVarIntNum(basketBytes.length)
121
+ paramWriter.write(basketBytes)
122
+ } else {
123
+ paramWriter.writeVarIntNum(-1)
124
+ }
125
+
126
+ // customInstructions
127
+ if (output.customInstructions) {
128
+ const customInstructionsBytes = Utils.toArray(output.customInstructions, 'utf8')
129
+ paramWriter.writeVarIntNum(customInstructionsBytes.length)
130
+ paramWriter.write(customInstructionsBytes)
131
+ } else {
132
+ paramWriter.writeVarIntNum(-1)
133
+ }
134
+
135
+ // tags
136
+ if (output.tags) {
137
+ paramWriter.writeVarIntNum(output.tags.length)
138
+ for (const tag of output.tags) {
139
+ const tagBytes = Utils.toArray(tag, 'utf8')
140
+ paramWriter.writeVarIntNum(tagBytes.length)
141
+ paramWriter.write(tagBytes)
142
+ }
143
+ } else {
144
+ paramWriter.writeVarIntNum(-1)
145
+ }
146
+ }
147
+ } else {
148
+ paramWriter.writeVarIntNum(-1)
149
+ }
150
+
151
+ // Serialize lockTime
152
+ if (typeof args.lockTime === 'number') {
153
+ paramWriter.writeVarIntNum(args.lockTime)
154
+ } else {
155
+ paramWriter.writeVarIntNum(-1)
156
+ }
157
+
158
+ // Serialize version
159
+ if (typeof args.version === 'number') {
160
+ paramWriter.writeVarIntNum(args.version)
161
+ } else {
162
+ paramWriter.writeVarIntNum(-1)
163
+ }
164
+
165
+ // Serialize labels
166
+ if (args.labels) {
167
+ paramWriter.writeVarIntNum(args.labels.length)
168
+ for (const label of args.labels) {
169
+ const labelBytes = Utils.toArray(label, 'utf8')
170
+ paramWriter.writeVarIntNum(labelBytes.length)
171
+ paramWriter.write(labelBytes)
172
+ }
173
+ } else {
174
+ paramWriter.writeVarIntNum(-1)
175
+ }
176
+
177
+ // Serialize options
178
+ if (args.options) {
179
+ paramWriter.writeInt8(1) // options present
180
+
181
+ // signAndProcess
182
+ if (typeof args.options.signAndProcess === 'boolean') {
183
+ paramWriter.writeInt8(args.options.signAndProcess ? 1 : 0)
184
+ } else {
185
+ paramWriter.writeInt8(-1)
186
+ }
187
+
188
+ // acceptDelayedBroadcast
189
+ if (typeof args.options.acceptDelayedBroadcast === 'boolean') {
190
+ paramWriter.writeInt8(args.options.acceptDelayedBroadcast ? 1 : 0)
191
+ } else {
192
+ paramWriter.writeInt8(-1)
193
+ }
194
+
195
+ // trustSelf
196
+ if (args.options.trustSelf === 'known') {
197
+ paramWriter.writeInt8(1)
198
+ } else {
199
+ paramWriter.writeInt8(-1)
200
+ }
201
+
202
+ // knownTxids
203
+ if (args.options.knownTxids) {
204
+ paramWriter.writeVarIntNum(args.options.knownTxids.length)
205
+ for (const txid of args.options.knownTxids) {
206
+ const txidBytes = Utils.toArray(txid, 'hex')
207
+ paramWriter.write(txidBytes)
208
+ }
209
+ } else {
210
+ paramWriter.writeVarIntNum(-1)
211
+ }
212
+
213
+ // returnTXIDOnly
214
+ if (typeof args.options.returnTXIDOnly === 'boolean') {
215
+ paramWriter.writeInt8(args.options.returnTXIDOnly ? 1 : 0)
216
+ } else {
217
+ paramWriter.writeInt8(-1)
218
+ }
219
+
220
+ // noSend
221
+ if (typeof args.options.noSend === 'boolean') {
222
+ paramWriter.writeInt8(args.options.noSend ? 1 : 0)
223
+ } else {
224
+ paramWriter.writeInt8(-1)
225
+ }
226
+
227
+ // noSendChange
228
+ if (args.options.noSendChange) {
229
+ paramWriter.writeVarIntNum(args.options.noSendChange.length)
230
+ for (const outpoint of args.options.noSendChange) {
231
+ paramWriter.write(this.encodeOutpoint(outpoint))
232
+ }
233
+ } else {
234
+ paramWriter.writeVarIntNum(-1)
235
+ }
236
+
237
+ // sendWith
238
+ if (args.options.sendWith) {
239
+ paramWriter.writeVarIntNum(args.options.sendWith.length)
240
+ for (const txid of args.options.sendWith) {
241
+ const txidBytes = Utils.toArray(txid, 'hex')
242
+ paramWriter.write(txidBytes)
243
+ }
244
+ } else {
245
+ paramWriter.writeVarIntNum(-1)
246
+ }
247
+
248
+ // randomizeOutputs
249
+ if (typeof args.options.randomizeOutputs === 'boolean') {
250
+ paramWriter.writeInt8(args.options.randomizeOutputs ? 1 : 0)
251
+ } else {
252
+ paramWriter.writeInt8(-1)
253
+ }
254
+ } else {
255
+ paramWriter.writeInt8(0) // options not present
256
+ }
257
+
258
+ // Transmit and parse response
259
+ const result = await this.transmit('createAction', originator, paramWriter.toArray())
260
+ const resultReader = new Utils.Reader(result)
261
+
262
+ const response: {
263
+ txid?: TXIDHexString
264
+ tx?: BEEF
265
+ noSendChange?: OutpointString[]
266
+ sendWithResults?: Array<{
267
+ txid: TXIDHexString
268
+ status: 'unproven' | 'sending' | 'failed'
269
+ }>
270
+ signableTransaction?: {
271
+ tx: BEEF
272
+ reference: Base64String
273
+ }
274
+ } = {}
275
+
276
+ // Parse txid
277
+ const txidFlag = resultReader.readInt8()
278
+ if (txidFlag === 1) {
279
+ const txidBytes = resultReader.read(32)
280
+ response.txid = Utils.toHex(txidBytes)
281
+ }
282
+
283
+ // Parse tx
284
+ const txFlag = resultReader.readInt8()
285
+ if (txFlag === 1) {
286
+ const txLength = resultReader.readVarIntNum()
287
+ response.tx = resultReader.read(txLength)
288
+ }
289
+
290
+ // Parse noSendChange
291
+ const noSendChangeLength = resultReader.readVarIntNum()
292
+ if (noSendChangeLength >= 0) {
293
+ response.noSendChange = []
294
+ for (let i = 0; i < noSendChangeLength; i++) {
295
+ const outpoint = this.readOutpoint(resultReader)
296
+ response.noSendChange.push(outpoint)
297
+ }
298
+ }
299
+
300
+ // Parse sendWithResults
301
+ const sendWithResultsLength = resultReader.readVarIntNum()
302
+ if (sendWithResultsLength >= 0) {
303
+ response.sendWithResults = []
304
+ for (let i = 0; i < sendWithResultsLength; i++) {
305
+ const txidBytes = resultReader.read(32)
306
+ const txid = Utils.toHex(txidBytes)
307
+ const statusCode = resultReader.readInt8()
308
+ let status: 'unproven' | 'sending' | 'failed'
309
+ if (statusCode === 1) status = 'unproven'
310
+ else if (statusCode === 2) status = 'sending'
311
+ else if (statusCode === 3) status = 'failed'
312
+ response.sendWithResults.push({ txid, status })
313
+ }
314
+ }
315
+
316
+ // Parse signableTransaction
317
+ const signableTransactionFlag = resultReader.readInt8()
318
+ if (signableTransactionFlag === 1) {
319
+ const txLength = resultReader.readVarIntNum()
320
+ const tx = resultReader.read(txLength)
321
+ const referenceLength = resultReader.readVarIntNum()
322
+ const referenceBytes = resultReader.read(referenceLength)
323
+ response.signableTransaction = {
324
+ tx,
325
+ reference: Utils.toBase64(referenceBytes)
326
+ }
327
+ }
328
+
329
+ return response
330
+ }
331
+
332
+ async signAction(args: SignActionArgs, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<SignActionResult> {
333
+ const paramWriter = new Utils.Writer()
334
+
335
+ // Serialize spends
336
+ const spendIndexes = Object.keys(args.spends)
337
+ paramWriter.writeVarIntNum(spendIndexes.length)
338
+ for (const index of spendIndexes) {
339
+ paramWriter.writeVarIntNum(Number(index))
340
+ const spend = args.spends[Number(index)]
341
+ // unlockingScript
342
+ const unlockingScriptBytes = Utils.toArray(spend.unlockingScript, 'hex')
343
+ paramWriter.writeVarIntNum(unlockingScriptBytes.length)
344
+ paramWriter.write(unlockingScriptBytes)
345
+ // sequenceNumber
346
+ if (typeof spend.sequenceNumber === 'number') {
347
+ paramWriter.writeVarIntNum(spend.sequenceNumber)
348
+ } else {
349
+ paramWriter.writeVarIntNum(-1)
350
+ }
351
+ }
352
+
353
+ // Serialize reference
354
+ const referenceBytes = Utils.toArray(args.reference, 'base64')
355
+ paramWriter.writeVarIntNum(referenceBytes.length)
356
+ paramWriter.write(referenceBytes)
357
+
358
+ // Serialize options
359
+ if (args.options) {
360
+ paramWriter.writeInt8(1) // options present
361
+
362
+ // acceptDelayedBroadcast
363
+ if (typeof args.options.acceptDelayedBroadcast === 'boolean') {
364
+ paramWriter.writeInt8(args.options.acceptDelayedBroadcast ? 1 : 0)
365
+ } else {
366
+ paramWriter.writeInt8(-1)
367
+ }
368
+
369
+ // returnTXIDOnly
370
+ if (typeof args.options.returnTXIDOnly === 'boolean') {
371
+ paramWriter.writeInt8(args.options.returnTXIDOnly ? 1 : 0)
372
+ } else {
373
+ paramWriter.writeInt8(-1)
374
+ }
375
+
376
+ // noSend
377
+ if (typeof args.options.noSend === 'boolean') {
378
+ paramWriter.writeInt8(args.options.noSend ? 1 : 0)
379
+ } else {
380
+ paramWriter.writeInt8(-1)
381
+ }
382
+
383
+ // sendWith
384
+ if (args.options.sendWith) {
385
+ paramWriter.writeVarIntNum(args.options.sendWith.length)
386
+ for (const txid of args.options.sendWith) {
387
+ const txidBytes = Utils.toArray(txid, 'hex')
388
+ paramWriter.write(txidBytes)
389
+ }
390
+ } else {
391
+ paramWriter.writeVarIntNum(-1)
392
+ }
393
+ } else {
394
+ paramWriter.writeInt8(0) // options not present
395
+ }
396
+
397
+ // Transmit and parse response
398
+ const result = await this.transmit('signAction', originator, paramWriter.toArray())
399
+ const resultReader = new Utils.Reader(result)
400
+
401
+ const response: {
402
+ txid?: TXIDHexString
403
+ tx?: BEEF
404
+ noSendChange?: OutpointString[]
405
+ sendWithResults?: Array<{
406
+ txid: TXIDHexString
407
+ status: 'unproven' | 'sending' | 'failed'
408
+ }>
409
+ } = {}
410
+
411
+ // Parse txid
412
+ const txidFlag = resultReader.readInt8()
413
+ if (txidFlag === 1) {
414
+ const txidBytes = resultReader.read(32)
415
+ response.txid = Utils.toHex(txidBytes)
416
+ }
417
+
418
+ // Parse tx
419
+ const txFlag = resultReader.readInt8()
420
+ if (txFlag === 1) {
421
+ const txLength = resultReader.readVarIntNum()
422
+ response.tx = resultReader.read(txLength)
423
+ }
424
+
425
+ // Parse sendWithResults
426
+ const sendWithResultsLength = resultReader.readVarIntNum()
427
+ if (sendWithResultsLength >= 0) {
428
+ response.sendWithResults = []
429
+ for (let i = 0; i < sendWithResultsLength; i++) {
430
+ const txidBytes = resultReader.read(32)
431
+ const txid = Utils.toHex(txidBytes)
432
+ const statusCode = resultReader.readInt8()
433
+ let status: 'unproven' | 'sending' | 'failed'
434
+ if (statusCode === 1) status = 'unproven'
435
+ else if (statusCode === 2) status = 'sending'
436
+ else if (statusCode === 3) status = 'failed'
437
+ response.sendWithResults.push({ txid, status })
438
+ }
439
+ }
440
+
441
+ return response
442
+ }
443
+
444
+ async abortAction(args: { reference: Base64String }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ aborted: true }> {
445
+ await this.transmit('abortAction', originator, Utils.toArray(args.reference, 'base64'))
446
+ return { aborted: true }
447
+ }
448
+
449
+ async listActions(args: ListActionsArgs, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<ListActionsResult> {
450
+ const paramWriter = new Utils.Writer()
451
+
452
+ // Serialize labels
453
+ paramWriter.writeVarIntNum(args.labels.length)
454
+ for (const label of args.labels) {
455
+ const labelBytes = Utils.toArray(label, 'utf8')
456
+ paramWriter.writeVarIntNum(labelBytes.length)
457
+ paramWriter.write(labelBytes)
458
+ }
459
+
460
+ // Serialize labelQueryMode
461
+ if (args.labelQueryMode === 'any') {
462
+ paramWriter.writeInt8(1)
463
+ } else if (args.labelQueryMode === 'all') {
464
+ paramWriter.writeInt8(2)
465
+ } else {
466
+ paramWriter.writeInt8(-1)
467
+ }
468
+
469
+ // Serialize include options
470
+ const includeOptions = [
471
+ args.includeLabels,
472
+ args.includeInputs,
473
+ args.includeInputSourceLockingScripts,
474
+ args.includeInputUnlockingScripts,
475
+ args.includeOutputs,
476
+ args.includeOutputLockingScripts
477
+ ]
478
+ for (const option of includeOptions) {
479
+ if (typeof option === 'boolean') {
480
+ paramWriter.writeInt8(option ? 1 : 0)
481
+ } else {
482
+ paramWriter.writeInt8(-1)
483
+ }
484
+ }
485
+
486
+ // Serialize limit and offset
487
+ if (typeof args.limit === 'number') {
488
+ paramWriter.writeVarIntNum(args.limit)
489
+ } else {
490
+ paramWriter.writeVarIntNum(-1)
491
+ }
492
+ if (typeof args.offset === 'number') {
493
+ paramWriter.writeVarIntNum(args.offset)
494
+ } else {
495
+ paramWriter.writeVarIntNum(-1)
496
+ }
497
+
498
+ // Serialize seekPermission
499
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
500
+
501
+ // Transmit and parse response
502
+ const result = await this.transmit('listActions', originator, paramWriter.toArray())
503
+ const resultReader = new Utils.Reader(result)
504
+
505
+ const totalActions = resultReader.readVarIntNum()
506
+ const actions: Array<{
507
+ txid: TXIDHexString
508
+ satoshis: SatoshiValue
509
+ status: 'completed' | 'unprocessed' | 'sending' | 'unproven' | 'unsigned' | 'nosend' | 'nonfinal'
510
+ isOutgoing: boolean
511
+ description: DescriptionString5to50Bytes
512
+ labels?: LabelStringUnder300Bytes[]
513
+ version: PositiveIntegerOrZero
514
+ lockTime: PositiveIntegerOrZero
515
+ inputs?: Array<{
516
+ sourceOutpoint: OutpointString
517
+ sourceSatoshis: SatoshiValue
518
+ sourceLockingScript?: HexString
519
+ unlockingScript?: HexString
520
+ inputDescription: DescriptionString5to50Bytes
521
+ sequenceNumber: PositiveIntegerOrZero
522
+ }>
523
+ outputs?: Array<{
524
+ outputIndex: PositiveIntegerOrZero
525
+ satoshis: SatoshiValue
526
+ lockingScript?: HexString
527
+ spendable: boolean
528
+ outputDescription: DescriptionString5to50Bytes
529
+ basket: BasketStringUnder300Bytes
530
+ tags: OutputTagStringUnder300Bytes[]
531
+ customInstructions?: string
532
+ }>
533
+ }> = []
534
+
535
+ for (let i = 0; i < totalActions; i++) {
536
+ // Parse action fields
537
+ const txidBytes = resultReader.read(32)
538
+ const txid = Utils.toHex(txidBytes)
539
+
540
+ const satoshis = resultReader.readVarIntNum()
541
+
542
+ const statusCode = resultReader.readInt8()
543
+ let status: 'completed' | 'unprocessed' | 'sending' | 'unproven' | 'unsigned' | 'nosend' | 'nonfinal'
544
+ switch (statusCode) {
545
+ case 1:
546
+ status = 'completed'
547
+ break
548
+ case 2:
549
+ status = 'unprocessed'
550
+ break
551
+ case 3:
552
+ status = 'sending'
553
+ break
554
+ case 4:
555
+ status = 'unproven'
556
+ break
557
+ case 5:
558
+ status = 'unsigned'
559
+ break
560
+ case 6:
561
+ status = 'nosend'
562
+ break
563
+ case 7:
564
+ status = 'nonfinal'
565
+ break
566
+ default:
567
+ throw new Error(`Unknown status code: ${statusCode}`)
568
+ }
569
+
570
+ const isOutgoing = resultReader.readInt8() === 1
571
+
572
+ const descriptionLength = resultReader.readVarIntNum()
573
+ const descriptionBytes = resultReader.read(descriptionLength)
574
+ const description = Utils.toUTF8(descriptionBytes)
575
+
576
+ const action: any = {
577
+ txid,
578
+ satoshis,
579
+ status,
580
+ isOutgoing,
581
+ description,
582
+ version: 0,
583
+ lockTime: 0
584
+ }
585
+
586
+ // Parse labels
587
+ const labelsLength = resultReader.readVarIntNum()
588
+ if (labelsLength >= 0) {
589
+ action.labels = []
590
+ for (let j = 0; j < labelsLength; j++) {
591
+ const labelLength = resultReader.readVarIntNum()
592
+ const labelBytes = resultReader.read(labelLength)
593
+ action.labels.push(Utils.toUTF8(labelBytes))
594
+ }
595
+ }
596
+
597
+ // Parse version and lockTime
598
+ action.version = resultReader.readVarIntNum()
599
+ action.lockTime = resultReader.readVarIntNum()
600
+
601
+ // Parse inputs
602
+ const inputsLength = resultReader.readVarIntNum()
603
+ if (inputsLength >= 0) {
604
+ action.inputs = []
605
+ for (let k = 0; k < inputsLength; k++) {
606
+ const sourceOutpoint = this.readOutpoint(resultReader)
607
+ const sourceSatoshis = resultReader.readVarIntNum()
608
+
609
+ // sourceLockingScript
610
+ const sourceLockingScriptLength = resultReader.readVarIntNum()
611
+ let sourceLockingScript: string | undefined
612
+ if (sourceLockingScriptLength >= 0) {
613
+ const sourceLockingScriptBytes = resultReader.read(sourceLockingScriptLength)
614
+ sourceLockingScript = Utils.toHex(sourceLockingScriptBytes)
615
+ }
616
+
617
+ // unlockingScript
618
+ const unlockingScriptLength = resultReader.readVarIntNum()
619
+ let unlockingScript: string | undefined
620
+ if (unlockingScriptLength >= 0) {
621
+ const unlockingScriptBytes = resultReader.read(unlockingScriptLength)
622
+ unlockingScript = Utils.toHex(unlockingScriptBytes)
623
+ }
624
+
625
+ // inputDescription
626
+ const inputDescriptionLength = resultReader.readVarIntNum()
627
+ const inputDescriptionBytes = resultReader.read(inputDescriptionLength)
628
+ const inputDescription = Utils.toUTF8(inputDescriptionBytes)
629
+
630
+ // sequenceNumber
631
+ const sequenceNumber = resultReader.readVarIntNum()
632
+
633
+ action.inputs.push({
634
+ sourceOutpoint,
635
+ sourceSatoshis,
636
+ sourceLockingScript,
637
+ unlockingScript,
638
+ inputDescription,
639
+ sequenceNumber
640
+ })
641
+ }
642
+ }
643
+
644
+ // Parse outputs
645
+ const outputsLength = resultReader.readVarIntNum()
646
+ if (outputsLength >= 0) {
647
+ action.outputs = []
648
+ for (let l = 0; l < outputsLength; l++) {
649
+ const outputIndex = resultReader.readVarIntNum()
650
+ const satoshis = resultReader.readVarIntNum()
651
+
652
+ // lockingScript
653
+ const lockingScriptLength = resultReader.readVarIntNum()
654
+ let lockingScript: string | undefined
655
+ if (lockingScriptLength >= 0) {
656
+ const lockingScriptBytes = resultReader.read(lockingScriptLength)
657
+ lockingScript = Utils.toHex(lockingScriptBytes)
658
+ }
659
+
660
+ const spendable = resultReader.readInt8() === 1
661
+
662
+ // outputDescription
663
+ const outputDescriptionLength = resultReader.readVarIntNum()
664
+ const outputDescriptionBytes = resultReader.read(outputDescriptionLength)
665
+ const outputDescription = Utils.toUTF8(outputDescriptionBytes)
666
+
667
+ // basket
668
+ const basketLength = resultReader.readVarIntNum()
669
+ let basket: string | undefined
670
+ if (basketLength >= 0) {
671
+ const basketBytes = resultReader.read(basketLength)
672
+ basket = Utils.toUTF8(basketBytes)
673
+ }
674
+
675
+ // tags
676
+ const tagsLength = resultReader.readVarIntNum()
677
+ const tags: string[] = []
678
+ if (tagsLength >= 0) {
679
+ for (let m = 0; m < tagsLength; m++) {
680
+ const tagLength = resultReader.readVarIntNum()
681
+ const tagBytes = resultReader.read(tagLength)
682
+ tags.push(Utils.toUTF8(tagBytes))
683
+ }
684
+ }
685
+
686
+ // customInstructions
687
+ const customInstructionsLength = resultReader.readVarIntNum()
688
+ let customInstructions: string | undefined
689
+ if (customInstructionsLength >= 0) {
690
+ const customInstructionsBytes = resultReader.read(customInstructionsLength)
691
+ customInstructions = Utils.toUTF8(customInstructionsBytes)
692
+ }
693
+
694
+ action.outputs.push({
695
+ outputIndex,
696
+ satoshis,
697
+ lockingScript,
698
+ spendable,
699
+ outputDescription,
700
+ basket,
701
+ tags,
702
+ customInstructions
703
+ })
704
+ }
705
+ }
706
+
707
+ actions.push(action)
708
+ }
709
+
710
+ return {
711
+ totalActions,
712
+ actions
713
+ }
714
+ }
715
+
716
+ async internalizeAction(args: InternalizeActionArgs, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ accepted: true }> {
717
+ const paramWriter = new Utils.Writer()
718
+ paramWriter.writeVarIntNum(args.tx.length)
719
+ paramWriter.write(args.tx)
720
+ paramWriter.writeVarIntNum(args.outputs.length)
721
+ for (const out of args.outputs) {
722
+ paramWriter.writeVarIntNum(out.outputIndex)
723
+ if (out.protocol === 'wallet payment') {
724
+ paramWriter.writeUInt8(1)
725
+ paramWriter.write(Utils.toArray(out.paymentRemittance.senderIdentityKey, 'hex'))
726
+ const derivationPrefixAsArray = Utils.toArray(out.paymentRemittance.derivationPrefix, 'base64')
727
+ paramWriter.writeVarIntNum(derivationPrefixAsArray.length)
728
+ paramWriter.write(derivationPrefixAsArray)
729
+ const derivationSuffixAsArray = Utils.toArray(out.paymentRemittance.derivationSuffix, 'base64')
730
+ paramWriter.writeVarIntNum(derivationSuffixAsArray.length)
731
+ paramWriter.write(derivationSuffixAsArray)
732
+ } else {
733
+ paramWriter.writeUInt8(2)
734
+ const basketAsArray = Utils.toArray(out.insertionRemittance.basket, 'utf8')
735
+ paramWriter.writeVarIntNum(basketAsArray.length)
736
+ paramWriter.write(basketAsArray)
737
+ if (typeof out.insertionRemittance.customInstructions) {
738
+ const customInstructionsAsArray = Utils.toArray(out.insertionRemittance.customInstructions, 'utf8')
739
+ paramWriter.writeVarIntNum(customInstructionsAsArray.length)
740
+ paramWriter.write(customInstructionsAsArray)
741
+ } else {
742
+ paramWriter.writeVarIntNum(-1)
743
+ }
744
+ if (typeof out.insertionRemittance.tags === 'object') {
745
+ paramWriter.writeVarIntNum(out.insertionRemittance.tags.length)
746
+ for (const tag of out.insertionRemittance.tags) {
747
+ const tagAsArray = Utils.toArray(tag, 'utf8')
748
+ paramWriter.writeVarIntNum(tagAsArray.length)
749
+ paramWriter.write(tagAsArray)
750
+ }
751
+ } else {
752
+ paramWriter.writeVarIntNum(0)
753
+ }
754
+ }
755
+ }
756
+ if (typeof args.labels === 'object') {
757
+ paramWriter.writeVarIntNum(args.labels.length)
758
+ for (const l of args.labels) {
759
+ const labelAsArray = Utils.toArray(l, 'utf8')
760
+ paramWriter.writeVarIntNum(labelAsArray.length)
761
+ paramWriter.write(labelAsArray)
762
+ }
763
+ } else {
764
+ paramWriter.writeVarIntNum(-1)
765
+ }
766
+ const descriptionAsArray = Utils.toArray(args.description)
767
+ paramWriter.writeVarIntNum(descriptionAsArray.length)
768
+ paramWriter.write(descriptionAsArray)
769
+
770
+ // Serialize seekPermission
771
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
772
+
773
+ await this.transmit('internalizeAction', originator, paramWriter.toArray())
774
+ return { accepted: true }
775
+ }
776
+
777
+ async listOutputs(args: ListOutputsArgs, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<ListOutputsResult> {
778
+ const paramWriter = new Utils.Writer()
779
+ const basketAsArray = Utils.toArray(args.basket, 'utf8')
780
+ paramWriter.writeVarIntNum(basketAsArray.length)
781
+ paramWriter.write(basketAsArray)
782
+ if (typeof args.tags === 'object') {
783
+ paramWriter.writeVarIntNum(args.tags.length)
784
+ for (const tag of args.tags) {
785
+ const tagAsArray = Utils.toArray(tag, 'utf8')
786
+ paramWriter.writeVarIntNum(tagAsArray.length)
787
+ paramWriter.write(tagAsArray)
788
+ }
789
+ } else {
790
+ paramWriter.writeVarIntNum(0)
791
+ }
792
+ if (args.tagQueryMode === 'all') {
793
+ paramWriter.writeInt8(1)
794
+ } else if (args.tagQueryMode === 'any') {
795
+ paramWriter.writeInt8(2)
796
+ } else {
797
+ paramWriter.writeInt8(-1)
798
+ }
799
+ if (args.include === 'locking scripts') {
800
+ paramWriter.writeInt8(1)
801
+ } else if (args.include === 'entire transactions') {
802
+ paramWriter.writeInt8(2)
803
+ } else {
804
+ paramWriter.writeInt8(-1)
805
+ }
806
+ if (typeof args.includeCustomInstructions === 'boolean') {
807
+ paramWriter.writeInt8(args.includeCustomInstructions ? 1 : 0)
808
+ } else {
809
+ paramWriter.writeInt8(-1)
810
+ }
811
+ if (typeof args.includeTags === 'boolean') {
812
+ paramWriter.writeInt8(args.includeTags ? 1 : 0)
813
+ } else {
814
+ paramWriter.writeInt8(-1)
815
+ }
816
+ if (typeof args.includeLabels === 'boolean') {
817
+ paramWriter.writeInt8(args.includeLabels ? 1 : 0)
818
+ } else {
819
+ paramWriter.writeInt8(-1)
820
+ }
821
+ if (typeof args.limit === 'number') {
822
+ paramWriter.writeVarIntNum(args.limit)
823
+ } else {
824
+ paramWriter.writeVarIntNum(-1)
825
+ }
826
+ if (typeof args.offset === 'number') {
827
+ paramWriter.writeVarIntNum(args.offset)
828
+ } else {
829
+ paramWriter.writeVarIntNum(-1)
830
+ }
831
+
832
+ // Serialize seekPermission
833
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
834
+
835
+ const result = await this.transmit('listOutputs', originator, paramWriter.toArray())
836
+ const resultReader = new Utils.Reader(result)
837
+ const totalOutputs = resultReader.readVarIntNum()
838
+ const beefLength = resultReader.readVarIntNum()
839
+ let BEEF = undefined
840
+ if (beefLength >= 0) {
841
+ BEEF = resultReader.read(beefLength)
842
+ }
843
+ const outputs: Array<{ outpoint: OutpointString, satoshis: SatoshiValue, lockingScript?: HexString, tx?: BEEF, spendable: true, customInstructions?: string, tags?: OutputTagStringUnder300Bytes[], labels?: LabelStringUnder300Bytes[] }> = []
844
+ for (let i = 0; i < totalOutputs; i++) {
845
+ const outpoint = this.readOutpoint(resultReader)
846
+ const satoshis = resultReader.readVarIntNum()
847
+ const output: { outpoint: OutpointString, satoshis: SatoshiValue, lockingScript?: HexString, tx?: BEEF, spendable: true, customInstructions?: string, tags?: OutputTagStringUnder300Bytes[], labels?: LabelStringUnder300Bytes[] } = {
848
+ spendable: true,
849
+ outpoint,
850
+ satoshis
851
+ }
852
+ const scriptLength = resultReader.readVarIntNum()
853
+ if (scriptLength >= 0) {
854
+ output.lockingScript = Utils.toHex(resultReader.read(scriptLength))
855
+ }
856
+ const customInstructionsLength = resultReader.readVarIntNum()
857
+ if (customInstructionsLength >= 0) {
858
+ output.customInstructions = Utils.toUTF8(resultReader.read(customInstructionsLength))
859
+ }
860
+ const tagsLength = resultReader.readVarIntNum()
861
+ if (tagsLength !== -1) {
862
+ const tags: OutputTagStringUnder300Bytes[] = []
863
+ for (let i = 0; i < tagsLength; i++) {
864
+ const tagLength = resultReader.readVarIntNum()
865
+ tags.push(Utils.toUTF8(resultReader.read(tagLength)))
866
+ }
867
+ output.tags = tags
868
+ }
869
+ const labelsLength = resultReader.readVarIntNum()
870
+ if (labelsLength !== -1) {
871
+ const labels: LabelStringUnder300Bytes[] = []
872
+ for (let i = 0; i < labelsLength; i++) {
873
+ const labelLength = resultReader.readVarIntNum()
874
+ labels.push(Utils.toUTF8(resultReader.read(labelLength)))
875
+ }
876
+ output.labels = labels
877
+ }
878
+ outputs.push(output)
879
+ }
880
+ return {
881
+ totalOutputs,
882
+ BEEF,
883
+ outputs
884
+ }
885
+ }
886
+
887
+ async relinquishOutput(args: { basket: BasketStringUnder300Bytes, output: OutpointString }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ relinquished: true }> {
888
+ const paramWriter = new Utils.Writer()
889
+ const basketAsArray = Utils.toArray(args.basket, 'utf8')
890
+ paramWriter.writeVarIntNum(basketAsArray.length)
891
+ paramWriter.write(basketAsArray)
892
+ paramWriter.write(this.encodeOutpoint(args.output))
893
+ await this.transmit('relinquishOutput', originator, paramWriter.toArray())
894
+ return { relinquished: true }
895
+ }
896
+
897
+ private encodeOutpoint(outpoint: OutpointString): number[] {
898
+ const writer = new Utils.Writer()
899
+ const [txid, index] = outpoint.split('.')
900
+ writer.write(Utils.toArray(txid, 'hex'))
901
+ writer.writeVarIntNum(Number(index))
902
+ return writer.toArray()
903
+ }
904
+
905
+ private readOutpoint(reader: Utils.Reader): OutpointString {
906
+ const txid = Utils.toHex(reader.read(32))
907
+ const index = reader.readVarIntNum()
908
+ return `${txid}.${index}`
909
+ }
910
+
911
+ async getPublicKey(args: { seekPermission?: BooleanDefaultTrue, identityKey?: true, protocolID?: [0 | 1 | 2, ProtocolString5To400Bytes], keyID?: KeyIDStringUnder800Bytes, privileged?: BooleanDefaultFalse, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', forSelf?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ publicKey: PubKeyHex }> {
912
+ const paramWriter = new Utils.Writer()
913
+ paramWriter.writeUInt8(args.identityKey ? 1 : 0)
914
+ if (!args.identityKey) {
915
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
916
+ if (typeof args.forSelf === 'boolean') {
917
+ paramWriter.writeInt8(args.forSelf ? 1 : 0)
918
+ } else {
919
+ paramWriter.writeInt8(-1)
920
+ }
921
+ } else {
922
+ paramWriter.write(this.encodePrivilegedParams(args.privileged, args.privilegedReason))
923
+ }
924
+
925
+ // Serialize seekPermission
926
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
927
+
928
+ const result = await this.transmit('getPublicKey', originator, paramWriter.toArray())
929
+ return {
930
+ publicKey: Utils.toHex(result)
931
+ }
932
+ }
933
+
934
+ async revealCounterpartyKeyLinkage(args: { counterparty: PubKeyHex, verifier: PubKeyHex, privilegedReason?: DescriptionString5to50Bytes, privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ prover: PubKeyHex, verifier: PubKeyHex, counterparty: PubKeyHex, revelationTime: ISOTimestampString, encryptedLinkage: Byte[], encryptedLinkageProof: number[] }> {
935
+ const paramWriter = new Utils.Writer()
936
+ paramWriter.write(this.encodePrivilegedParams(args.privileged, args.privilegedReason))
937
+ paramWriter.write(Utils.toArray(args.counterparty, 'hex'))
938
+ paramWriter.write(Utils.toArray(args.verifier, 'hex'))
939
+ const result = await this.transmit('revealCounterpartyKeyLinkage', originator, paramWriter.toArray())
940
+ const resultReader = new Utils.Reader(result)
941
+ const prover = Utils.toHex(resultReader.read(33))
942
+ const verifier = Utils.toHex(resultReader.read(33))
943
+ const counterparty = Utils.toHex(resultReader.read(33))
944
+ const revelationTimeLength = resultReader.readVarIntNum()
945
+ const revelationTime = Utils.toUTF8(resultReader.read(revelationTimeLength))
946
+ const encryptedLinkageLength = resultReader.readVarIntNum()
947
+ const encryptedLinkage = resultReader.read(encryptedLinkageLength)
948
+ const encryptedLinkageProofLength = resultReader.readVarIntNum()
949
+ const encryptedLinkageProof = resultReader.read(encryptedLinkageProofLength)
950
+ return {
951
+ prover,
952
+ verifier,
953
+ counterparty,
954
+ revelationTime,
955
+ encryptedLinkage,
956
+ encryptedLinkageProof
957
+ }
958
+ }
959
+
960
+ async revealSpecificKeyLinkage(args: { counterparty: PubKeyHex, verifier: PubKeyHex, protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ prover: PubKeyHex, verifier: PubKeyHex, counterparty: PubKeyHex, protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, encryptedLinkage: Byte[], encryptedLinkageProof: Byte[], proofType: Byte }> {
961
+ const paramWriter = new Utils.Writer()
962
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
963
+ paramWriter.write(Utils.toArray(args.verifier, 'hex'))
964
+ const result = await this.transmit('revealSpecificKeyLinkage', originator, paramWriter.toArray())
965
+ const resultReader = new Utils.Reader(result)
966
+ const prover = Utils.toHex(resultReader.read(33))
967
+ const verifier = Utils.toHex(resultReader.read(33))
968
+ const counterparty = Utils.toHex(resultReader.read(33))
969
+ const securityLevel = resultReader.readUInt8()
970
+ const protocolLength = resultReader.readVarIntNum()
971
+ const protocol = Utils.toUTF8(resultReader.read(protocolLength))
972
+ const keyIDLength = resultReader.readVarIntNum()
973
+ const keyID = Utils.toUTF8(resultReader.read(keyIDLength))
974
+ const encryptedLinkageLength = resultReader.readVarIntNum()
975
+ const encryptedLinkage = resultReader.read(encryptedLinkageLength)
976
+ const encryptedLinkageProofLength = resultReader.readVarIntNum()
977
+ const encryptedLinkageProof = resultReader.read(encryptedLinkageProofLength)
978
+ const proofType = resultReader.readUInt8()
979
+ return {
980
+ prover,
981
+ verifier,
982
+ counterparty,
983
+ protocolID: [securityLevel as 0 | 1 | 2, protocol],
984
+ keyID,
985
+ encryptedLinkage,
986
+ encryptedLinkageProof,
987
+ proofType
988
+ }
989
+ }
990
+
991
+ async encrypt(args: { seekPermission?: BooleanDefaultTrue, plaintext: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ ciphertext: Byte[] }> {
992
+ const paramWriter = new Utils.Writer()
993
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
994
+ paramWriter.writeVarIntNum(args.plaintext.length)
995
+ paramWriter.write(args.plaintext)
996
+ // Serialize seekPermission
997
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
998
+ return {
999
+ ciphertext: await this.transmit('encrypt', originator, paramWriter.toArray())
1000
+ }
1001
+ }
1002
+
1003
+ async decrypt(args: { seekPermission?: BooleanDefaultTrue, ciphertext: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ plaintext: Byte[] }> {
1004
+ const paramWriter = new Utils.Writer()
1005
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
1006
+ paramWriter.writeVarIntNum(args.ciphertext.length)
1007
+ paramWriter.write(args.ciphertext)
1008
+ // Serialize seekPermission
1009
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1010
+ return {
1011
+ plaintext: await this.transmit('decrypt', originator, paramWriter.toArray())
1012
+ }
1013
+ }
1014
+
1015
+ async createHmac(args: { seekPermission?: BooleanDefaultTrue, data: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ hmac: Byte[] }> {
1016
+ const paramWriter = new Utils.Writer()
1017
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
1018
+ paramWriter.writeVarIntNum(args.data.length)
1019
+ paramWriter.write(args.data)
1020
+ // Serialize seekPermission
1021
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1022
+ return {
1023
+ hmac: await this.transmit('createHmac', originator, paramWriter.toArray())
1024
+ }
1025
+ }
1026
+
1027
+ async verifyHmac(args: { seekPermission?: BooleanDefaultTrue, data: Byte[], hmac: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ valid: true }> {
1028
+ const paramWriter = new Utils.Writer()
1029
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
1030
+ paramWriter.write(args.hmac)
1031
+ paramWriter.writeVarIntNum(args.data.length)
1032
+ paramWriter.write(args.data)
1033
+ // Serialize seekPermission
1034
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1035
+ await this.transmit('verifyHmac', originator, paramWriter.toArray())
1036
+ return { valid: true }
1037
+ }
1038
+
1039
+ async createSignature(args: { seekPermission?: BooleanDefaultTrue, data?: Byte[], hashToDirectlySign?: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ signature: Byte[] }> {
1040
+ const paramWriter = new Utils.Writer()
1041
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
1042
+ if (typeof args.data === 'object') {
1043
+ paramWriter.writeUInt8(1)
1044
+ paramWriter.writeVarIntNum(args.data.length)
1045
+ paramWriter.write(args.data)
1046
+ } else {
1047
+ paramWriter.writeUInt8(2)
1048
+ paramWriter.write(args.hashToDirectlySign)
1049
+ }
1050
+ // Serialize seekPermission
1051
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1052
+ return {
1053
+ signature: await this.transmit('createSignature', originator, paramWriter.toArray())
1054
+ }
1055
+ }
1056
+
1057
+ async verifySignature(args: { seekPermission?: BooleanDefaultTrue, data?: Byte[], hashToDirectlyVerify?: Byte[], signature: Byte[], protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, privilegedReason?: DescriptionString5to50Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', forSelf?: BooleanDefaultFalse, privileged?: BooleanDefaultFalse }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ valid: true }> {
1058
+ const paramWriter = new Utils.Writer()
1059
+ paramWriter.write(this.encodeKeyRelatedParams(args.protocolID, args.keyID, args.counterparty, args.privileged, args.privilegedReason))
1060
+ if (typeof args.forSelf === 'boolean') {
1061
+ paramWriter.writeInt8(args.forSelf ? 1 : 0)
1062
+ } else {
1063
+ paramWriter.writeInt8(-1)
1064
+ }
1065
+ paramWriter.writeVarIntNum(args.signature.length)
1066
+ paramWriter.write(args.signature)
1067
+ if (typeof args.data === 'object') {
1068
+ paramWriter.writeUInt8(1)
1069
+ paramWriter.writeVarIntNum(args.data.length)
1070
+ paramWriter.write(args.data)
1071
+ } else {
1072
+ paramWriter.writeUInt8(2)
1073
+ paramWriter.write(args.hashToDirectlyVerify)
1074
+ }
1075
+ // Serialize seekPermission
1076
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1077
+ await this.transmit('verifySignature', originator, paramWriter.toArray())
1078
+ return { valid: true }
1079
+ }
1080
+
1081
+ private encodeKeyRelatedParams(protocolID: [0 | 1 | 2, ProtocolString5To400Bytes], keyID: KeyIDStringUnder800Bytes, counterparty?: PubKeyHex | 'self' | 'anyone', privileged?: boolean, privilegedReason?: string): number[] {
1082
+ const paramWriter = new Utils.Writer()
1083
+ paramWriter.writeUInt8(protocolID[0])
1084
+ const protocolAsArray = Utils.toArray(protocolID[1], 'utf8')
1085
+ paramWriter.writeVarIntNum(protocolAsArray.length)
1086
+ paramWriter.write(protocolAsArray)
1087
+ const keyIDAsArray = Utils.toArray(keyID, 'utf8')
1088
+ paramWriter.writeVarIntNum(keyIDAsArray.length)
1089
+ paramWriter.write(keyIDAsArray)
1090
+ if (typeof counterparty !== 'string') {
1091
+ paramWriter.writeUInt8(0)
1092
+ } else if (counterparty === 'self') {
1093
+ paramWriter.writeUInt8(11)
1094
+ } else if (counterparty === 'anyone') {
1095
+ paramWriter.writeUInt8(12)
1096
+ } else {
1097
+ paramWriter.write(Utils.toArray(counterparty, 'hex'))
1098
+ }
1099
+ paramWriter.write(this.encodePrivilegedParams(privileged, privilegedReason))
1100
+ return paramWriter.toArray()
1101
+ }
1102
+
1103
+ async acquireCertificate(
1104
+ args: AcquireCertificateArgs,
1105
+ originator?: OriginatorDomainNameStringUnder250Bytes
1106
+ ): Promise<AcquireCertificateResult> {
1107
+ const paramWriter = new Utils.Writer()
1108
+ paramWriter.write(Utils.toArray(args.type, 'base64'))
1109
+ paramWriter.write(Utils.toArray(args.certifier, 'hex'))
1110
+
1111
+ const fieldEntries = Object.entries(args.fields)
1112
+ paramWriter.writeVarIntNum(fieldEntries.length)
1113
+ for (const [key, value] of fieldEntries) {
1114
+ const keyAsArray = Utils.toArray(key, 'utf8')
1115
+ const valueAsArray = Utils.toArray(value, 'utf8')
1116
+
1117
+ paramWriter.writeVarIntNum(keyAsArray.length)
1118
+ paramWriter.write(keyAsArray)
1119
+
1120
+ paramWriter.writeVarIntNum(valueAsArray.length)
1121
+ paramWriter.write(valueAsArray)
1122
+ }
1123
+
1124
+ paramWriter.write(this.encodePrivilegedParams(args.privileged, args.privilegedReason))
1125
+ paramWriter.writeUInt8(args.acquisitionProtocol === 'direct' ? 1 : 2)
1126
+
1127
+ if (args.acquisitionProtocol === 'direct') {
1128
+ paramWriter.write(Utils.toArray(args.serialNumber, 'base64'))
1129
+ paramWriter.write(this.encodeOutpoint(args.revocationOutpoint))
1130
+ const signatureAsArray = Utils.toArray(args.signature, 'hex')
1131
+ paramWriter.writeVarIntNum(signatureAsArray.length)
1132
+ paramWriter.write(signatureAsArray)
1133
+
1134
+ const keyringRevealerAsArray = args.keyringRevealer !== 'certifier'
1135
+ ? Utils.toArray(args.keyringRevealer, 'hex')
1136
+ : [11]
1137
+ paramWriter.write(keyringRevealerAsArray)
1138
+
1139
+ const keyringKeys = Object.keys(args.keyringForSubject)
1140
+ paramWriter.writeVarIntNum(keyringKeys.length)
1141
+ for (let i = 0; i < keyringKeys.length; i++) {
1142
+ const keyringKeysAsArray = Utils.toArray(keyringKeys[i], 'utf8')
1143
+ paramWriter.writeVarIntNum(keyringKeysAsArray.length)
1144
+ paramWriter.write(keyringKeysAsArray)
1145
+ const keyringForSubjectAsArray = Utils.toArray(args.keyringForSubject[keyringKeys[i]], 'base64')
1146
+ paramWriter.writeVarIntNum(keyringForSubjectAsArray.length)
1147
+ paramWriter.write(keyringForSubjectAsArray)
1148
+ }
1149
+ } else {
1150
+ const certifierUrlAsArray = Utils.toArray(args.certifierUrl, 'utf8')
1151
+ paramWriter.writeVarIntNum(certifierUrlAsArray.length)
1152
+ paramWriter.write(certifierUrlAsArray)
1153
+ }
1154
+
1155
+ const result = await this.transmit('acquireCertificate', originator, paramWriter.toArray())
1156
+ const cert = Certificate.fromBin(result)
1157
+ return {
1158
+ ...cert,
1159
+ signature: cert.signature as string
1160
+ }
1161
+ }
1162
+
1163
+ private encodePrivilegedParams(privileged?: boolean, privilegedReason?: string): number[] {
1164
+ const paramWriter = new Utils.Writer()
1165
+ if (typeof privileged === 'boolean') {
1166
+ paramWriter.writeInt8(privileged ? 1 : 0)
1167
+ } else {
1168
+ paramWriter.writeInt8(-1)
1169
+ }
1170
+ if (typeof privilegedReason === 'string') {
1171
+ const privilegedReasonAsArray = Utils.toArray(privilegedReason, 'utf8')
1172
+ paramWriter.writeInt8(privilegedReasonAsArray.length)
1173
+ paramWriter.write(privilegedReasonAsArray)
1174
+ } else {
1175
+ paramWriter.writeInt8(-1)
1176
+ }
1177
+ return paramWriter.toArray()
1178
+ }
1179
+
1180
+ async listCertificates(args: { certifiers: PubKeyHex[], types: Base64String[], limit?: PositiveIntegerDefault10Max10000, offset?: PositiveIntegerOrZero, privileged?: BooleanDefaultFalse, privilegedReason?: DescriptionString5to50Bytes }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<ListCertificatesResult> {
1181
+ const paramWriter = new Utils.Writer()
1182
+ paramWriter.writeVarIntNum(args.certifiers.length)
1183
+ for (let i = 0; i < args.certifiers.length; i++) {
1184
+ paramWriter.write(Utils.toArray(args.certifiers[i], 'hex'))
1185
+ }
1186
+
1187
+ paramWriter.writeVarIntNum(args.types.length)
1188
+ for (let i = 0; i < args.types.length; i++) {
1189
+ paramWriter.write(Utils.toArray(args.types[i], 'base64'))
1190
+ }
1191
+ if (typeof args.limit === 'number') {
1192
+ paramWriter.writeVarIntNum(args.limit)
1193
+ } else {
1194
+ paramWriter.writeVarIntNum(-1)
1195
+ }
1196
+ if (typeof args.offset === 'number') {
1197
+ paramWriter.writeVarIntNum(args.offset)
1198
+ } else {
1199
+ paramWriter.writeVarIntNum(-1)
1200
+ }
1201
+ paramWriter.write(this.encodePrivilegedParams(args.privileged, args.privilegedReason))
1202
+ const result = await this.transmit('listCertificates', originator, paramWriter.toArray())
1203
+ const resultReader = new Utils.Reader(result)
1204
+ const totalCertificates = resultReader.readVarIntNum()
1205
+ const certificates: Array<{
1206
+ type: Base64String
1207
+ subject: PubKeyHex
1208
+ serialNumber: Base64String
1209
+ certifier: PubKeyHex
1210
+ revocationOutpoint: OutpointString
1211
+ signature: HexString
1212
+ fields: Record<CertificateFieldNameUnder50Bytes, Base64String>
1213
+ }> = []
1214
+ for (let i = 0; i < totalCertificates; i++) {
1215
+ const certificateLength = resultReader.readVarIntNum()
1216
+ const certificateBin = resultReader.read(certificateLength)
1217
+ const cert = Certificate.fromBin(certificateBin)
1218
+ certificates.push({
1219
+ ...cert,
1220
+ signature: cert.signature as string
1221
+ })
1222
+ }
1223
+ return {
1224
+ totalCertificates,
1225
+ certificates
1226
+ }
1227
+ }
1228
+
1229
+ async proveCertificate(args: ProveCertificateArgs, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<ProveCertificateResult> {
1230
+ const paramWriter = new Utils.Writer()
1231
+ const typeAsArray = Utils.toArray(args.certificate.type, 'base64')
1232
+ paramWriter.write(typeAsArray)
1233
+ const subjectAsArray = Utils.toArray(args.certificate.subject, 'hex')
1234
+ paramWriter.write(subjectAsArray)
1235
+ const serialNumberAsArray = Utils.toArray(args.certificate.serialNumber, 'base64')
1236
+ paramWriter.write(serialNumberAsArray)
1237
+ const certifierAsArray = Utils.toArray(args.certificate.certifier, 'hex')
1238
+ paramWriter.write(certifierAsArray)
1239
+ const revocationOutpointAsArray = this.encodeOutpoint(args.certificate.revocationOutpoint)
1240
+ paramWriter.write(revocationOutpointAsArray)
1241
+ const signatureAsArray = Utils.toArray(args.certificate.signature, 'hex')
1242
+ paramWriter.writeVarIntNum(signatureAsArray.length)
1243
+ paramWriter.write(signatureAsArray)
1244
+ const fieldEntries = Object.entries(args.certificate.fields)
1245
+ paramWriter.writeVarIntNum(fieldEntries.length)
1246
+ for (const [key, value] of fieldEntries) {
1247
+ const keyAsArray = Utils.toArray(key, 'utf8')
1248
+ const valueAsArray = Utils.toArray(value, 'utf8')
1249
+ paramWriter.writeVarIntNum(keyAsArray.length)
1250
+ paramWriter.write(keyAsArray)
1251
+ paramWriter.writeVarIntNum(valueAsArray.length)
1252
+ paramWriter.write(valueAsArray)
1253
+ }
1254
+ paramWriter.writeVarIntNum(args.fieldsToReveal.length)
1255
+ for (const field of args.fieldsToReveal) {
1256
+ const fieldAsArray = Utils.toArray(field, 'utf8')
1257
+ paramWriter.writeVarIntNum(fieldAsArray.length)
1258
+ paramWriter.write(fieldAsArray)
1259
+ }
1260
+ paramWriter.write(Utils.toArray(args.verifier, 'hex'))
1261
+ paramWriter.write(this.encodePrivilegedParams(args.privileged, args.privilegedReason))
1262
+ const result = await this.transmit('proveCertificate', originator, paramWriter.toArray())
1263
+ const resultReader = new Utils.Reader(result)
1264
+ const numFields = resultReader.readVarIntNum()
1265
+ const keyringForVerifier: Record<string, string> = {}
1266
+ for (let i = 0; i < numFields; i++) {
1267
+ const fieldKeyLength = resultReader.readVarIntNum()
1268
+ const fieldKey = Utils.toUTF8(resultReader.read(fieldKeyLength))
1269
+ const fieldValueLength = resultReader.readVarIntNum()
1270
+ keyringForVerifier[fieldKey] = Utils.toBase64(resultReader.read(fieldValueLength))
1271
+ }
1272
+ return {
1273
+ keyringForVerifier
1274
+ }
1275
+ }
1276
+
1277
+ async relinquishCertificate(args: { type: Base64String, serialNumber: Base64String, certifier: PubKeyHex }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ relinquished: true }> {
1278
+ const paramWriter = new Utils.Writer()
1279
+ const typeAsArray = Utils.toArray(args.type, 'base64')
1280
+ paramWriter.write(typeAsArray)
1281
+ const serialNumberAsArray = Utils.toArray(args.serialNumber, 'base64')
1282
+ paramWriter.write(serialNumberAsArray)
1283
+ const certifierAsArray = Utils.toArray(args.certifier, 'hex')
1284
+ paramWriter.write(certifierAsArray)
1285
+ await this.transmit('relinquishCertificate', originator, paramWriter.toArray())
1286
+ return { relinquished: true }
1287
+ }
1288
+
1289
+ private parseDiscoveryResult(result: number[]): {
1290
+ totalCertificates: number
1291
+ certificates: Array<{
1292
+ type: Base64String
1293
+ subject: PubKeyHex
1294
+ serialNumber: Base64String
1295
+ certifier: PubKeyHex
1296
+ revocationOutpoint: OutpointString
1297
+ signature: HexString
1298
+ fields: Record<CertificateFieldNameUnder50Bytes, Base64String>
1299
+ certifierInfo: {
1300
+ name: EntityNameStringMax100Bytes
1301
+ iconUrl: EntityIconURLStringMax500Bytes
1302
+ description: DescriptionString5to50Bytes
1303
+ trust: PositiveIntegerMax10
1304
+ }
1305
+ publiclyRevealedKeyring: Record<CertificateFieldNameUnder50Bytes, Base64String>
1306
+ decryptedFields: Record<CertificateFieldNameUnder50Bytes, string>
1307
+ }>
1308
+ } {
1309
+ const resultReader = new Utils.Reader(result)
1310
+ const totalCertificates = resultReader.readVarIntNum()
1311
+ const certificates: Array<{
1312
+ type: Base64String
1313
+ subject: PubKeyHex
1314
+ serialNumber: Base64String
1315
+ certifier: PubKeyHex
1316
+ revocationOutpoint: OutpointString
1317
+ signature: HexString
1318
+ fields: Record<CertificateFieldNameUnder50Bytes, Base64String>
1319
+ certifierInfo: {
1320
+ name: EntityNameStringMax100Bytes
1321
+ iconUrl: EntityIconURLStringMax500Bytes
1322
+ description: DescriptionString5to50Bytes
1323
+ trust: PositiveIntegerMax10
1324
+ }
1325
+ publiclyRevealedKeyring: Record<CertificateFieldNameUnder50Bytes, Base64String>
1326
+ decryptedFields: Record<CertificateFieldNameUnder50Bytes, string>
1327
+ }> = []
1328
+ for (let i = 0; i < totalCertificates; i++) {
1329
+ const certBinLen = resultReader.readVarIntNum()
1330
+ const certBin = resultReader.read(certBinLen)
1331
+ const cert = Certificate.fromBin(certBin)
1332
+ const nameLength = resultReader.readVarIntNum()
1333
+ const name = Utils.toUTF8(resultReader.read(nameLength))
1334
+ const iconUrlLength = resultReader.readVarIntNum()
1335
+ const iconUrl = Utils.toUTF8(resultReader.read(iconUrlLength))
1336
+ const descriptionLength = resultReader.readVarIntNum()
1337
+ const description = Utils.toUTF8(resultReader.read(descriptionLength))
1338
+ const trust = resultReader.readUInt8()
1339
+ const publiclyRevealedKeyring = {}
1340
+ const numPublicKeyringEntries = resultReader.readVarIntNum()
1341
+ for (let j = 0; j < numPublicKeyringEntries; j++) {
1342
+ const fieldKeyLen = resultReader.readVarIntNum()
1343
+ const fieldKey = Utils.toUTF8(resultReader.read(fieldKeyLen))
1344
+ const fieldValueLen = resultReader.readVarIntNum()
1345
+ publiclyRevealedKeyring[fieldKey] = resultReader.read(fieldValueLen)
1346
+ }
1347
+ const decryptedFields = {}
1348
+ const numDecryptedFields = resultReader.readVarIntNum()
1349
+ for (let k = 0; k < numDecryptedFields; k++) {
1350
+ const fieldKeyLen = resultReader.readVarIntNum()
1351
+ const fieldKey = Utils.toUTF8(resultReader.read(fieldKeyLen))
1352
+ const fieldValueLen = resultReader.readVarIntNum()
1353
+ decryptedFields[fieldKey] = Utils.toUTF8(resultReader.read(fieldValueLen))
1354
+ }
1355
+ certificates.push({
1356
+ ...cert,
1357
+ signature: cert.signature as string,
1358
+ certifierInfo: { iconUrl, name, description, trust },
1359
+ publiclyRevealedKeyring,
1360
+ decryptedFields
1361
+ })
1362
+ }
1363
+ return {
1364
+ totalCertificates,
1365
+ certificates
1366
+ }
1367
+ }
1368
+
1369
+ async discoverByIdentityKey(args: { seekPermission?: BooleanDefaultTrue, identityKey: PubKeyHex, limit?: PositiveIntegerDefault10Max10000, offset?: PositiveIntegerOrZero }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<DiscoverCertificatesResult> {
1370
+ const paramWriter = new Utils.Writer()
1371
+ paramWriter.write(Utils.toArray(args.identityKey, 'hex'))
1372
+ if (typeof args.limit === 'number') {
1373
+ paramWriter.writeVarIntNum(args.limit)
1374
+ } else {
1375
+ paramWriter.writeVarIntNum(-1)
1376
+ }
1377
+ if (typeof args.offset === 'number') {
1378
+ paramWriter.writeVarIntNum(args.offset)
1379
+ } else {
1380
+ paramWriter.writeVarIntNum(-1)
1381
+ }
1382
+ // Serialize seekPermission
1383
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1384
+ const result = await this.transmit('discoverByIdentityKey', originator, paramWriter.toArray())
1385
+ return this.parseDiscoveryResult(result)
1386
+ }
1387
+
1388
+ async discoverByAttributes(args: { seekPermission?: BooleanDefaultTrue, attributes: Record<CertificateFieldNameUnder50Bytes, string>, limit?: PositiveIntegerDefault10Max10000, offset?: PositiveIntegerOrZero }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<DiscoverCertificatesResult> {
1389
+ const paramWriter = new Utils.Writer()
1390
+ const attributeKeys = Object.keys(args.attributes)
1391
+ paramWriter.writeVarIntNum(attributeKeys.length)
1392
+ for (let i = 0; i < attributeKeys.length; i++) {
1393
+ paramWriter.writeVarIntNum(attributeKeys[i].length)
1394
+ paramWriter.write(Utils.toArray(attributeKeys[i], 'utf8'))
1395
+ paramWriter.writeVarIntNum(args.attributes[attributeKeys[i]].length)
1396
+ paramWriter.write(Utils.toArray(args.attributes[attributeKeys[i]], 'utf8'))
1397
+ }
1398
+ if (typeof args.limit === 'number') {
1399
+ paramWriter.writeVarIntNum(args.limit)
1400
+ } else {
1401
+ paramWriter.writeVarIntNum(-1)
1402
+ }
1403
+ if (typeof args.offset === 'number') {
1404
+ paramWriter.writeVarIntNum(args.offset)
1405
+ } else {
1406
+ paramWriter.writeVarIntNum(-1)
1407
+ }
1408
+ // Serialize seekPermission
1409
+ paramWriter.writeInt8(typeof args.seekPermission === 'boolean' ? args.seekPermission ? 1 : 0 : -1)
1410
+ const result = await this.transmit('discoverByAttributes', originator, paramWriter.toArray())
1411
+ return this.parseDiscoveryResult(result)
1412
+ }
1413
+
1414
+ async isAuthenticated(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ authenticated: boolean }> {
1415
+ const result = await this.transmit('isAuthenticated', originator)
1416
+ return { authenticated: !!result[0] }
1417
+ }
1418
+
1419
+ async waitForAuthentication(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ authenticated: true }> {
1420
+ await this.transmit('waitForAuthentication', originator)
1421
+ return { authenticated: true }
1422
+ }
1423
+
1424
+ async getHeight(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ height: PositiveInteger }> {
1425
+ const result = await this.transmit('getHeight', originator)
1426
+ const resultReader = new Utils.Reader(result)
1427
+ return {
1428
+ height: resultReader.readVarIntNum()
1429
+ }
1430
+ }
1431
+
1432
+ async getHeaderForHeight(args: { height: PositiveInteger }, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ header: HexString }> {
1433
+ const paramWriter = new Utils.Writer()
1434
+ paramWriter.writeVarIntNum(args.height)
1435
+ const header = await this.transmit('getHeaderForHeight', originator, paramWriter.toArray())
1436
+ return {
1437
+ header: Utils.toHex(header)
1438
+ }
1439
+ }
1440
+
1441
+ async getNetwork(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ network: 'mainnet' | 'testnet' }> {
1442
+ const net = await this.transmit('getNetwork', originator)
1443
+ return {
1444
+ network: net[0] === 0 ? 'mainnet' : 'testnet'
1445
+ }
1446
+ }
1447
+
1448
+ async getVersion(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<{ version: VersionString7To30Bytes }> {
1449
+ const version = await this.transmit('getVersion', originator)
1450
+ return {
1451
+ version: Utils.toUTF8(version)
1452
+ }
1453
+ }
1454
+ }