@bsv/sdk 1.5.2 → 1.6.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 (66) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/primitives/AESGCM.js +113 -137
  3. package/dist/cjs/src/primitives/AESGCM.js.map +1 -1
  4. package/dist/cjs/src/primitives/BigNumber.js +1019 -3947
  5. package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
  6. package/dist/cjs/src/primitives/K256.js +53 -37
  7. package/dist/cjs/src/primitives/K256.js.map +1 -1
  8. package/dist/cjs/src/primitives/Mersenne.js +16 -21
  9. package/dist/cjs/src/primitives/Mersenne.js.map +1 -1
  10. package/dist/cjs/src/primitives/MontgomoryMethod.js.map +1 -1
  11. package/dist/cjs/src/primitives/utils.js +27 -17
  12. package/dist/cjs/src/primitives/utils.js.map +1 -1
  13. package/dist/cjs/src/script/Spend.js +618 -858
  14. package/dist/cjs/src/script/Spend.js.map +1 -1
  15. package/dist/cjs/src/transaction/Beef.js +17 -0
  16. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  17. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  18. package/dist/esm/src/primitives/AESGCM.js +112 -137
  19. package/dist/esm/src/primitives/AESGCM.js.map +1 -1
  20. package/dist/esm/src/primitives/BigNumber.js +1011 -3969
  21. package/dist/esm/src/primitives/BigNumber.js.map +1 -1
  22. package/dist/esm/src/primitives/K256.js +53 -37
  23. package/dist/esm/src/primitives/K256.js.map +1 -1
  24. package/dist/esm/src/primitives/Mersenne.js +16 -21
  25. package/dist/esm/src/primitives/Mersenne.js.map +1 -1
  26. package/dist/esm/src/primitives/MontgomoryMethod.js.map +1 -1
  27. package/dist/esm/src/primitives/utils.js +29 -17
  28. package/dist/esm/src/primitives/utils.js.map +1 -1
  29. package/dist/esm/src/script/Spend.js +618 -857
  30. package/dist/esm/src/script/Spend.js.map +1 -1
  31. package/dist/esm/src/transaction/Beef.js +17 -0
  32. package/dist/esm/src/transaction/Beef.js.map +1 -1
  33. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  34. package/dist/types/src/primitives/AESGCM.d.ts.map +1 -1
  35. package/dist/types/src/primitives/BigNumber.d.ts +238 -1705
  36. package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
  37. package/dist/types/src/primitives/K256.d.ts.map +1 -1
  38. package/dist/types/src/primitives/Mersenne.d.ts +2 -2
  39. package/dist/types/src/primitives/Mersenne.d.ts.map +1 -1
  40. package/dist/types/src/primitives/utils.d.ts +2 -0
  41. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  42. package/dist/types/src/script/Spend.d.ts +11 -1
  43. package/dist/types/src/script/Spend.d.ts.map +1 -1
  44. package/dist/types/src/transaction/Beef.d.ts +21 -1
  45. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  46. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  47. package/dist/umd/bundle.js +1 -1
  48. package/docs/performance.md +70 -0
  49. package/docs/primitives.md +262 -3049
  50. package/docs/transaction.md +34 -0
  51. package/docs/wallet.md +1 -1
  52. package/package.json +1 -1
  53. package/src/auth/__tests/Peer.test.ts +38 -23
  54. package/src/auth/certificates/__tests/MasterCertificate.test.ts +27 -20
  55. package/src/auth/certificates/__tests/VerifiableCertificate.test.ts +24 -24
  56. package/src/primitives/AESGCM.ts +118 -164
  57. package/src/primitives/BigNumber.ts +867 -4180
  58. package/src/primitives/K256.ts +57 -37
  59. package/src/primitives/Mersenne.ts +16 -20
  60. package/src/primitives/MontgomoryMethod.ts +2 -2
  61. package/src/primitives/__tests/ReductionContext.test.ts +6 -1
  62. package/src/primitives/utils.ts +28 -17
  63. package/src/script/Spend.ts +634 -1309
  64. package/src/transaction/Beef.ts +18 -1
  65. package/src/transaction/__tests/Transaction.test.ts +14 -16
  66. package/src/transaction/__tests/Transaction.benchmarks.test.ts +0 -237
@@ -573,6 +573,10 @@ export class Beef {
573
573
  mergeBeef(beef: number[] | Beef): void
574
574
  isValid(allowTxidOnly?: boolean): boolean
575
575
  async verify(chainTracker: ChainTracker, allowTxidOnly?: boolean): Promise<boolean>
576
+ verifyValid(allowTxidOnly?: boolean): {
577
+ valid: boolean;
578
+ roots: Record<number, string>;
579
+ }
576
580
  toWriter(writer: Writer): void
577
581
  toBinary(): number[]
578
582
  toBinaryAtomic(txid: string): number[]
@@ -950,6 +954,36 @@ Argument Details
950
954
  + **allowTxidOnly**
951
955
  + optional. If true, transaction txid is assumed valid
952
956
 
957
+ #### Method verifyValid
958
+
959
+ Sorts `txs` and confirms validity of transaction data contained in beef
960
+ by validating structure of this beef.
961
+
962
+ Returns block heights and merkle root values to be confirmed by a chaintracker.
963
+
964
+ Validity requirements:
965
+ 1. No 'known' txids, unless `allowTxidOnly` is true.
966
+ 2. All transactions have bumps or their inputs chain back to bumps (or are known).
967
+ 3. Order of transactions satisfies dependencies before dependents.
968
+ 4. No transactions with duplicate txids.
969
+
970
+ ```ts
971
+ verifyValid(allowTxidOnly?: boolean): {
972
+ valid: boolean;
973
+ roots: Record<number, string>;
974
+ }
975
+ ```
976
+
977
+ Returns
978
+
979
+ `valid` is true iff this Beef is structuraly valid.
980
+ `roots` is a record where keys are block heights and values are the corresponding merkle roots to be validated.
981
+
982
+ Argument Details
983
+
984
+ + **allowTxidOnly**
985
+ + optional. If true, transaction txid is assumed valid
986
+
953
987
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Enums](#enums), [Variables](#variables)
954
988
 
955
989
  ---
package/docs/wallet.md CHANGED
@@ -2610,7 +2610,7 @@ The SDK is how applications communicate with wallets over a communications subst
2610
2610
  export default class WalletClient implements WalletInterface {
2611
2611
  public substrate: "auto" | WalletInterface;
2612
2612
  originator?: OriginatorDomainNameStringUnder250Bytes;
2613
- constructor(substrate: "auto" | "Cicada" | "XDM" | "window.CWI" | "json-api" | WalletInterface = "auto", originator?: OriginatorDomainNameStringUnder250Bytes)
2613
+ constructor(substrate: "auto" | "Cicada" | "XDM" | "window.CWI" | "json-api" | "react-native" | WalletInterface = "auto", originator?: OriginatorDomainNameStringUnder250Bytes)
2614
2614
  async connectToSubstrate(): Promise<void>
2615
2615
  async createAction(args: CreateActionArgs): Promise<CreateActionResult>
2616
2616
  async signAction(args: SignActionArgs): Promise<SignActionResult>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.5.2",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -8,6 +8,10 @@ import { MasterCertificate } from '../../auth/certificates/MasterCertificate.js'
8
8
  import { getVerifiableCertificates } from '../../auth/utils/getVerifiableCertificates.js'
9
9
  import { CompletedProtoWallet } from '../certificates/__tests/CompletedProtoWallet.js'
10
10
 
11
+ const certifierPrivKey = new PrivateKey(21)
12
+ const alicePrivKey = new PrivateKey(22)
13
+ const bobPrivKey = new PrivateKey(23)
14
+
11
15
  jest.mock('../../auth/utils/getVerifiableCertificates')
12
16
 
13
17
  class LocalTransport implements Transport {
@@ -40,6 +44,19 @@ class LocalTransport implements Transport {
40
44
  }
41
45
  }
42
46
 
47
+ function waitForNextGeneralMessage (
48
+ peer: Peer,
49
+ handler?: (senderPublicKey: string, payload: number[]) => void
50
+ ): Promise<void> {
51
+ return new Promise(resolve => {
52
+ const listenerId = peer.listenForGeneralMessages((senderPublicKey, payload) => {
53
+ peer.stopListeningForGeneralMessages(listenerId)
54
+ if (handler !== undefined) handler(senderPublicKey, payload)
55
+ resolve()
56
+ })
57
+ })
58
+ }
59
+
43
60
  describe('Peer class mutual authentication and certificate exchange', () => {
44
61
  let walletA: WalletInterface, walletB: WalletInterface
45
62
  let transportA: LocalTransport, transportB: LocalTransport
@@ -49,7 +66,7 @@ describe('Peer class mutual authentication and certificate exchange', () => {
49
66
 
50
67
  const certificateType = Utils.toBase64(new Array(32).fill(1))
51
68
  // const certificateSerialNumber = Utils.toBase64(new Array(32).fill(2))
52
- const certifierPrivateKey = PrivateKey.fromRandom()
69
+ const certifierPrivateKey = certifierPrivKey
53
70
  const certifierPublicKey = certifierPrivateKey.toPublicKey().toString()
54
71
  const certificatesToRequest = {
55
72
  certifiers: [certifierPublicKey],
@@ -198,8 +215,8 @@ describe('Peer class mutual authentication and certificate exchange', () => {
198
215
  certificatesReceivedByAlice = []
199
216
  certificatesReceivedByBob = []
200
217
 
201
- walletA = new CompletedProtoWallet(PrivateKey.fromRandom())
202
- walletB = new CompletedProtoWallet(PrivateKey.fromRandom())
218
+ walletA = new CompletedProtoWallet(alicePrivKey)
219
+ walletB = new CompletedProtoWallet(bobPrivKey)
203
220
  })
204
221
 
205
222
  it('Neither Alice nor Bob request certificates, mutual authentication completes successfully', async () => {
@@ -235,10 +252,10 @@ describe('Peer class mutual authentication and certificate exchange', () => {
235
252
  const transportA2 = new LocalTransport()
236
253
  const transportB = new LocalTransport()
237
254
  transportA1.connect(transportB)
238
- const aliceKey = PrivateKey.fromRandom()
255
+ const aliceKey = alicePrivKey
239
256
  const walletA1 = new CompletedProtoWallet(aliceKey)
240
257
  const walletA2 = new CompletedProtoWallet(aliceKey)
241
- const walletB = new CompletedProtoWallet(PrivateKey.fromRandom())
258
+ const walletB = new CompletedProtoWallet(alicePrivKey)
242
259
  const aliceFirstDevice = new Peer(
243
260
  walletA1,
244
261
  transportA1
@@ -264,22 +281,14 @@ describe('Peer class mutual authentication and certificate exchange', () => {
264
281
  })().catch(e => { })
265
282
  })
266
283
  })
267
- let aliceReceivedGeneralMessageOnFirstDevice = new Promise<void>((resolve) => {
268
- aliceFirstDevice.listenForGeneralMessages((senderPublicKey, payload) => {
269
- (async () => {
270
- resolve()
271
- alice1MessageHandler(senderPublicKey, payload)
272
- })().catch(e => { })
273
- })
274
- })
275
- const aliceReceivedGeneralMessageOnOtherDevice = new Promise<void>((resolve) => {
276
- aliceOtherDevice.listenForGeneralMessages((senderPublicKey, payload) => {
277
- (async () => {
278
- resolve()
279
- alice2MessageHandler(senderPublicKey, payload)
280
- })().catch(e => { })
281
- })
282
- })
284
+ const aliceReceivedGeneralMessageOnFirstDevice = waitForNextGeneralMessage(
285
+ aliceFirstDevice,
286
+ alice1MessageHandler
287
+ )
288
+ const aliceReceivedGeneralMessageOnOtherDevice = waitForNextGeneralMessage(
289
+ aliceOtherDevice,
290
+ alice2MessageHandler
291
+ )
283
292
 
284
293
  await aliceFirstDevice.toPeer(Utils.toArray('Hello Bob!'))
285
294
  await bobReceivedGeneralMessage
@@ -288,8 +297,14 @@ describe('Peer class mutual authentication and certificate exchange', () => {
288
297
  await aliceOtherDevice.toPeer(Utils.toArray('Hello Bob from my other device!'))
289
298
  await aliceReceivedGeneralMessageOnOtherDevice
290
299
  transportA1.connect(transportB)
291
- await aliceFirstDevice.toPeer(Utils.toArray('Back on my first device now, Bob! Can you still hear me?'))
292
- await new Promise(resolve => setTimeout(resolve, 2000))
300
+ const waitForSecondMessage = waitForNextGeneralMessage(
301
+ aliceFirstDevice,
302
+ alice1MessageHandler
303
+ )
304
+ await aliceFirstDevice.toPeer(
305
+ Utils.toArray('Back on my first device now, Bob! Can you still hear me?')
306
+ )
307
+ await waitForSecondMessage
293
308
  expect(alice1MessageHandler.mock.calls.length).toEqual(2)
294
309
  }, 30000)
295
310
 
@@ -3,23 +3,30 @@ import { VerifiableCertificate } from '../../../auth/certificates/VerifiableCert
3
3
  import { PrivateKey, SymmetricKey, Utils, Random } from '../../../../mod'
4
4
  import { CompletedProtoWallet } from '../../../auth/certificates/__tests/CompletedProtoWallet'
5
5
 
6
+ const subjectPrivateKey = new PrivateKey(21)
7
+ const certifierPrivateKey = new PrivateKey(22)
8
+
9
+ const fieldSymFixed1 = new SymmetricKey(51)
10
+ const fieldSymWrong = new SymmetricKey(61)
11
+
12
+ const subjectKey2 = new PrivateKey(71)
13
+ const verifierKey2 = new PrivateKey(81)
14
+
15
+ // A mock revocation outpoint for testing
16
+ const mockRevocationOutpoint =
17
+ 'deadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000.1'
18
+
19
+ // Arbitrary certificate data (in plaintext)
20
+ const plaintextFields = {
21
+ name: 'Alice',
22
+ email: 'alice@example.com',
23
+ department: 'Engineering'
24
+ }
25
+
26
+ const subjectWallet = new CompletedProtoWallet(subjectPrivateKey)
27
+ const certifierWallet = new CompletedProtoWallet(certifierPrivateKey)
28
+
6
29
  describe('MasterCertificate', () => {
7
- const subjectPrivateKey = PrivateKey.fromRandom()
8
- const certifierPrivateKey = PrivateKey.fromRandom()
9
-
10
- // A mock revocation outpoint for testing
11
- const mockRevocationOutpoint =
12
- 'deadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000.1'
13
-
14
- // Arbitrary certificate data (in plaintext)
15
- const plaintextFields = {
16
- name: 'Alice',
17
- email: 'alice@example.com',
18
- department: 'Engineering'
19
- }
20
-
21
- const subjectWallet = new CompletedProtoWallet(subjectPrivateKey)
22
- const certifierWallet = new CompletedProtoWallet(certifierPrivateKey)
23
30
  let subjectIdentityKey: string
24
31
  let certifierIdentityKey: string
25
32
 
@@ -35,7 +42,7 @@ describe('MasterCertificate', () => {
35
42
  describe('constructor', () => {
36
43
  it('should construct a MasterCertificate successfully when masterKeyring is valid', () => {
37
44
  // Prepare a minimal valid MasterCertificate
38
- const fieldSymKey = SymmetricKey.fromRandom()
45
+ const fieldSymKey = fieldSymFixed1
39
46
  const encryptedFieldValue = Utils.toBase64(
40
47
  fieldSymKey.encrypt(Utils.toArray('Alice', 'utf8')) as number[]
41
48
  )
@@ -129,7 +136,7 @@ describe('MasterCertificate', () => {
129
136
  mockRevocationOutpoint,
130
137
  {
131
138
  name: Utils.toBase64(
132
- SymmetricKey.fromRandom().encrypt(
139
+ fieldSymWrong.encrypt(
133
140
  Utils.toArray('Alice', 'utf8')
134
141
  ) as number[]
135
142
  )
@@ -149,7 +156,7 @@ describe('MasterCertificate', () => {
149
156
  })
150
157
 
151
158
  describe('createKeyringForVerifier (static)', () => {
152
- const verifierPrivateKey = PrivateKey.fromRandom()
159
+ const verifierPrivateKey = verifierKey2
153
160
  const verifierWallet = new CompletedProtoWallet(verifierPrivateKey)
154
161
  let verifierIdentityKey: string
155
162
 
@@ -350,7 +357,7 @@ describe('MasterCertificate', () => {
350
357
  })
351
358
  it('should allow issuing a self-signed certificate and decrypt it with the same wallet', async () => {
352
359
  // In a self-signed scenario, the subject and certifier are the same
353
- const subjectWallet = new CompletedProtoWallet(PrivateKey.fromRandom())
360
+ const subjectWallet = new CompletedProtoWallet(subjectKey2)
354
361
 
355
362
  // Some sample fields
356
363
  const selfSignedFields = {
@@ -5,28 +5,31 @@ import { CompletedProtoWallet } from '../../../auth/certificates/__tests/Complet
5
5
  import { MasterCertificate } from '../../../auth/certificates/MasterCertificate'
6
6
  import { ProtoWallet, WalletCertificate } from '../../../wallet/index'
7
7
 
8
- describe('VerifiableCertificate', () => {
9
- const subjectPrivateKey = PrivateKey.fromRandom()
10
- const subjectIdentityKey = subjectPrivateKey.toPublicKey().toString()
11
- const certifierPrivateKey = PrivateKey.fromRandom()
12
- const certifierIdentityKey = certifierPrivateKey.toPublicKey().toString()
13
- const verifierPrivateKey = PrivateKey.fromRandom()
14
- const verifierIdentityKey = verifierPrivateKey.toPublicKey().toString()
15
-
16
- const subjectWallet = new CompletedProtoWallet(subjectPrivateKey)
17
- const verifierWallet = new CompletedProtoWallet(verifierPrivateKey)
18
-
19
- const sampleType = Utils.toBase64(new Array(32).fill(1))
20
- const sampleSerialNumber = Utils.toBase64(new Array(32).fill(2))
21
- const sampleRevocationOutpoint =
22
- 'deadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000.1'
23
-
24
- const plaintextFields = {
25
- name: 'Alice',
26
- email: 'alice@example.com',
27
- organization: 'Example Corp'
28
- }
8
+ const subjectPrivateKey = new PrivateKey(21)
9
+ const subjectIdentityKey = subjectPrivateKey.toPublicKey().toString()
10
+ const certifierPrivateKey = new PrivateKey(22)
11
+ const certifierIdentityKey = certifierPrivateKey.toPublicKey().toString()
12
+ const verifierPrivateKey = new PrivateKey(23)
13
+ const verifierIdentityKey = verifierPrivateKey.toPublicKey().toString()
14
+
15
+ const wrongPrivateKey = new PrivateKey(31)
16
+ const wrongWallet = new CompletedProtoWallet(wrongPrivateKey)
17
+
18
+ const subjectWallet = new CompletedProtoWallet(subjectPrivateKey)
19
+ const verifierWallet = new CompletedProtoWallet(verifierPrivateKey)
20
+
21
+ const sampleType = Utils.toBase64(new Array(32).fill(1))
22
+ const sampleSerialNumber = Utils.toBase64(new Array(32).fill(2))
23
+ const sampleRevocationOutpoint =
24
+ 'deadbeefdeadbeefdeadbeefdeadbeef00000000000000000000000000000000.1'
25
+
26
+ const plaintextFields = {
27
+ name: 'Alice',
28
+ email: 'alice@example.com',
29
+ organization: 'Example Corp'
30
+ }
29
31
 
32
+ describe('VerifiableCertificate', () => {
30
33
  let verifiableCert: VerifiableCertificate
31
34
 
32
35
  beforeEach(async () => {
@@ -79,9 +82,6 @@ describe('VerifiableCertificate', () => {
79
82
  })
80
83
 
81
84
  it('should fail if the verifier wallet does not have the correct private key (wrong key)', async () => {
82
- const wrongPrivateKey = PrivateKey.fromRandom()
83
- const wrongWallet = new CompletedProtoWallet(wrongPrivateKey)
84
-
85
85
  await expect(verifiableCert.decryptFields(wrongWallet)).rejects.toThrow(
86
86
  /Failed to decrypt selectively revealed certificate fields using keyring/
87
87
  )