@bsv/sdk 1.8.9 → 1.8.10

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 (63) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/transaction/Beef.js +1 -0
  3. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  4. package/dist/cjs/src/wallet/WERR_INSUFFICIENT_FUNDS.js +26 -0
  5. package/dist/cjs/src/wallet/WERR_INSUFFICIENT_FUNDS.js.map +1 -0
  6. package/dist/cjs/src/wallet/WERR_INVALID_PARAMETER.js +20 -0
  7. package/dist/cjs/src/wallet/WERR_INVALID_PARAMETER.js.map +1 -0
  8. package/dist/cjs/src/wallet/WalletClient.js +23 -0
  9. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  10. package/dist/cjs/src/wallet/WalletError.js +55 -0
  11. package/dist/cjs/src/wallet/WalletError.js.map +1 -1
  12. package/dist/cjs/src/wallet/index.js +18 -1
  13. package/dist/cjs/src/wallet/index.js.map +1 -1
  14. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js +28 -11
  15. package/dist/cjs/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  16. package/dist/cjs/src/wallet/validationHelpers.js +920 -0
  17. package/dist/cjs/src/wallet/validationHelpers.js.map +1 -0
  18. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  19. package/dist/esm/src/transaction/Beef.js +1 -0
  20. package/dist/esm/src/transaction/Beef.js.map +1 -1
  21. package/dist/esm/src/wallet/WERR_INSUFFICIENT_FUNDS.js +25 -0
  22. package/dist/esm/src/wallet/WERR_INSUFFICIENT_FUNDS.js.map +1 -0
  23. package/dist/esm/src/wallet/WERR_INVALID_PARAMETER.js +18 -0
  24. package/dist/esm/src/wallet/WERR_INVALID_PARAMETER.js.map +1 -0
  25. package/dist/esm/src/wallet/WalletClient.js +23 -0
  26. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  27. package/dist/esm/src/wallet/WalletError.js +55 -0
  28. package/dist/esm/src/wallet/WalletError.js.map +1 -1
  29. package/dist/esm/src/wallet/index.js +3 -0
  30. package/dist/esm/src/wallet/index.js.map +1 -1
  31. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js +25 -11
  32. package/dist/esm/src/wallet/substrates/HTTPWalletJSON.js.map +1 -1
  33. package/dist/esm/src/wallet/validationHelpers.js +859 -0
  34. package/dist/esm/src/wallet/validationHelpers.js.map +1 -0
  35. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  36. package/dist/types/src/transaction/Beef.d.ts +1 -0
  37. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  38. package/dist/types/src/wallet/WERR_INSUFFICIENT_FUNDS.d.ts +19 -0
  39. package/dist/types/src/wallet/WERR_INSUFFICIENT_FUNDS.d.ts.map +1 -0
  40. package/dist/types/src/wallet/WERR_INVALID_PARAMETER.d.ts +13 -0
  41. package/dist/types/src/wallet/WERR_INVALID_PARAMETER.d.ts.map +1 -0
  42. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
  43. package/dist/types/src/wallet/WalletError.d.ts +14 -1
  44. package/dist/types/src/wallet/WalletError.d.ts.map +1 -1
  45. package/dist/types/src/wallet/index.d.ts +3 -0
  46. package/dist/types/src/wallet/index.d.ts.map +1 -1
  47. package/dist/types/src/wallet/substrates/HTTPWalletJSON.d.ts.map +1 -1
  48. package/dist/types/src/wallet/validationHelpers.d.ts +512 -0
  49. package/dist/types/src/wallet/validationHelpers.d.ts.map +1 -0
  50. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  51. package/dist/umd/bundle.js +4 -4
  52. package/dist/umd/bundle.js.map +1 -1
  53. package/docs/reference/wallet.md +1431 -53
  54. package/package.json +1 -1
  55. package/src/transaction/Beef.ts +2 -0
  56. package/src/wallet/WERR_INSUFFICIENT_FUNDS.ts +25 -0
  57. package/src/wallet/WERR_INVALID_PARAMETER.ts +20 -0
  58. package/src/wallet/WalletClient.ts +30 -0
  59. package/src/wallet/WalletError.ts +52 -0
  60. package/src/wallet/__tests/WalletClient.test.ts +31 -0
  61. package/src/wallet/index.ts +3 -0
  62. package/src/wallet/substrates/HTTPWalletJSON.ts +19 -9
  63. package/src/wallet/validationHelpers.ts +1211 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.8.9",
3
+ "version": "1.8.10",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -869,3 +869,5 @@ export class Beef {
869
869
  }
870
870
  }
871
871
  }
872
+
873
+ export default Beef
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Insufficient funds in the available inputs to cover the cost of the required outputs
3
+ * and the transaction fee (${moreSatoshisNeeded} more satoshis are needed,
4
+ * for a total of ${totalSatoshisNeeded}), plus whatever would be required in order
5
+ * to pay the fee to unlock and spend the outputs used to provide the additional satoshis.
6
+ */
7
+ export class WERR_INSUFFICIENT_FUNDS extends Error {
8
+ code: number
9
+ isError: boolean = true
10
+
11
+ /**
12
+ * @param totalSatoshisNeeded Total satoshis required to fund transactions after net of required inputs and outputs.
13
+ * @param moreSatoshisNeeded Shortfall on total satoshis required to fund transactions after net of required inputs and outputs.
14
+ */
15
+ constructor (
16
+ public totalSatoshisNeeded: number,
17
+ public moreSatoshisNeeded: number
18
+ ) {
19
+ super(`Insufficient funds in the available inputs to cover the cost of the required outputs and the transaction fee (${moreSatoshisNeeded} more satoshis are needed, for a total of ${totalSatoshisNeeded}), plus whatever would be required in order to pay the fee to unlock and spend the outputs used to provide the additional satoshis.`)
20
+ this.code = 7
21
+ this.name = this.constructor.name
22
+ }
23
+ }
24
+
25
+ export default WERR_INSUFFICIENT_FUNDS
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The ${parameter} parameter is invalid.
3
+ *
4
+ * This is an example of an error object with a custom property `parameter` and templated `message`.
5
+ */
6
+ export class WERR_INVALID_PARAMETER extends Error {
7
+ code: number
8
+ isError: boolean = true
9
+
10
+ constructor (
11
+ public parameter: string,
12
+ mustBe?: string
13
+ ) {
14
+ super(`The ${parameter} parameter must be ${mustBe ?? 'valid.'}`)
15
+ this.code = 6
16
+ this.name = this.constructor.name
17
+ }
18
+ }
19
+
20
+ export default WERR_INVALID_PARAMETER
@@ -41,6 +41,23 @@ import WalletWireTransceiver from './substrates/WalletWireTransceiver.js'
41
41
  import HTTPWalletWire from './substrates/HTTPWalletWire.js'
42
42
  import HTTPWalletJSON from './substrates/HTTPWalletJSON.js'
43
43
  import ReactNativeWebView from './substrates/ReactNativeWebView.js'
44
+ import {
45
+ validateAbortActionArgs,
46
+ validateAcquireDirectCertificateArgs,
47
+ validateAcquireIssuanceCertificateArgs,
48
+ validateCreateActionArgs,
49
+ validateDiscoverByAttributesArgs,
50
+ validateDiscoverByIdentityKeyArgs,
51
+ validateInternalizeActionArgs,
52
+ validateListActionsArgs,
53
+ validateListCertificatesArgs,
54
+ validateListOutputsArgs,
55
+ validateProveCertificateArgs,
56
+ validateRelinquishCertificateArgs,
57
+ validateRelinquishOutputArgs,
58
+ validateSignActionArgs
59
+ } from './validationHelpers.js'
60
+ import { WERR_INVALID_PARAMETER } from './WERR_INVALID_PARAMETER.js'
44
61
 
45
62
  const MAX_XDM_RESPONSE_WAIT = 200
46
63
 
@@ -133,6 +150,7 @@ export default class WalletClient implements WalletInterface {
133
150
  }
134
151
 
135
152
  async createAction (args: CreateActionArgs): Promise<CreateActionResult> {
153
+ validateCreateActionArgs(args)
136
154
  await this.connectToSubstrate()
137
155
  return await (this.substrate as WalletInterface).createAction(
138
156
  args,
@@ -141,6 +159,7 @@ export default class WalletClient implements WalletInterface {
141
159
  }
142
160
 
143
161
  async signAction (args: SignActionArgs): Promise<SignActionResult> {
162
+ validateSignActionArgs(args)
144
163
  await this.connectToSubstrate()
145
164
  return await (this.substrate as WalletInterface).signAction(
146
165
  args,
@@ -151,6 +170,7 @@ export default class WalletClient implements WalletInterface {
151
170
  async abortAction (args: {
152
171
  reference: Base64String
153
172
  }): Promise<{ aborted: true }> {
173
+ validateAbortActionArgs(args)
154
174
  await this.connectToSubstrate()
155
175
  return await (this.substrate as WalletInterface).abortAction(
156
176
  args,
@@ -159,6 +179,7 @@ export default class WalletClient implements WalletInterface {
159
179
  }
160
180
 
161
181
  async listActions (args: ListActionsArgs): Promise<ListActionsResult> {
182
+ validateListActionsArgs(args)
162
183
  await this.connectToSubstrate()
163
184
  return await (this.substrate as WalletInterface).listActions(
164
185
  args,
@@ -169,6 +190,7 @@ export default class WalletClient implements WalletInterface {
169
190
  async internalizeAction (
170
191
  args: InternalizeActionArgs
171
192
  ): Promise<{ accepted: true }> {
193
+ validateInternalizeActionArgs(args)
172
194
  await this.connectToSubstrate()
173
195
  return await (this.substrate as WalletInterface).internalizeAction(
174
196
  args,
@@ -177,6 +199,7 @@ export default class WalletClient implements WalletInterface {
177
199
  }
178
200
 
179
201
  async listOutputs (args: ListOutputsArgs): Promise<ListOutputsResult> {
202
+ validateListOutputsArgs(args)
180
203
  await this.connectToSubstrate()
181
204
  return await (this.substrate as WalletInterface).listOutputs(
182
205
  args,
@@ -188,6 +211,7 @@ export default class WalletClient implements WalletInterface {
188
211
  basket: BasketStringUnder300Bytes
189
212
  output: OutpointString
190
213
  }): Promise<{ relinquished: true }> {
214
+ validateRelinquishOutputArgs(args)
191
215
  await this.connectToSubstrate()
192
216
  return await (this.substrate as WalletInterface).relinquishOutput(
193
217
  args,
@@ -352,6 +376,7 @@ export default class WalletClient implements WalletInterface {
352
376
  async acquireCertificate (
353
377
  args: AcquireCertificateArgs
354
378
  ): Promise<AcquireCertificateResult> {
379
+ if (args.acquisitionProtocol === 'direct') { validateAcquireDirectCertificateArgs(args) } else if (args.acquisitionProtocol === 'issuance') { validateAcquireIssuanceCertificateArgs(args) } else { throw new WERR_INVALID_PARAMETER('acquisitionProtocol', `valid. ${String(args.acquisitionProtocol)} is unrecognized.`) }
355
380
  await this.connectToSubstrate()
356
381
  return await (this.substrate as WalletInterface).acquireCertificate(
357
382
  args,
@@ -367,6 +392,7 @@ export default class WalletClient implements WalletInterface {
367
392
  privileged?: BooleanDefaultFalse
368
393
  privilegedReason?: DescriptionString5to50Bytes
369
394
  }): Promise<ListCertificatesResult> {
395
+ validateListCertificatesArgs(args)
370
396
  await this.connectToSubstrate()
371
397
  return await (this.substrate as WalletInterface).listCertificates(
372
398
  args,
@@ -377,6 +403,7 @@ export default class WalletClient implements WalletInterface {
377
403
  async proveCertificate (
378
404
  args: ProveCertificateArgs
379
405
  ): Promise<ProveCertificateResult> {
406
+ validateProveCertificateArgs(args)
380
407
  await this.connectToSubstrate()
381
408
  return await (this.substrate as WalletInterface).proveCertificate(
382
409
  args,
@@ -389,6 +416,7 @@ export default class WalletClient implements WalletInterface {
389
416
  serialNumber: Base64String
390
417
  certifier: PubKeyHex
391
418
  }): Promise<{ relinquished: true }> {
419
+ validateRelinquishCertificateArgs(args)
392
420
  await this.connectToSubstrate()
393
421
  return await (this.substrate as WalletInterface).relinquishCertificate(
394
422
  args,
@@ -401,6 +429,7 @@ export default class WalletClient implements WalletInterface {
401
429
  limit?: PositiveIntegerDefault10Max10000
402
430
  offset?: PositiveIntegerOrZero
403
431
  }): Promise<DiscoverCertificatesResult> {
432
+ validateDiscoverByIdentityKeyArgs(args)
404
433
  await this.connectToSubstrate()
405
434
  return await (this.substrate as WalletInterface).discoverByIdentityKey(
406
435
  args,
@@ -413,6 +442,7 @@ export default class WalletClient implements WalletInterface {
413
442
  limit?: PositiveIntegerDefault10Max10000
414
443
  offset?: PositiveIntegerOrZero
415
444
  }): Promise<DiscoverCertificatesResult> {
445
+ validateDiscoverByAttributesArgs(args)
416
446
  await this.connectToSubstrate()
417
447
  return await (this.substrate as WalletInterface).discoverByAttributes(
418
448
  args,
@@ -13,6 +13,56 @@ export class WalletError extends Error {
13
13
  Error.captureStackTrace(this, this.constructor)
14
14
  }
15
15
  }
16
+
17
+ /**
18
+ * Safely serializes a WalletError (including special cases), Error or unknown error to JSON.
19
+ *
20
+ * Safely means avoiding deep, large, circular issues.
21
+ *
22
+ * Example deserialization can be found in HTTPWalletJSON.ts of bsv ts-sdk.
23
+ *
24
+ * @param error
25
+ * @returns stringified JSON representation of the error such that it can be deserialized to a WalletError.
26
+ */
27
+ static unknownToJson (error: any): string {
28
+ let e: any | undefined
29
+ if (typeof error.constructor.name === 'string' && String(error.constructor.name).startsWith('WERR_')) {
30
+ e = {
31
+ name: error.constructor.name,
32
+ message: error.message,
33
+ isError: true
34
+ }
35
+ if (e.name === 'WERR_REVIEW_ACTIONS') {
36
+ e.reviewActionResults = error.reviewActionResults
37
+ e.sendWithResults = error.sendWithResults
38
+ e.txid = error.txid
39
+ e.tx = error.tx
40
+ e.noSendChange = error.noSendChange
41
+ e.code = 5
42
+ } else if (e.name === 'WERR_INVALID_PARAMETER') {
43
+ e.parameter = error.parameter
44
+ e.code = 6
45
+ } else if (e.name === 'WERR_INSUFFICIENT_FUNDS') {
46
+ e.totalSatoshisNeeded = error.totalSatoshisNeeded
47
+ e.moreSatoshisNeeded = error.moreSatoshisNeeded
48
+ e.code = 7
49
+ }
50
+ } else if (error instanceof Error) {
51
+ e = {
52
+ name: error.constructor.name,
53
+ message: error.message,
54
+ isError: true
55
+ }
56
+ } else {
57
+ e = {
58
+ name: 'WERR_UNKNOWN',
59
+ message: String(error),
60
+ isError: true
61
+ }
62
+ }
63
+ const json = JSON.stringify(e)
64
+ return json
65
+ }
16
66
  }
17
67
 
18
68
  // NOTE: Enum values must not exceed the UInt8 range (0–255)
@@ -22,6 +72,8 @@ export enum walletErrors {
22
72
  invalidHmac = 3,
23
73
  invalidSignature = 4,
24
74
  reviewActions = 5,
75
+ invalidParameter = 6,
76
+ insufficientFunds = 7,
25
77
  }
26
78
 
27
79
  export type WalletErrorCode = keyof typeof walletErrors
@@ -0,0 +1,31 @@
1
+ import { CreateActionArgs } from '../Wallet.interfaces'
2
+ import WalletClient from '../WalletClient'
3
+ describe('WalletClient', () => {
4
+ it('0 createAction', async () => {
5
+ const wallet = new WalletClient('auto', '0.WalletClient.test')
6
+
7
+ async function testArgs(args: CreateActionArgs, parameter: string) {
8
+ try {
9
+ const r = await wallet.createAction(args)
10
+ expect(true).toBe(false)
11
+ } catch (e: any) {
12
+ expect(e.name).toBe('WERR_INVALID_PARAMETER')
13
+ expect(e.parameter).toBe(parameter)
14
+ }
15
+ }
16
+
17
+ const args: CreateActionArgs = {
18
+ description: 't' // too short to be valid
19
+ }
20
+ testArgs(args, 'description')
21
+ args.description = '12345'
22
+ args.outputs = [{
23
+ lockingScript: '',
24
+ satoshis: 0,
25
+ outputDescription: ''
26
+ }]
27
+ testArgs(args, 'lockingScript')
28
+ args.outputs[0].lockingScript = '1234'
29
+ testArgs(args, 'outputDescription')
30
+ })
31
+ })
@@ -6,5 +6,8 @@ export { default as WalletClient } from './WalletClient.js'
6
6
  // Is this an error? should it be 'walletErrors', the enum not the class?
7
7
  export { default as WalletErrors } from './WalletError.js'
8
8
  export { default as WERR_REVIEW_ACTIONS } from './WERR_REVIEW_ACTIONS.js'
9
+ export { default as WERR_INVALID_PARAMETER } from './WERR_INVALID_PARAMETER.js'
10
+ export { default as WERR_INSUFFICIENT_FUNDS } from './WERR_INSUFFICIENT_FUNDS.js'
9
11
  export * from './WalletError.js'
12
+ export * as Validation from './validationHelpers.js'
10
13
  export * from './substrates/index.js'
@@ -36,7 +36,9 @@ import {
36
36
  VersionString7To30Bytes,
37
37
  } from '../Wallet.interfaces.js'
38
38
  import { WERR_REVIEW_ACTIONS } from '../WERR_REVIEW_ACTIONS.js'
39
+ import { WERR_INVALID_PARAMETER } from '../WERR_INVALID_PARAMETER.js'
39
40
  import { toOriginHeader } from './utils/toOriginHeader.js'
41
+ import WERR_INSUFFICIENT_FUNDS from '../WERR_INSUFFICIENT_FUNDS.js'
40
42
 
41
43
  export default class HTTPWalletJSON implements WalletInterface {
42
44
  baseUrl: string
@@ -84,17 +86,25 @@ export default class HTTPWalletJSON implements WalletInterface {
84
86
 
85
87
  // Check the HTTP status on the original response
86
88
  if (!res.ok) {
87
- if (res.status === 400 && data.isError && data.code === 5) {
88
- const err = new WERR_REVIEW_ACTIONS(data.reviewActionResults, data.sendWithResults, data.txid, data.tx, data.noSendChange)
89
- throw err
90
- } else {
91
- const err = {
92
- call,
93
- args,
94
- message: data.message ?? `HTTP Client error ${res.status}`
89
+ if (res.status === 400 && data.isError) {
90
+ let err: any
91
+ switch (data.code) {
92
+ case 5:
93
+ err = new WERR_REVIEW_ACTIONS(data.reviewActionResults, data.sendWithResults, data.txid, data.tx, data.noSendChange); break;
94
+ case 6:
95
+ err = new WERR_INVALID_PARAMETER(data.parameter); err.message = data.message; break;
96
+ case 7:
97
+ err = new WERR_INSUFFICIENT_FUNDS(data.totalSatoshisNeeded, data.moreSatoshisNeeded); break;
98
+ default: break;
95
99
  }
96
- throw new Error(JSON.stringify(err))
100
+ if (err) throw err
97
101
  }
102
+ const err = {
103
+ call,
104
+ args,
105
+ message: data.message ?? `HTTP Client error ${res.status}`
106
+ }
107
+ throw new Error(JSON.stringify(err))
98
108
  }
99
109
  return data
100
110
  }