@v3finance/core-sdk 0.1.0 → 0.2.1

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 (217) hide show
  1. package/CHANGELOG.md +441 -7
  2. package/README.md +219 -73
  3. package/dist/cjs/client.d.ts +67 -22
  4. package/dist/cjs/client.d.ts.map +1 -1
  5. package/dist/cjs/client.js +38 -2
  6. package/dist/cjs/client.js.map +1 -1
  7. package/dist/cjs/core/errors.d.ts +30 -10
  8. package/dist/cjs/core/errors.d.ts.map +1 -1
  9. package/dist/cjs/core/errors.js +47 -15
  10. package/dist/cjs/core/errors.js.map +1 -1
  11. package/dist/cjs/core/gated.d.ts +30 -6
  12. package/dist/cjs/core/gated.d.ts.map +1 -1
  13. package/dist/cjs/core/gated.js +21 -6
  14. package/dist/cjs/core/gated.js.map +1 -1
  15. package/dist/cjs/core/http.d.ts +12 -8
  16. package/dist/cjs/core/http.d.ts.map +1 -1
  17. package/dist/cjs/core/http.js +147 -43
  18. package/dist/cjs/core/http.js.map +1 -1
  19. package/dist/cjs/core/pagination.d.ts +28 -1
  20. package/dist/cjs/core/pagination.d.ts.map +1 -1
  21. package/dist/cjs/core/pagination.js +36 -1
  22. package/dist/cjs/core/pagination.js.map +1 -1
  23. package/dist/cjs/generated/operations.js +1 -1
  24. package/dist/cjs/generated/types.d.ts +965 -179
  25. package/dist/cjs/generated/types.d.ts.map +1 -1
  26. package/dist/cjs/index.d.ts +32 -8
  27. package/dist/cjs/index.d.ts.map +1 -1
  28. package/dist/cjs/index.js +12 -0
  29. package/dist/cjs/index.js.map +1 -1
  30. package/dist/cjs/resources/addresses.d.ts +23 -8
  31. package/dist/cjs/resources/addresses.d.ts.map +1 -1
  32. package/dist/cjs/resources/addresses.js +8 -1
  33. package/dist/cjs/resources/addresses.js.map +1 -1
  34. package/dist/cjs/resources/admin.d.ts +150 -25
  35. package/dist/cjs/resources/admin.d.ts.map +1 -1
  36. package/dist/cjs/resources/admin.js +94 -23
  37. package/dist/cjs/resources/admin.js.map +1 -1
  38. package/dist/cjs/resources/approvals.d.ts +46 -5
  39. package/dist/cjs/resources/approvals.d.ts.map +1 -1
  40. package/dist/cjs/resources/approvals.js +27 -4
  41. package/dist/cjs/resources/approvals.js.map +1 -1
  42. package/dist/cjs/resources/balances.d.ts +152 -16
  43. package/dist/cjs/resources/balances.d.ts.map +1 -1
  44. package/dist/cjs/resources/balances.js +9 -5
  45. package/dist/cjs/resources/balances.js.map +1 -1
  46. package/dist/cjs/resources/categories.d.ts +93 -21
  47. package/dist/cjs/resources/categories.d.ts.map +1 -1
  48. package/dist/cjs/resources/categories.js +65 -18
  49. package/dist/cjs/resources/categories.js.map +1 -1
  50. package/dist/cjs/resources/counterparties.d.ts +26 -3
  51. package/dist/cjs/resources/counterparties.d.ts.map +1 -1
  52. package/dist/cjs/resources/counterparties.js +17 -0
  53. package/dist/cjs/resources/counterparties.js.map +1 -1
  54. package/dist/cjs/resources/folders.d.ts +51 -10
  55. package/dist/cjs/resources/folders.d.ts.map +1 -1
  56. package/dist/cjs/resources/folders.js +36 -5
  57. package/dist/cjs/resources/folders.js.map +1 -1
  58. package/dist/cjs/resources/history.d.ts +20 -2
  59. package/dist/cjs/resources/history.d.ts.map +1 -1
  60. package/dist/cjs/resources/history.js.map +1 -1
  61. package/dist/cjs/resources/me.d.ts +27 -4
  62. package/dist/cjs/resources/me.d.ts.map +1 -1
  63. package/dist/cjs/resources/me.js +22 -1
  64. package/dist/cjs/resources/me.js.map +1 -1
  65. package/dist/cjs/resources/members.d.ts +19 -4
  66. package/dist/cjs/resources/members.d.ts.map +1 -1
  67. package/dist/cjs/resources/members.js +15 -6
  68. package/dist/cjs/resources/members.js.map +1 -1
  69. package/dist/cjs/resources/operations.d.ts +64 -8
  70. package/dist/cjs/resources/operations.d.ts.map +1 -1
  71. package/dist/cjs/resources/operations.js +26 -2
  72. package/dist/cjs/resources/operations.js.map +1 -1
  73. package/dist/cjs/resources/registries.d.ts +87 -9
  74. package/dist/cjs/resources/registries.d.ts.map +1 -1
  75. package/dist/cjs/resources/registries.js +54 -11
  76. package/dist/cjs/resources/registries.js.map +1 -1
  77. package/dist/cjs/resources/reports.d.ts +300 -41
  78. package/dist/cjs/resources/reports.d.ts.map +1 -1
  79. package/dist/cjs/resources/reports.js +135 -7
  80. package/dist/cjs/resources/reports.js.map +1 -1
  81. package/dist/cjs/resources/sharing.d.ts +61 -10
  82. package/dist/cjs/resources/sharing.d.ts.map +1 -1
  83. package/dist/cjs/resources/sharing.js +51 -4
  84. package/dist/cjs/resources/sharing.js.map +1 -1
  85. package/dist/cjs/resources/transfers.d.ts +44 -6
  86. package/dist/cjs/resources/transfers.d.ts.map +1 -1
  87. package/dist/cjs/resources/transfers.js +41 -3
  88. package/dist/cjs/resources/transfers.js.map +1 -1
  89. package/dist/cjs/resources/types.d.ts +16 -0
  90. package/dist/cjs/resources/types.d.ts.map +1 -1
  91. package/dist/cjs/units.d.ts.map +1 -1
  92. package/dist/cjs/units.js +18 -2
  93. package/dist/cjs/units.js.map +1 -1
  94. package/dist/cjs/version.d.ts +1 -1
  95. package/dist/cjs/version.js +1 -1
  96. package/dist/esm/client.d.ts +67 -22
  97. package/dist/esm/client.d.ts.map +1 -1
  98. package/dist/esm/client.js +38 -2
  99. package/dist/esm/client.js.map +1 -1
  100. package/dist/esm/core/errors.d.ts +30 -10
  101. package/dist/esm/core/errors.d.ts.map +1 -1
  102. package/dist/esm/core/errors.js +47 -15
  103. package/dist/esm/core/errors.js.map +1 -1
  104. package/dist/esm/core/gated.d.ts +30 -6
  105. package/dist/esm/core/gated.d.ts.map +1 -1
  106. package/dist/esm/core/gated.js +21 -6
  107. package/dist/esm/core/gated.js.map +1 -1
  108. package/dist/esm/core/http.d.ts +12 -8
  109. package/dist/esm/core/http.d.ts.map +1 -1
  110. package/dist/esm/core/http.js +148 -44
  111. package/dist/esm/core/http.js.map +1 -1
  112. package/dist/esm/core/pagination.d.ts +28 -1
  113. package/dist/esm/core/pagination.d.ts.map +1 -1
  114. package/dist/esm/core/pagination.js +36 -1
  115. package/dist/esm/core/pagination.js.map +1 -1
  116. package/dist/esm/generated/operations.js +1 -1
  117. package/dist/esm/generated/types.d.ts +965 -179
  118. package/dist/esm/generated/types.d.ts.map +1 -1
  119. package/dist/esm/index.d.ts +32 -8
  120. package/dist/esm/index.d.ts.map +1 -1
  121. package/dist/esm/index.js +17 -5
  122. package/dist/esm/index.js.map +1 -1
  123. package/dist/esm/resources/addresses.d.ts +23 -8
  124. package/dist/esm/resources/addresses.d.ts.map +1 -1
  125. package/dist/esm/resources/addresses.js +8 -1
  126. package/dist/esm/resources/addresses.js.map +1 -1
  127. package/dist/esm/resources/admin.d.ts +150 -25
  128. package/dist/esm/resources/admin.d.ts.map +1 -1
  129. package/dist/esm/resources/admin.js +94 -23
  130. package/dist/esm/resources/admin.js.map +1 -1
  131. package/dist/esm/resources/approvals.d.ts +46 -5
  132. package/dist/esm/resources/approvals.d.ts.map +1 -1
  133. package/dist/esm/resources/approvals.js +27 -4
  134. package/dist/esm/resources/approvals.js.map +1 -1
  135. package/dist/esm/resources/balances.d.ts +152 -16
  136. package/dist/esm/resources/balances.d.ts.map +1 -1
  137. package/dist/esm/resources/balances.js +9 -5
  138. package/dist/esm/resources/balances.js.map +1 -1
  139. package/dist/esm/resources/categories.d.ts +93 -21
  140. package/dist/esm/resources/categories.d.ts.map +1 -1
  141. package/dist/esm/resources/categories.js +65 -18
  142. package/dist/esm/resources/categories.js.map +1 -1
  143. package/dist/esm/resources/counterparties.d.ts +26 -3
  144. package/dist/esm/resources/counterparties.d.ts.map +1 -1
  145. package/dist/esm/resources/counterparties.js +17 -0
  146. package/dist/esm/resources/counterparties.js.map +1 -1
  147. package/dist/esm/resources/folders.d.ts +51 -10
  148. package/dist/esm/resources/folders.d.ts.map +1 -1
  149. package/dist/esm/resources/folders.js +36 -5
  150. package/dist/esm/resources/folders.js.map +1 -1
  151. package/dist/esm/resources/history.d.ts +20 -2
  152. package/dist/esm/resources/history.d.ts.map +1 -1
  153. package/dist/esm/resources/history.js.map +1 -1
  154. package/dist/esm/resources/me.d.ts +27 -4
  155. package/dist/esm/resources/me.d.ts.map +1 -1
  156. package/dist/esm/resources/me.js +22 -1
  157. package/dist/esm/resources/me.js.map +1 -1
  158. package/dist/esm/resources/members.d.ts +19 -4
  159. package/dist/esm/resources/members.d.ts.map +1 -1
  160. package/dist/esm/resources/members.js +15 -6
  161. package/dist/esm/resources/members.js.map +1 -1
  162. package/dist/esm/resources/operations.d.ts +64 -8
  163. package/dist/esm/resources/operations.d.ts.map +1 -1
  164. package/dist/esm/resources/operations.js +26 -2
  165. package/dist/esm/resources/operations.js.map +1 -1
  166. package/dist/esm/resources/registries.d.ts +87 -9
  167. package/dist/esm/resources/registries.d.ts.map +1 -1
  168. package/dist/esm/resources/registries.js +54 -11
  169. package/dist/esm/resources/registries.js.map +1 -1
  170. package/dist/esm/resources/reports.d.ts +300 -41
  171. package/dist/esm/resources/reports.d.ts.map +1 -1
  172. package/dist/esm/resources/reports.js +135 -7
  173. package/dist/esm/resources/reports.js.map +1 -1
  174. package/dist/esm/resources/sharing.d.ts +61 -10
  175. package/dist/esm/resources/sharing.d.ts.map +1 -1
  176. package/dist/esm/resources/sharing.js +51 -4
  177. package/dist/esm/resources/sharing.js.map +1 -1
  178. package/dist/esm/resources/transfers.d.ts +44 -6
  179. package/dist/esm/resources/transfers.d.ts.map +1 -1
  180. package/dist/esm/resources/transfers.js +41 -3
  181. package/dist/esm/resources/transfers.js.map +1 -1
  182. package/dist/esm/resources/types.d.ts +16 -0
  183. package/dist/esm/resources/types.d.ts.map +1 -1
  184. package/dist/esm/units.d.ts.map +1 -1
  185. package/dist/esm/units.js +18 -2
  186. package/dist/esm/units.js.map +1 -1
  187. package/dist/esm/version.d.ts +1 -1
  188. package/dist/esm/version.js +1 -1
  189. package/docs/concepts.md +193 -0
  190. package/docs/errors.md +491 -0
  191. package/package.json +7 -6
  192. package/src/client.ts +89 -25
  193. package/src/core/errors.ts +49 -15
  194. package/src/core/gated.ts +31 -7
  195. package/src/core/http.ts +173 -49
  196. package/src/core/pagination.ts +38 -1
  197. package/src/generated/operations.ts +1 -1
  198. package/src/generated/types.ts +1001 -180
  199. package/src/index.ts +64 -7
  200. package/src/resources/addresses.ts +24 -8
  201. package/src/resources/admin.ts +186 -33
  202. package/src/resources/approvals.ts +55 -9
  203. package/src/resources/balances.ts +186 -14
  204. package/src/resources/categories.ts +125 -30
  205. package/src/resources/counterparties.ts +23 -6
  206. package/src/resources/folders.ts +74 -18
  207. package/src/resources/history.ts +27 -2
  208. package/src/resources/me.ts +30 -5
  209. package/src/resources/members.ts +26 -7
  210. package/src/resources/operations.ts +73 -8
  211. package/src/resources/registries.ts +90 -11
  212. package/src/resources/reports.ts +348 -67
  213. package/src/resources/sharing.ts +71 -18
  214. package/src/resources/transfers.ts +51 -7
  215. package/src/resources/types.ts +16 -0
  216. package/src/units.ts +19 -2
  217. package/src/version.ts +1 -1
@@ -1,11 +1,13 @@
1
1
  import { seg, type HttpClient } from '../core/http.js'
2
2
  import { toGated, type Gated } from '../core/gated.js'
3
3
  import type {
4
+ CancelResult,
4
5
  CreateTransactionResult,
5
6
  CreateTransferBody,
6
7
  ReconcileTransferBody,
7
8
  ReconcileTransferResult,
8
9
  TransactionDetail,
10
+ VoteResult,
9
11
  } from '../generated/types.js'
10
12
 
11
13
  export interface VoteInput {
@@ -21,10 +23,20 @@ export interface VoteInput {
21
23
  *
22
24
  * applied (201) — executed, the money left;
23
25
  * pending (202) — awaiting signatures, funds RESERVED but not sent;
24
- * replayed (200) — a repeat; the transfer already existed.
26
+ * replayed (200) — a transfer with this `idempotencyKey` already existed,
27
+ * and this is that transfer as it stands NOW.
25
28
  *
26
29
  * They cannot be told apart by the body. Showing "sent" on `pending` tells
27
30
  * the person money has gone when it is frozen.
31
+ *
32
+ * `replayed` does not mean "sent" either. It says only that the request was
33
+ * seen before; what became of it is in `data.transaction.status`:
34
+ *
35
+ * confirmed, submitted — it left;
36
+ * awaiting_approval — waiting for signatures, funds reserved;
37
+ * pending — still executing;
38
+ * failed, rejected,
39
+ * cancelled — it did not leave.
28
40
  */
29
41
  export class TransfersResource {
30
42
  readonly #http: HttpClient
@@ -35,7 +47,13 @@ export class TransfersResource {
35
47
  this.#base = `/api/v1/vaults/${seg(vaultCode)}/transfers`
36
48
  }
37
49
 
38
- /** Sends a transfer. The timeout is long: the path calls the wallet service. */
50
+ /**
51
+ * Sends a transfer. The timeout is long: the path calls the wallet service.
52
+ *
53
+ * On `outcome: 'replayed'` read `data.transaction.status` before telling
54
+ * anyone anything — a replay of an attempt that failed, or that is still
55
+ * waiting for signatures, comes back the same way as one that went out.
56
+ */
39
57
  async send(
40
58
  input: CreateTransferBody,
41
59
  options: { signal?: AbortSignal; timeoutMs?: number } = {},
@@ -66,17 +84,43 @@ export class TransfersResource {
66
84
  * Only people captured in the approver SNAPSHOT taken when the request was
67
85
  * created may vote: editing a policy or a group afterwards does not change
68
86
  * an in-flight request.
87
+ *
88
+ * READ `status` FROM THE ANSWER — it is the status of the TRANSFER after
89
+ * the vote, and the vote is where the money moves:
90
+ *
91
+ * awaiting_approval — counted, more signatures still needed;
92
+ * rejected — a `reject` is a veto, and the reserve is released;
93
+ * confirmed/failed — this vote completed the threshold, so execution ran
94
+ * INSIDE this request (gas, then broadcast, ~10s).
95
+ *
96
+ * `failed` means the money is back: execution broke after approval and the
97
+ * reserve was released, with the reason in `executionError`. Treating the
98
+ * call as "approved, done" hides both the success and that failure.
69
99
  */
70
- vote(transferId: string, input: VoteInput): Promise<unknown> {
71
- return this.#http.request('POST', `${this.#base}/${seg(transferId)}/approvals`, { body: input })
100
+ vote(transferId: string, input: VoteInput): Promise<VoteResult> {
101
+ return this.#http.request<VoteResult>(
102
+ 'POST',
103
+ `${this.#base}/${seg(transferId)}/approvals`,
104
+ { body: input },
105
+ )
72
106
  }
73
107
 
74
108
  /**
75
109
  * Cancels your own transfer that is awaiting signatures and releases the
76
- * reserve. A transfer already broadcast cannot be cancelled.
110
+ * reserve. A transfer already broadcast cannot be cancelled; administrators
111
+ * may cancel somebody else's, so a stuck request is not hostage to an
112
+ * absent initiator.
113
+ *
114
+ * The resulting status is its own value, `cancelled` — not the `rejected`
115
+ * of a veto and not `failed`. Worth keeping apart in the interface: "you
116
+ * withdrew this" and "somebody refused it" are different events.
117
+ *
118
+ * Clear a stuck transfer through this endpoint and never by writing the
119
+ * status directly: the reserve is released by a ledger posting, not by the
120
+ * status, so a hand-edited row leaves the funds locked for good.
77
121
  */
78
- cancel(transferId: string): Promise<unknown> {
79
- return this.#http.request('POST', `${this.#base}/${seg(transferId)}/cancel`)
122
+ cancel(transferId: string): Promise<CancelResult> {
123
+ return this.#http.request<CancelResult>('POST', `${this.#base}/${seg(transferId)}/cancel`)
80
124
  }
81
125
 
82
126
  /**
@@ -21,6 +21,22 @@ import type {
21
21
  /**
22
22
  * An address as it appears in listings.
23
23
  *
24
+ * Which shape comes from where: `GET /addresses` and `PATCH /addresses/{id}`
25
+ * both answer with `AddressListItem` — that is why this is an alias of it and
26
+ * not of the schema called `Address`. `GET /addresses/{id}` answers with the
27
+ * larger `AddressDetail` (transactions, shares, vault).
28
+ *
29
+ * The document DOES also declare a schema named `Address`, and this export
30
+ * shadows it — `src/index.ts` re-exports this name explicitly, and an
31
+ * explicit re-export beats `export type *`. That is deliberate, and the
32
+ * reason belongs here so nobody "fixes" it the wrong way round: no operation
33
+ * references the `Address` schema (zero `$ref`), and its sixteen properties
34
+ * are a strict subset of `AddressListItem`'s twenty-three, identical in type
35
+ * and in optionality. The alias is therefore narrower than the schema it
36
+ * hides, never wider, and the hidden schema describes no response at all.
37
+ * Pointing this name at `Address` would be the real break: the seven extra
38
+ * fields would vanish from the type while still arriving on the wire.
39
+ *
24
40
  * `balance` is `string | null`, and the `null` matters: it means the address
25
41
  * has NO ledger account yet — nothing has ever arrived. That is not zero, and
26
42
  * the two must not be merged, because "no account" and "empty account"
package/src/units.ts CHANGED
@@ -35,8 +35,16 @@ export class AmountError extends Error {
35
35
  const RAW_RE = /^-?\d+$/
36
36
  const DECIMAL_RE = /^-?\d+(\.\d+)?$/
37
37
 
38
+ /**
39
+ * The API's own ceiling: `CreateTokenBody.decimals` is `int().min(0).max(38)`
40
+ * in the policy engine's `src/openapi/models.ts`. A lower bound here would
41
+ * contradict the rest of the package — `registries.createToken` would accept a
42
+ * token this module then refuses to do arithmetic on.
43
+ */
44
+ const MAX_DECIMALS = 38
45
+
38
46
  function assertDecimals(decimals: number): void {
39
- if (!Number.isInteger(decimals) || decimals < 0 || decimals > 36) {
47
+ if (!Number.isInteger(decimals) || decimals < 0 || decimals > MAX_DECIMALS) {
40
48
  throw new AmountError(`Invalid decimals: ${decimals}`)
41
49
  }
42
50
  }
@@ -96,8 +104,17 @@ export function format(
96
104
  options: { locale?: string; withAsset?: boolean; minFractionDigits?: number } = {},
97
105
  ): string {
98
106
  const decimal = toDecimalString(a, { trim: false })
107
+ // The padding is clamped to `decimals` because `decimals` is the maximum
108
+ // below, and Intl throws RangeError when a minimum exceeds its maximum. So
109
+ // the default of two digits made `format` unusable — not merely unpadded —
110
+ // for any token with 0 or 1 decimals, and such tokens are reachable: the API
111
+ // allows `decimals: 0` on a token, and a `currency` category field takes
112
+ // `scale: 0` today. Clamping rather than raising the maximum: digits past
113
+ // `decimals` do not exist in the asset, and printing them would claim a
114
+ // divisibility the token does not have.
115
+ const minFraction = Math.min(options.minFractionDigits ?? 2, a.decimals)
99
116
  const formatter = new Intl.NumberFormat(options.locale ?? 'en-US', {
100
- minimumFractionDigits: options.minFractionDigits ?? 2,
117
+ minimumFractionDigits: minFraction,
101
118
  maximumFractionDigits: a.decimals,
102
119
  })
103
120
  // The runtime accepts a string and keeps precision; lib.es5 still types the
package/src/version.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** SDK version, sent in the `user-agent` header. */
2
- export const SDK_VERSION = '0.1.0'
2
+ export const SDK_VERSION = '0.2.1'
3
3
 
4
4
  /** Default API base URL. */
5
5
  export const DEFAULT_BASE_URL = 'https://policy-engine-rest.ezig.workers.dev'