@bsv/sdk 1.7.6 → 1.8.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 (57) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/transaction/Beef.js +25 -2
  3. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  4. package/dist/cjs/src/transaction/Transaction.js +36 -40
  5. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  6. package/dist/cjs/src/transaction/fee-models/LivePolicy.js +90 -0
  7. package/dist/cjs/src/transaction/fee-models/LivePolicy.js.map +1 -0
  8. package/dist/cjs/src/transaction/fee-models/index.js +3 -1
  9. package/dist/cjs/src/transaction/fee-models/index.js.map +1 -1
  10. package/dist/cjs/src/wallet/WalletClient.js +43 -52
  11. package/dist/cjs/src/wallet/WalletClient.js.map +1 -1
  12. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js +19 -0
  13. package/dist/cjs/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  14. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js +18 -1
  15. package/dist/cjs/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  16. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  17. package/dist/esm/src/transaction/Beef.js +25 -2
  18. package/dist/esm/src/transaction/Beef.js.map +1 -1
  19. package/dist/esm/src/transaction/Transaction.js +36 -40
  20. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  21. package/dist/esm/src/transaction/fee-models/LivePolicy.js +85 -0
  22. package/dist/esm/src/transaction/fee-models/LivePolicy.js.map +1 -0
  23. package/dist/esm/src/transaction/fee-models/index.js +1 -0
  24. package/dist/esm/src/transaction/fee-models/index.js.map +1 -1
  25. package/dist/esm/src/wallet/WalletClient.js +43 -52
  26. package/dist/esm/src/wallet/WalletClient.js.map +1 -1
  27. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js +19 -0
  28. package/dist/esm/src/wallet/substrates/WalletWireProcessor.js.map +1 -1
  29. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js +18 -1
  30. package/dist/esm/src/wallet/substrates/WalletWireTransceiver.js.map +1 -1
  31. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  32. package/dist/types/src/transaction/Beef.d.ts +4 -0
  33. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  34. package/dist/types/src/transaction/Transaction.d.ts +2 -2
  35. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  36. package/dist/types/src/transaction/fee-models/LivePolicy.d.ts +41 -0
  37. package/dist/types/src/transaction/fee-models/LivePolicy.d.ts.map +1 -0
  38. package/dist/types/src/transaction/fee-models/index.d.ts +1 -0
  39. package/dist/types/src/transaction/fee-models/index.d.ts.map +1 -1
  40. package/dist/types/src/wallet/WalletClient.d.ts +1 -1
  41. package/dist/types/src/wallet/WalletClient.d.ts.map +1 -1
  42. package/dist/types/src/wallet/substrates/WalletWireProcessor.d.ts.map +1 -1
  43. package/dist/types/src/wallet/substrates/WalletWireTransceiver.d.ts.map +1 -1
  44. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  45. package/dist/umd/bundle.js +3 -3
  46. package/dist/umd/bundle.js.map +1 -1
  47. package/docs/reference/transaction.md +73 -55
  48. package/docs/reference/wallet.md +1 -1
  49. package/package.json +1 -1
  50. package/src/transaction/Beef.ts +28 -2
  51. package/src/transaction/Transaction.ts +43 -40
  52. package/src/transaction/fee-models/LivePolicy.ts +97 -0
  53. package/src/transaction/fee-models/__tests/LivePolicy.test.ts +148 -0
  54. package/src/transaction/fee-models/index.ts +1 -0
  55. package/src/wallet/WalletClient.ts +50 -51
  56. package/src/wallet/substrates/WalletWireProcessor.ts +21 -0
  57. package/src/wallet/substrates/WalletWireTransceiver.ts +22 -10
@@ -58,6 +58,7 @@ export default class WalletClient implements WalletInterface {
58
58
  | 'window.CWI'
59
59
  | 'json-api'
60
60
  | 'react-native'
61
+ | 'secure-json-api'
61
62
  | WalletInterface = 'auto',
62
63
  originator?: OriginatorDomainNameStringUnder250Bytes
63
64
  ) {
@@ -68,6 +69,7 @@ export default class WalletClient implements WalletInterface {
68
69
  if (substrate === 'XDM') substrate = new XDMSubstrate()
69
70
  if (substrate === 'json-api') substrate = new HTTPWalletJSON(originator)
70
71
  if (substrate === 'react-native') substrate = new ReactNativeWebView(originator)
72
+ if (substrate === 'secure-json-api') substrate = new HTTPWalletJSON(originator, 'https://localhost:2121')
71
73
  this.substrate = substrate
72
74
  this.originator = originator
73
75
  }
@@ -76,61 +78,58 @@ export default class WalletClient implements WalletInterface {
76
78
  if (typeof this.substrate === 'object') {
77
79
  return // substrate is already connected
78
80
  }
79
- let sub: WalletInterface
80
- const checkSub = async (timeout?: number): Promise<void> => {
81
- let result
82
- if (typeof timeout === 'number') {
83
- result = await Promise.race([
84
- sub.getVersion({}),
85
- new Promise<never>((_resolve, reject) =>
86
- setTimeout(() => reject(new Error('Timed out.')), timeout)
87
- )
88
- ])
89
- } else {
90
- result = await sub.getVersion({})
91
- }
92
- if (typeof result !== 'object' || typeof result.version !== 'string') {
93
- throw new Error('Failed to use substrate.')
94
- }
95
- }
96
- try {
97
- sub = new WindowCWISubstrate()
98
- await checkSub()
99
- this.substrate = sub
100
- } catch (e) {
101
- // XDM failed, try the next one...
81
+
82
+ const attemptSubstrate = async (factory: () => WalletInterface, timeout?: number): Promise<{ success: boolean, sub?: WalletInterface }> => {
102
83
  try {
103
- sub = new XDMSubstrate()
104
- await checkSub(MAX_XDM_RESPONSE_WAIT)
105
- this.substrate = sub
106
- } catch (e) {
107
- // HTTP wire failed, move on...
108
- try {
109
- sub = new WalletWireTransceiver(new HTTPWalletWire(this.originator))
110
- await checkSub()
111
- this.substrate = sub
112
- } catch (e) {
113
- // HTTP Wire failed, attempt the next...
114
- try {
115
- sub = new HTTPWalletJSON(this.originator)
116
- await checkSub()
117
- this.substrate = sub
118
- } catch (e) {
119
- // HTTP JSON failed, attempt the next...
120
- try {
121
- sub = new ReactNativeWebView(this.originator)
122
- await checkSub()
123
- this.substrate = sub
124
- } catch (e) {
125
- // No comms. Tell the user to install a BSV wallet.
126
- throw new Error(
127
- 'No wallet available over any communication substrate. Install a BSV wallet today!'
128
- )
129
- }
130
- }
84
+ const sub = factory()
85
+ let result
86
+ if (typeof timeout === 'number') {
87
+ result = await Promise.race([
88
+ sub.getVersion({}),
89
+ new Promise<never>((_resolve, reject) =>
90
+ setTimeout(() => reject(new Error('Timed out.')), timeout)
91
+ )
92
+ ])
93
+ } else {
94
+ result = await sub.getVersion({})
95
+ }
96
+ if (typeof result !== 'object' || typeof result.version !== 'string') {
97
+ return { success: false }
131
98
  }
99
+ return { success: true, sub }
100
+ } catch {
101
+ return { success: false }
132
102
  }
133
103
  }
104
+
105
+ // Try fast substrates first
106
+ const fastAttempts = [
107
+ attemptSubstrate(() => new WindowCWISubstrate()),
108
+ attemptSubstrate(() => new HTTPWalletJSON(this.originator, 'https://localhost:2121')),
109
+ attemptSubstrate(() => new HTTPWalletJSON(this.originator)),
110
+ attemptSubstrate(() => new ReactNativeWebView(this.originator)),
111
+ attemptSubstrate(() => new WalletWireTransceiver(new HTTPWalletWire(this.originator)))
112
+ ]
113
+
114
+ const fastResults = await Promise.allSettled(fastAttempts)
115
+ const fastSuccessful = fastResults
116
+ .filter((r): r is PromiseFulfilledResult<{ success: boolean, sub?: WalletInterface }> => r.status === 'fulfilled' && r.value.success && r.value.sub !== undefined)
117
+ .map(r => r.value.sub as WalletInterface)
118
+
119
+ if (fastSuccessful.length > 0) {
120
+ this.substrate = fastSuccessful[0]
121
+ return
122
+ }
123
+
124
+ // Fall back to slower XDM substrate
125
+ const xdmResult = await attemptSubstrate(() => new XDMSubstrate(), MAX_XDM_RESPONSE_WAIT)
126
+ if (xdmResult.success && xdmResult.sub !== undefined) {
127
+ this.substrate = xdmResult.sub
128
+ } else {
129
+ throw new Error(
130
+ 'No wallet available over any communication substrate. Install a BSV wallet today!'
131
+ )
132
+ }
134
133
  }
135
134
 
136
135
  async createAction (args: CreateActionArgs): Promise<CreateActionResult> {
@@ -1782,6 +1782,27 @@ export default class WalletWireProcessor implements WalletWire {
1782
1782
  // Write certificate binary length and data
1783
1783
  resultWriter.writeVarIntNum(certBin.length)
1784
1784
  resultWriter.write(certBin)
1785
+
1786
+ if (cert.keyring && Object.keys(cert.keyring).length > 0) {
1787
+ resultWriter.writeInt8(1) // Flag indicating keyring is present
1788
+ const keyringEntries = Object.entries(cert.keyring)
1789
+ resultWriter.writeVarIntNum(keyringEntries.length)
1790
+ for (const [fieldName, fieldValue] of keyringEntries) {
1791
+ const fieldNameBytes = Utils.toArray(fieldName, 'utf8')
1792
+ resultWriter.writeVarIntNum(fieldNameBytes.length)
1793
+ resultWriter.write(fieldNameBytes)
1794
+
1795
+ const fieldValueBytes = Utils.toArray(fieldValue, 'base64')
1796
+ resultWriter.writeVarIntNum(fieldValueBytes.length)
1797
+ resultWriter.write(fieldValueBytes)
1798
+ }
1799
+ } else {
1800
+ resultWriter.writeInt8(0) // Flag indicating no keyring
1801
+ }
1802
+
1803
+ const verifierBytes = Utils.toArray(cert.verifier, 'hex')
1804
+ resultWriter.writeVarIntNum(verifierBytes.length)
1805
+ resultWriter.write(verifierBytes)
1785
1806
  }
1786
1807
 
1787
1808
  // Return the response
@@ -11,6 +11,7 @@ import {
11
11
  BooleanDefaultTrue,
12
12
  Byte,
13
13
  CertificateFieldNameUnder50Bytes,
14
+ CertificateResult,
14
15
  CreateActionArgs,
15
16
  CreateActionResult,
16
17
  DescriptionString5to50Bytes,
@@ -1672,22 +1673,33 @@ export default class WalletWireTransceiver implements WalletInterface {
1672
1673
  )
1673
1674
  const resultReader = new Utils.Reader(result)
1674
1675
  const totalCertificates = resultReader.readVarIntNum()
1675
- const certificates: Array<{
1676
- type: Base64String
1677
- subject: PubKeyHex
1678
- serialNumber: Base64String
1679
- certifier: PubKeyHex
1680
- revocationOutpoint: OutpointString
1681
- signature: HexString
1682
- fields: Record<CertificateFieldNameUnder50Bytes, Base64String>
1683
- }> = []
1676
+ const certificates: Array<CertificateResult> = []
1684
1677
  for (let i = 0; i < totalCertificates; i++) {
1685
1678
  const certificateLength = resultReader.readVarIntNum()
1686
1679
  const certificateBin = resultReader.read(certificateLength)
1687
1680
  const cert = Certificate.fromBinary(certificateBin)
1681
+ const keyringForVerifier: Record<string, string> = {}
1682
+ if (resultReader.readInt8() === 1) {
1683
+ const numFields = resultReader.readVarIntNum()
1684
+ for (let i = 0; i < numFields; i++) {
1685
+ const fieldKeyLength = resultReader.readVarIntNum()
1686
+ const fieldKey = Utils.toUTF8(resultReader.read(fieldKeyLength))
1687
+ const fieldValueLength = resultReader.readVarIntNum()
1688
+ keyringForVerifier[fieldKey] = Utils.toBase64(
1689
+ resultReader.read(fieldValueLength)
1690
+ )
1691
+ }
1692
+ }
1693
+ const verifierLength = resultReader.readVarIntNum()
1694
+ let verifier: string | undefined = undefined
1695
+ if (verifierLength > 0) {
1696
+ verifier = Utils.toUTF8(resultReader.read(verifierLength))
1697
+ }
1688
1698
  certificates.push({
1689
1699
  ...cert,
1690
- signature: cert.signature as string
1700
+ signature: cert.signature as string,
1701
+ keyring: keyringForVerifier,
1702
+ verifier,
1691
1703
  })
1692
1704
  }
1693
1705
  return {