@florent-uzio/custody 2.3.0 → 2.5.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 (79) hide show
  1. package/README.md +1 -6
  2. package/dist/constants/urls.d.ts +24 -0
  3. package/dist/constants/urls.d.ts.map +1 -1
  4. package/dist/constants/urls.js +26 -0
  5. package/dist/constants/urls.js.map +1 -1
  6. package/dist/index.d.ts +6 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/models/capabilities.generated.d.ts +51 -0
  11. package/dist/models/capabilities.generated.d.ts.map +1 -0
  12. package/dist/models/capabilities.generated.js +9770 -0
  13. package/dist/models/capabilities.generated.js.map +1 -0
  14. package/dist/models/custody-types.d.ts +7314 -3341
  15. package/dist/models/custody-types.d.ts.map +1 -1
  16. package/dist/models/custody-types.js +2 -2
  17. package/dist/namespaces/accounts.d.ts.map +1 -1
  18. package/dist/namespaces/accounts.js +2 -1
  19. package/dist/namespaces/accounts.js.map +1 -1
  20. package/dist/namespaces/domains.d.ts +34 -0
  21. package/dist/namespaces/domains.d.ts.map +1 -1
  22. package/dist/namespaces/domains.js +34 -0
  23. package/dist/namespaces/domains.js.map +1 -1
  24. package/dist/ripple-custody.d.ts +9 -0
  25. package/dist/ripple-custody.d.ts.map +1 -1
  26. package/dist/ripple-custody.js +37 -3
  27. package/dist/ripple-custody.js.map +1 -1
  28. package/dist/ripple-custody.types.d.ts +33 -0
  29. package/dist/ripple-custody.types.d.ts.map +1 -1
  30. package/dist/services/index.d.ts +2 -0
  31. package/dist/services/index.d.ts.map +1 -1
  32. package/dist/services/index.js +2 -0
  33. package/dist/services/index.js.map +1 -1
  34. package/dist/services/omnibus/index.d.ts +2 -0
  35. package/dist/services/omnibus/index.d.ts.map +1 -0
  36. package/dist/services/omnibus/index.js +2 -0
  37. package/dist/services/omnibus/index.js.map +1 -0
  38. package/dist/services/omnibus/omnibus.types.d.ts +37 -0
  39. package/dist/services/omnibus/omnibus.types.d.ts.map +1 -0
  40. package/dist/services/omnibus/omnibus.types.js +2 -0
  41. package/dist/services/omnibus/omnibus.types.js.map +1 -0
  42. package/dist/services/sponsors/index.d.ts +2 -0
  43. package/dist/services/sponsors/index.d.ts.map +1 -0
  44. package/dist/services/sponsors/index.js +2 -0
  45. package/dist/services/sponsors/index.js.map +1 -0
  46. package/dist/services/sponsors/sponsors.types.d.ts +36 -0
  47. package/dist/services/sponsors/sponsors.types.d.ts.map +1 -0
  48. package/dist/services/sponsors/sponsors.types.js +2 -0
  49. package/dist/services/sponsors/sponsors.types.js.map +1 -0
  50. package/dist/services/xrpl/index.d.ts +1 -0
  51. package/dist/services/xrpl/index.d.ts.map +1 -1
  52. package/dist/services/xrpl/index.js +1 -0
  53. package/dist/services/xrpl/index.js.map +1 -1
  54. package/dist/services/xrpl/xrpl.builders.d.ts.map +1 -1
  55. package/dist/services/xrpl/xrpl.builders.js +2 -0
  56. package/dist/services/xrpl/xrpl.builders.js.map +1 -1
  57. package/dist/services/xrpl/xrpl.service.d.ts +3 -1
  58. package/dist/services/xrpl/xrpl.service.d.ts.map +1 -1
  59. package/dist/services/xrpl/xrpl.service.js +11 -1
  60. package/dist/services/xrpl/xrpl.service.js.map +1 -1
  61. package/dist/services/xrpl/xrpl.types.d.ts +4 -0
  62. package/dist/services/xrpl/xrpl.types.d.ts.map +1 -1
  63. package/dist/services/xrpl/xrpl.validators.d.ts +23 -0
  64. package/dist/services/xrpl/xrpl.validators.d.ts.map +1 -0
  65. package/dist/services/xrpl/xrpl.validators.js +43 -0
  66. package/dist/services/xrpl/xrpl.validators.js.map +1 -0
  67. package/dist/transport/typed-transport.d.ts +5 -3
  68. package/dist/transport/typed-transport.d.ts.map +1 -1
  69. package/dist/transport/typed-transport.js +18 -4
  70. package/dist/transport/typed-transport.js.map +1 -1
  71. package/dist/versioning/detect.d.ts +25 -0
  72. package/dist/versioning/detect.d.ts.map +1 -0
  73. package/dist/versioning/detect.js +45 -0
  74. package/dist/versioning/detect.js.map +1 -0
  75. package/dist/versioning/version-guard.d.ts +101 -0
  76. package/dist/versioning/version-guard.d.ts.map +1 -0
  77. package/dist/versioning/version-guard.js +181 -0
  78. package/dist/versioning/version-guard.js.map +1 -0
  79. package/package.json +5 -4
@@ -0,0 +1,181 @@
1
+ import { CAPABILITIES } from "../models/capabilities.generated.js";
2
+ import { CustodyError } from "../models/index.js";
3
+ /**
4
+ * Thrown when a call needs a capability the resolved backend version does not
5
+ * support. Extends {@link CustodyError} so existing `catch (CustodyError)`
6
+ * handlers still catch it.
7
+ */
8
+ export class UnsupportedInVersionError extends CustodyError {
9
+ capability;
10
+ kind;
11
+ appVersion;
12
+ sdkMethod;
13
+ constructor(args) {
14
+ super({
15
+ reason: `${args.sdkMethod} requires ${args.kind} "${args.capability}", which is not ` +
16
+ `available on the resolved backend version ${args.appVersion}.`,
17
+ });
18
+ this.name = "UnsupportedInVersionError";
19
+ this.capability = args.capability;
20
+ this.kind = args.kind;
21
+ this.appVersion = args.appVersion;
22
+ this.sdkMethod = args.sdkMethod;
23
+ }
24
+ }
25
+ /**
26
+ * Maps an XRPL operation `type` (the discriminator of `Core_XrplOperation`) to
27
+ * its component-schema name. The generated union members are named
28
+ * `Core_XrplOperation_<type>` exactly, so no lookup table is needed.
29
+ */
30
+ export function xrplOperationSchema(operationType) {
31
+ return `Core_XrplOperation_${operationType}`;
32
+ }
33
+ /**
34
+ * Builds the capability set for an explicitly-requested app version from the
35
+ * bundled capability data. Throws when the version is not bundled.
36
+ */
37
+ export function resolveExplicitCapabilities(apiVersion) {
38
+ const entry = CAPABILITIES[apiVersion];
39
+ if (!entry) {
40
+ const known = Object.keys(CAPABILITIES).join(", ");
41
+ throw new CustodyError({
42
+ reason: `Unknown apiVersion "${apiVersion}". Known versions: ${known}.`,
43
+ });
44
+ }
45
+ return {
46
+ appVersion: apiVersion,
47
+ endpoints: new Set(entry.endpoints),
48
+ schemas: new Set(entry.schemas),
49
+ };
50
+ }
51
+ /**
52
+ * Runtime guard that blocks calls the resolved backend version cannot serve.
53
+ *
54
+ * When constructed with no resolved capabilities it is a **pass-through**: every
55
+ * check is a no-op (fail-open). The backend remains the ultimate authority.
56
+ */
57
+ export class VersionGuard {
58
+ resolved;
59
+ settled;
60
+ pending;
61
+ failedOpen = false;
62
+ warned = false;
63
+ resolver;
64
+ onFailOpen;
65
+ /**
66
+ * Construct a guard with capabilities already resolved (or `undefined` for a
67
+ * pass-through guard). Pass a `resolver` for lazy resolution, or use
68
+ * {@link VersionGuard.deferred}. `onFailOpen` runs once the first time the
69
+ * guard passes a call through because no version could be resolved.
70
+ */
71
+ constructor(resolved, resolver, onFailOpen) {
72
+ this.resolved = resolved;
73
+ this.resolver = resolver;
74
+ this.onFailOpen = onFailOpen;
75
+ this.settled = resolver === undefined;
76
+ }
77
+ /**
78
+ * Construct a guard whose capabilities are resolved lazily on first use (e.g.
79
+ * by fetching the live instance spec). The resolver runs at most once per
80
+ * successful resolution; concurrent triggers share a single invocation.
81
+ */
82
+ static deferred(resolver, onFailOpen) {
83
+ return new VersionGuard(undefined, resolver, onFailOpen);
84
+ }
85
+ /** Whether the guard has a resolved version and is actively gating. */
86
+ get isActive() {
87
+ return this.resolved !== undefined;
88
+ }
89
+ /**
90
+ * Resolve the capability set if not already resolved. Idempotent and
91
+ * concurrency-safe: parallel calls share one in-flight resolution. On failure
92
+ * the error propagates and a later call retries.
93
+ */
94
+ async ensureResolved() {
95
+ if (this.settled)
96
+ return;
97
+ if (!this.pending) {
98
+ const resolver = this.resolver;
99
+ this.pending = resolver().then((caps) => {
100
+ this.resolved = caps;
101
+ this.settled = true;
102
+ }, (error) => {
103
+ this.pending = undefined;
104
+ throw error;
105
+ });
106
+ }
107
+ return this.pending;
108
+ }
109
+ /** Resolves (detecting if needed) then asserts the endpoint capability. */
110
+ async checkEndpoint(httpMethod, pathTemplate, sdkMethod) {
111
+ if (await this.gatingActive()) {
112
+ this.assertEndpoint(httpMethod, pathTemplate, sdkMethod);
113
+ }
114
+ }
115
+ /** Resolves (detecting if needed) then asserts the feature capability. */
116
+ async checkFeature(schemaName, sdkMethod) {
117
+ if (await this.gatingActive()) {
118
+ this.assertFeature(schemaName, sdkMethod);
119
+ }
120
+ }
121
+ /**
122
+ * Whether gating is active for the call path. Resolves the version on first
123
+ * use; if no version can be resolved — detection failed, or the guard is a
124
+ * pass-through — it **fails open**: returns `false` (call passes through) and
125
+ * fires `onFailOpen` once. The unresolved state is cached, so detection is
126
+ * not re-attempted on every call. `ensureResolved`/`ready()` keep surfacing
127
+ * detection errors independently.
128
+ */
129
+ async gatingActive() {
130
+ if (this.failedOpen)
131
+ return false;
132
+ try {
133
+ await this.ensureResolved();
134
+ }
135
+ catch {
136
+ return this.enterFailOpen();
137
+ }
138
+ if (!this.resolved)
139
+ return this.enterFailOpen();
140
+ return true;
141
+ }
142
+ enterFailOpen() {
143
+ this.failedOpen = true;
144
+ if (!this.warned) {
145
+ this.warned = true;
146
+ this.onFailOpen?.();
147
+ }
148
+ return false;
149
+ }
150
+ /**
151
+ * Asserts the resolved version serves `METHOD /pathTemplate`.
152
+ * @param sdkMethod - Label for the error (defaults to the HTTP descriptor).
153
+ */
154
+ assertEndpoint(httpMethod, pathTemplate, sdkMethod) {
155
+ if (!this.resolved)
156
+ return;
157
+ const capability = `${httpMethod.toUpperCase()} ${pathTemplate}`;
158
+ if (!this.resolved.endpoints.has(capability)) {
159
+ throw new UnsupportedInVersionError({
160
+ capability,
161
+ kind: "endpoint",
162
+ appVersion: this.resolved.appVersion,
163
+ sdkMethod: sdkMethod ?? capability,
164
+ });
165
+ }
166
+ }
167
+ /** Asserts the resolved version defines the component schema `schemaName`. */
168
+ assertFeature(schemaName, sdkMethod) {
169
+ if (!this.resolved)
170
+ return;
171
+ if (!this.resolved.schemas.has(schemaName)) {
172
+ throw new UnsupportedInVersionError({
173
+ capability: schemaName,
174
+ kind: "feature",
175
+ appVersion: this.resolved.appVersion,
176
+ sdkMethod,
177
+ });
178
+ }
179
+ }
180
+ }
181
+ //# sourceMappingURL=version-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version-guard.js","sourceRoot":"","sources":["../../src/versioning/version-guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwB,MAAM,qCAAqC,CAAA;AACxF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAkBjD;;;;GAIG;AACH,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IACzC,UAAU,CAAQ;IAClB,IAAI,CAAgB;IACpB,UAAU,CAAQ;IAClB,SAAS,CAAQ;IAEjC,YAAY,IAKX;QACC,KAAK,CAAC;YACJ,MAAM,EACJ,GAAG,IAAI,CAAC,SAAS,aAAa,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,UAAU,kBAAkB;gBAC7E,6CAA6C,IAAI,CAAC,UAAU,GAAG;SAClE,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAA;QACvC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAA;IACjC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,aAAqB;IACvD,OAAO,sBAAsB,aAAa,EAAE,CAAA;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B,CAAC,UAAkB;IAC5D,MAAM,KAAK,GAAG,YAAY,CAAC,UAA6B,CAAC,CAAA;IACzD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,IAAI,YAAY,CAAC;YACrB,MAAM,EAAE,uBAAuB,UAAU,sBAAsB,KAAK,GAAG;SACxE,CAAC,CAAA;IACJ,CAAC;IACD,OAAO;QACL,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC;QACnC,OAAO,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC;KAChC,CAAA;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IACf,QAAQ,CAAkC;IAC1C,OAAO,CAAS;IAChB,OAAO,CAAgB;IACvB,UAAU,GAAG,KAAK,CAAA;IAClB,MAAM,GAAG,KAAK,CAAA;IACL,QAAQ,CAAkD;IAC1D,UAAU,CAAa;IAExC;;;;;OAKG;IACH,YACE,QAA0C,EAC1C,QAA0D,EAC1D,UAAuB;QAEvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,QAAQ,KAAK,SAAS,CAAA;IACvC,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,QAAQ,CACb,QAAyD,EACzD,UAAuB;QAEvB,OAAO,IAAI,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC1D,CAAC;IAED,uEAAuE;IACvE,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAA;IACpC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAM;QACxB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAS,CAAA;YAC/B,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,IAAI,CAC5B,CAAC,IAAI,EAAE,EAAE;gBACP,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;gBACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;YACrB,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;gBACjB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;gBACxB,MAAM,KAAK,CAAA;YACb,CAAC,CACF,CAAA;QACH,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,aAAa,CAAC,UAAkB,EAAE,YAAoB,EAAE,SAAkB;QAC9E,IAAI,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,YAAY,EAAE,SAAS,CAAC,CAAA;QAC1D,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,YAAY,CAAC,UAAkB,EAAE,SAAiB;QACtD,IAAI,MAAM,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YAC9B,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,KAAK,CAAC,YAAY;QACxB,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,KAAK,CAAA;QACjC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,cAAc,EAAE,CAAA;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC,aAAa,EAAE,CAAA;QAC7B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,aAAa,EAAE,CAAA;QAC/C,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAA;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;YAClB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAA;QACrB,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,UAAkB,EAAE,YAAoB,EAAE,SAAkB;QACzE,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAM;QAC1B,MAAM,UAAU,GAAG,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,YAAY,EAAE,CAAA;QAChE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,yBAAyB,CAAC;gBAClC,UAAU;gBACV,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU;gBACpC,SAAS,EAAE,SAAS,IAAI,UAAU;aACnC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,aAAa,CAAC,UAAkB,EAAE,SAAiB;QACjD,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,OAAM;QAC1B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,yBAAyB,CAAC;gBAClC,UAAU,EAAE,UAAU;gBACtB,IAAI,EAAE,SAAS;gBACf,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU;gBACpC,SAAS;aACV,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@florent-uzio/custody",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "An SDK to interact with the Ripple Custody API",
5
5
  "keywords": [
6
6
  "Ripple Custody",
@@ -36,8 +36,9 @@
36
36
  "check-format": "prettier --check .",
37
37
  "ci": "npm run build && npm run check-format && npm run test",
38
38
  "dev": "vitest",
39
+ "fetch:openapi-spec": "node ./scripts/fetch-openapi-release.mjs",
39
40
  "format": "prettier --write .",
40
- "generate:custody-types": "npx openapi-typescript ./openapi/Ripple-Custody-v1-OpenAPI.json -o ./src/models/custody-types.ts && prettier --write ./src/models/custody-types.ts",
41
+ "generate:custody-types": "node ./scripts/generate-custody-types/generate.mjs && prettier --write ./src/models/custody-types.ts ./src/models/capabilities.generated.ts",
41
42
  "local-release": "changeset version && changeset publish",
42
43
  "prepare": "npm run build",
43
44
  "release": "changeset publish",
@@ -64,8 +65,8 @@
64
65
  "@vitest/ui": "^3.1.4",
65
66
  "dotenv": "^16.4.7",
66
67
  "openapi-typescript": "^7.9.1",
67
- "prettier": "^3.5.3",
68
- "prettier-plugin-organize-imports": "^4.1.0",
68
+ "prettier": "^3.9.5",
69
+ "prettier-plugin-organize-imports": "^4.3.0",
69
70
  "ts-node": "^10.9.2",
70
71
  "typescript": "^5.8.2",
71
72
  "vitest": "^3.1.4"