@bsv/sdk 2.0.15 → 2.1.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 (40) hide show
  1. package/dist/cjs/package.json +14 -13
  2. package/dist/cjs/src/kvstore/GlobalKVStore.js +16 -3
  3. package/dist/cjs/src/kvstore/GlobalKVStore.js.map +1 -1
  4. package/dist/cjs/src/kvstore/types.js.map +1 -1
  5. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  6. package/dist/esm/src/kvstore/GlobalKVStore.js +16 -3
  7. package/dist/esm/src/kvstore/GlobalKVStore.js.map +1 -1
  8. package/dist/esm/src/kvstore/types.js.map +1 -1
  9. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  10. package/dist/types/src/kvstore/GlobalKVStore.d.ts +7 -0
  11. package/dist/types/src/kvstore/GlobalKVStore.d.ts.map +1 -1
  12. package/dist/types/src/kvstore/types.d.ts +2 -1
  13. package/dist/types/src/kvstore/types.d.ts.map +1 -1
  14. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  15. package/dist/umd/bundle.js +1 -1
  16. package/docs/reference/primitives.md +0 -1
  17. package/docs/reference/script.md +0 -7
  18. package/docs/reference/transaction.md +2 -2
  19. package/package.json +29 -28
  20. package/src/kvstore/GlobalKVStore.ts +19 -3
  21. package/src/kvstore/__tests/GlobalKVStore.test.ts +24 -1
  22. package/src/kvstore/types.ts +2 -1
  23. package/docs/swagger/dist/LICENSE +0 -21
  24. package/docs/swagger/dist/favicon-16x16.png +0 -0
  25. package/docs/swagger/dist/favicon-32x32.png +0 -0
  26. package/docs/swagger/dist/index.css +0 -16
  27. package/docs/swagger/dist/oauth2-redirect.html +0 -79
  28. package/docs/swagger/dist/swagger-initializer.js +0 -20
  29. package/docs/swagger/dist/swagger-ui-bundle.js +0 -2
  30. package/docs/swagger/dist/swagger-ui-bundle.js.map +0 -1
  31. package/docs/swagger/dist/swagger-ui-es-bundle-core.js +0 -3
  32. package/docs/swagger/dist/swagger-ui-es-bundle-core.js.map +0 -1
  33. package/docs/swagger/dist/swagger-ui-es-bundle.js +0 -2
  34. package/docs/swagger/dist/swagger-ui-es-bundle.js.map +0 -1
  35. package/docs/swagger/dist/swagger-ui-standalone-preset.js +0 -2
  36. package/docs/swagger/dist/swagger-ui-standalone-preset.js.map +0 -1
  37. package/docs/swagger/dist/swagger-ui.css +0 -3
  38. package/docs/swagger/dist/swagger-ui.css.map +0 -1
  39. package/docs/swagger/dist/swagger-ui.js +0 -2
  40. package/docs/swagger/dist/swagger-ui.js.map +0 -1
@@ -4948,7 +4948,6 @@ export default class TransactionSignature extends Signature {
4948
4948
  static formatBip143(params: TransactionSignatureFormatParams): Uint8Array
4949
4949
  static format(params: TransactionSignatureFormatParams): number[]
4950
4950
  static formatBytes(params: TransactionSignatureFormatParams): Uint8Array
4951
- static usesOtdaSingleBug(params: TransactionSignatureFormatParams): boolean
4952
4951
  static fromChecksigFormat(buf: number[]): TransactionSignature
4953
4952
  constructor(r: BigNumber, s: BigNumber, scope: number)
4954
4953
  public hasLowS(): boolean
@@ -45,7 +45,6 @@ A representation of a chunk of a script, which includes an opcode. For push oper
45
45
  export default interface ScriptChunk {
46
46
  op: number;
47
47
  data?: number[];
48
- invalidLength?: boolean;
49
48
  }
50
49
  ```
51
50
 
@@ -805,14 +804,10 @@ export default class Spend {
805
804
  stack: number[][];
806
805
  altStack: number[][];
807
806
  ifStack: boolean[];
808
- elseStack: boolean[];
809
807
  memoryLimit: number;
810
808
  stackMem: number;
811
809
  altStackMem: number;
812
810
  isRelaxedOverride: boolean;
813
- verifyFlags?: Set<string>;
814
- executedOpCount: number;
815
- returningFromConditional: boolean;
816
811
  constructor(params: {
817
812
  sourceTXID: string;
818
813
  sourceOutputIndex: number;
@@ -827,7 +822,6 @@ export default class Spend {
827
822
  lockTime: number;
828
823
  memoryLimit?: number;
829
824
  isRelaxed?: boolean;
830
- verifyFlags?: string | string[];
831
825
  })
832
826
  reset(): void
833
827
  step(): boolean
@@ -854,7 +848,6 @@ constructor(params: {
854
848
  lockTime: number;
855
849
  memoryLimit?: number;
856
850
  isRelaxed?: boolean;
857
- verifyFlags?: string | string[];
858
851
  })
859
852
  ```
860
853
  See also: [LockingScript](./script.md#class-lockingscript), [TransactionInput](./transaction.md#interface-transactioninput), [TransactionOutput](./transaction.md#interface-transactionoutput), [UnlockingScript](./script.md#class-unlockingscript)
@@ -2455,8 +2455,8 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
2455
2455
  ### Function: defaultHttpClient
2456
2456
 
2457
2457
  Returns a default HttpClient implementation based on the environment that it is run on.
2458
- This method will attempt to use `window.fetch` if available (in browser environments),
2459
- then `globalThis.fetch` (service workers, Deno, Node 18+), then the Node `https` module.
2458
+ This method will attempt to use `window.fetch` if available (in browser environments).
2459
+ If running in a Node environment, it falls back to using the Node `https` module
2460
2460
 
2461
2461
  ```ts
2462
2462
  export function defaultHttpClient(): HttpClient
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "2.0.15",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -218,24 +218,10 @@
218
218
  "import": "./dist/umd/bundle.js"
219
219
  }
220
220
  },
221
- "scripts": {
222
- "test": "npm run build && jest",
223
- "test:watch": "npm run build && jest --watch",
224
- "test:coverage": "npm run build && jest --coverage",
225
- "lint:ci": "ts-standard src/**/*.ts",
226
- "lint": "ts-standard --fix src/**/*.ts",
227
- "build": "npm run build:ts && npm run build:umd",
228
- "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
229
- "build:umd": "rspack --config rspack.config.js",
230
- "dev": "tsc -b -w",
231
- "prepublish": "npm run build",
232
- "doc": "ts2md",
233
- "docs:serve": "mkdocs serve",
234
- "docs:build": "mkdocs build"
235
- },
236
221
  "repository": {
237
222
  "type": "git",
238
- "url": "git+https://github.com/bsv-blockchain/ts-sdk.git"
223
+ "url": "git+https://github.com/bsv-blockchain/ts-stack.git",
224
+ "directory": "packages/sdk"
239
225
  },
240
226
  "keywords": [
241
227
  "BSV",
@@ -247,32 +233,47 @@
247
233
  "author": "BSV Blockchain Association",
248
234
  "license": "SEE LICENSE IN LICENSE.txt",
249
235
  "bugs": {
250
- "url": "https://github.com/bsv-blockchain/ts-sdk/issues"
236
+ "url": "https://github.com/bsv-blockchain/ts-stack/issues"
251
237
  },
252
- "homepage": "https://github.com/bsv-blockchain/ts-sdk#readme",
238
+ "homepage": "https://github.com/bsv-blockchain/ts-stack/tree/main/packages/sdk#readme",
253
239
  "devDependencies": {
254
- "@eslint/js": "^10.0.1",
240
+ "@eslint/js": "^9.39.1",
255
241
  "@jest/globals": "^30.3.0",
256
242
  "@rspack/cli": "^2.0.0",
257
- "@rspack/core": "^2.0.0",
243
+ "@rspack/core": "^1.6.1",
258
244
  "@types/jest": "^30.0.0",
259
- "@types/node": "^25.6.0",
260
- "eslint": "^10.2.1",
261
- "globals": "^17.5.0",
245
+ "@types/node": "^24.10.1",
246
+ "eslint": "^9.39.1",
247
+ "globals": "^16.5.0",
262
248
  "jest": "^30.3.0",
263
249
  "jest-environment-jsdom": "^30.3.0",
264
250
  "ts-jest": "^29.4.9",
265
- "ts-loader": "^9.5.7",
251
+ "ts-loader": "^9.5.4",
266
252
  "ts-standard": "^12.0.2",
267
253
  "ts2md": "^0.2.8",
268
254
  "tsconfig-to-dual-package": "^1.2.0",
269
- "typescript": "^6.0.3",
270
- "typescript-eslint": "^8.59.0"
255
+ "typescript": "^5.9.3",
256
+ "typescript-eslint": "^8.46.4"
271
257
  },
272
258
  "ts-standard": {
273
259
  "project": "tsconfig.eslint.json",
274
260
  "ignore": [
275
261
  "dist"
276
262
  ]
263
+ },
264
+ "scripts": {
265
+ "test": "npm run build && jest",
266
+ "test:watch": "npm run build && jest --watch",
267
+ "test:coverage": "npm run build && jest --coverage --watchman=false",
268
+ "lint:ci": "ts-standard src/**/*.ts",
269
+ "lint": "ts-standard --fix src/**/*.ts",
270
+ "build": "npm run build:ts && npm run build:umd",
271
+ "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
272
+ "build:umd": "rspack --config rspack.config.js",
273
+ "dev": "tsc -b -w",
274
+ "prepublish": "npm run build",
275
+ "doc": "ts2md",
276
+ "docs:serve": "mkdocs serve",
277
+ "docs:build": "mkdocs build"
277
278
  }
278
- }
279
+ }
@@ -106,9 +106,7 @@ export class GlobalKVStore {
106
106
  * @returns {Promise<KVStoreEntry | KVStoreEntry[] | undefined>} Single entry for key+controller queries, array for all other queries
107
107
  */
108
108
  async get (query: KVStoreQuery, options: KVStoreGetOptions = {}): Promise<KVStoreEntry | KVStoreEntry[] | undefined> {
109
- if (Object.keys(query).length === 0) {
110
- throw new Error('Must specify either key, controller, or protocolID')
111
- }
109
+ this.validateQuerySelectors(query)
112
110
  if (query.key != null && query.controller != null) {
113
111
  // Specific key+controller query - return single entry
114
112
  const entries = await this.queryOverlay(query, options)
@@ -117,6 +115,24 @@ export class GlobalKVStore {
117
115
  return await this.queryOverlay(query, options)
118
116
  }
119
117
 
118
+ /**
119
+ * Ensures lookup pagination and ordering options are only used with a real KV selector.
120
+ *
121
+ * @param {KVStoreQuery} query - Query parameters sent to overlay.
122
+ * @throws {Error} If the query does not include a valid selector.
123
+ */
124
+ private validateQuerySelectors (query: KVStoreQuery): void {
125
+ const hasSelector =
126
+ (typeof query.key === 'string' && query.key.length > 0) ||
127
+ (typeof query.controller === 'string' && query.controller.length > 0) ||
128
+ (Array.isArray(query.protocolID) && query.protocolID.length === 2) ||
129
+ (Array.isArray(query.tags) && query.tags.length > 0)
130
+
131
+ if (!hasSelector) {
132
+ throw new Error('Must specify at least one selector: key, controller, protocolID, or tags')
133
+ }
134
+ }
135
+
120
136
  /**
121
137
  * Sets a key-value pair. The current user (wallet identity) becomes the controller.
122
138
  *
@@ -577,7 +577,30 @@ describe('GlobalKVStore', () => {
577
577
 
578
578
  describe('sad paths', () => {
579
579
  it('rejects when no query parameters provided', async () => {
580
- await expect(kvStore.get({})).rejects.toThrow('Must specify either key, controller, or protocolID')
580
+ await expect(kvStore.get({})).rejects.toThrow(
581
+ 'Must specify at least one selector: key, controller, protocolID, or tags'
582
+ )
583
+ })
584
+
585
+ it('rejects pagination-only queries before resolving overlay hosts', async () => {
586
+ await expect(kvStore.get({ limit: 10 })).rejects.toThrow(
587
+ 'Must specify at least one selector: key, controller, protocolID, or tags'
588
+ )
589
+ expect(mockResolver.query).not.toHaveBeenCalled()
590
+ })
591
+
592
+ it('rejects ordering-only queries before resolving overlay hosts', async () => {
593
+ await expect(kvStore.get({ sortOrder: 'desc' })).rejects.toThrow(
594
+ 'Must specify at least one selector: key, controller, protocolID, or tags'
595
+ )
596
+ expect(mockResolver.query).not.toHaveBeenCalled()
597
+ })
598
+
599
+ it('rejects empty tag selector queries before resolving overlay hosts', async () => {
600
+ await expect(kvStore.get({ tags: [] })).rejects.toThrow(
601
+ 'Must specify at least one selector: key, controller, protocolID, or tags'
602
+ )
603
+ expect(mockResolver.query).not.toHaveBeenCalled()
581
604
  })
582
605
 
583
606
  it('propagates overlay errors', async () => {
@@ -37,7 +37,8 @@ export interface KVStoreConfig {
37
37
 
38
38
  /**
39
39
  * Query parameters for KVStore lookups from overlay services.
40
- * Used when searching for existing key-value pairs in the network.
40
+ * Must include at least one selector: key, controller, protocolID, or non-empty tags.
41
+ * Pagination and ordering fields only refine selector-based lookups.
41
42
  */
42
43
  export interface KVStoreQuery {
43
44
  key?: string
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Peter Evans
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
Binary file
Binary file
@@ -1,16 +0,0 @@
1
- html {
2
- box-sizing: border-box;
3
- overflow: -moz-scrollbars-vertical;
4
- overflow-y: scroll;
5
- }
6
-
7
- *,
8
- *:before,
9
- *:after {
10
- box-sizing: inherit;
11
- }
12
-
13
- body {
14
- margin: 0;
15
- background: #fafafa;
16
- }
@@ -1,79 +0,0 @@
1
- <!doctype html>
2
- <html lang="en-US">
3
- <head>
4
- <title>Swagger UI: OAuth2 Redirect</title>
5
- </head>
6
- <body>
7
- <script>
8
- 'use strict';
9
- function run () {
10
- var oauth2 = window.opener.swaggerUIRedirectOauth2;
11
- var sentState = oauth2.state;
12
- var redirectUrl = oauth2.redirectUrl;
13
- var isValid, qp, arr;
14
-
15
- if (/code|token|error/.test(window.location.hash)) {
16
- qp = window.location.hash.substring(1).replace('?', '&');
17
- } else {
18
- qp = location.search.substring(1);
19
- }
20
-
21
- arr = qp.split("&");
22
- arr.forEach(function (v,i,_arr) { _arr[i] = '"' + v.replace('=', '":"') + '"';});
23
- qp = qp ? JSON.parse('{' + arr.join() + '}',
24
- function (key, value) {
25
- return key === "" ? value : decodeURIComponent(value);
26
- }
27
- ) : {};
28
-
29
- isValid = qp.state === sentState;
30
-
31
- if ((
32
- oauth2.auth.schema.get("flow") === "accessCode" ||
33
- oauth2.auth.schema.get("flow") === "authorizationCode" ||
34
- oauth2.auth.schema.get("flow") === "authorization_code"
35
- ) && !oauth2.auth.code) {
36
- if (!isValid) {
37
- oauth2.errCb({
38
- authId: oauth2.auth.name,
39
- source: "auth",
40
- level: "warning",
41
- message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
42
- });
43
- }
44
-
45
- if (qp.code) {
46
- delete oauth2.state;
47
- oauth2.auth.code = qp.code;
48
- oauth2.callback({auth: oauth2.auth, redirectUrl: redirectUrl});
49
- } else {
50
- let oauthErrorMsg;
51
- if (qp.error) {
52
- oauthErrorMsg = "["+qp.error+"]: " +
53
- (qp.error_description ? qp.error_description+ ". " : "no accessCode received from the server. ") +
54
- (qp.error_uri ? "More info: "+qp.error_uri : "");
55
- }
56
-
57
- oauth2.errCb({
58
- authId: oauth2.auth.name,
59
- source: "auth",
60
- level: "error",
61
- message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
62
- });
63
- }
64
- } else {
65
- oauth2.callback({auth: oauth2.auth, token: qp, isValid: isValid, redirectUrl: redirectUrl});
66
- }
67
- window.close();
68
- }
69
-
70
- if (document.readyState !== 'loading') {
71
- run();
72
- } else {
73
- document.addEventListener('DOMContentLoaded', function () {
74
- run();
75
- });
76
- }
77
- </script>
78
- </body>
79
- </html>
@@ -1,20 +0,0 @@
1
- window.onload = function() {
2
- //<editor-fold desc="Changeable Configuration Block">
3
-
4
- // the following lines will be replaced by docker/configurator, when it runs in a docker-container
5
- window.ui = SwaggerUIBundle({
6
- url: "swagger.yaml",
7
- dom_id: '#swagger-ui',
8
- deepLinking: true,
9
- presets: [
10
- SwaggerUIBundle.presets.apis,
11
- SwaggerUIStandalonePreset
12
- ],
13
- plugins: [
14
- SwaggerUIBundle.plugins.DownloadUrl
15
- ],
16
- layout: "StandaloneLayout"
17
- });
18
-
19
- //</editor-fold>
20
- };