@gearbox-protocol/sdk 14.12.0-next.80 → 14.12.0-next.82

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 (221) hide show
  1. package/dist/cjs/model/filters.js +0 -4
  2. package/dist/cjs/model/filters.schema.js +10 -1
  3. package/dist/cjs/model/index.js +11 -0
  4. package/dist/cjs/model/liquidations.js +1 -1
  5. package/dist/cjs/model/liquidations.schema.js +1 -1
  6. package/dist/cjs/model/opportunities.js +1 -1
  7. package/dist/cjs/model/opportunities.schema.js +6 -13
  8. package/dist/cjs/model/positions.js +1 -1
  9. package/dist/cjs/model/positions.schema.js +33 -1
  10. package/dist/cjs/model/response.js +1 -0
  11. package/dist/cjs/model/response.schema.js +64 -0
  12. package/dist/cjs/new-sdk/AbstractNamespace.js +46 -128
  13. package/dist/cjs/new-sdk/GearboxSDK.js +55 -42
  14. package/dist/cjs/new-sdk/errors/AllSourcesFailedError.js +20 -0
  15. package/dist/cjs/new-sdk/errors/MissingSourceError.js +25 -0
  16. package/dist/cjs/new-sdk/errors/NoSourceServedError.js +20 -0
  17. package/dist/cjs/new-sdk/errors/SourceChainMismatchError.js +34 -0
  18. package/dist/cjs/new-sdk/errors/SourceUnavailableError.js +25 -0
  19. package/dist/cjs/new-sdk/errors/assertSameChains.js +12 -0
  20. package/dist/cjs/new-sdk/errors/everyChainFailed.js +11 -0
  21. package/dist/cjs/new-sdk/errors/index.js +15 -0
  22. package/dist/cjs/new-sdk/index.js +23 -3
  23. package/dist/cjs/new-sdk/opportunities/OpportunitiesNamespace.js +37 -89
  24. package/dist/cjs/new-sdk/positions/PositionsNamespace.js +27 -94
  25. package/dist/cjs/new-sdk/types.js +0 -21
  26. package/dist/cjs/new-sdk/utils/filterResponse.js +21 -0
  27. package/dist/cjs/new-sdk/utils/index.js +6 -0
  28. package/dist/cjs/new-sdk/utils/mergeChains.js +81 -0
  29. package/dist/cjs/new-sdk/utils/types.js +1 -0
  30. package/dist/cjs/offchain/AbstractOffchainNamespace.js +42 -65
  31. package/dist/cjs/offchain/GearboxAPI.js +12 -8
  32. package/dist/cjs/offchain/errors/OffchainInvalidJsonError.js +19 -0
  33. package/dist/cjs/offchain/errors/OffchainNotConfiguredError.js +20 -0
  34. package/dist/cjs/offchain/errors/OffchainNotImplementedError.js +19 -0
  35. package/dist/cjs/offchain/errors/OffchainRequestFailedError.js +24 -0
  36. package/dist/cjs/offchain/errors/OffchainStatusError.js +20 -0
  37. package/dist/cjs/offchain/errors/OffchainTransportError.js +31 -0
  38. package/dist/cjs/offchain/errors/OffchainValidationError.js +26 -0
  39. package/dist/cjs/offchain/errors/backendMessage.js +28 -0
  40. package/dist/cjs/offchain/errors/errorCause.js +12 -0
  41. package/dist/cjs/offchain/errors/index.js +21 -0
  42. package/dist/cjs/offchain/errors/readResponseBody.js +15 -0
  43. package/dist/cjs/offchain/index.js +22 -5
  44. package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +6 -3
  45. package/dist/cjs/offchain/positions/OffchainPositions.js +15 -21
  46. package/dist/cjs/offchain/types.js +0 -75
  47. package/dist/cjs/sdk/MultichainSDK.js +1 -1
  48. package/dist/cjs/sdk/OnchainSDK.js +1 -1
  49. package/dist/cjs/sdk/accounts/credit-account-compressor/CreditAccountCompressor.js +6 -6
  50. package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +26 -20
  51. package/dist/cjs/sdk/accounts/liquidations/MultichainLiquidationsService.js +38 -14
  52. package/dist/cjs/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +7 -5
  53. package/dist/cjs/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +3 -2
  54. package/dist/cjs/sdk/base/MultichainConstruct.js +73 -34
  55. package/dist/cjs/sdk/chain/chains.js +11 -0
  56. package/dist/cjs/sdk/chain/index.js +1 -0
  57. package/dist/cjs/sdk/core/index.js +1 -1
  58. package/dist/cjs/sdk/index.js +2 -1
  59. package/dist/cjs/sdk/market/rwa/RWARegistry.js +4 -2
  60. package/dist/cjs/sdk/opportunities/MultichainOpportunitiesService.js +18 -32
  61. package/dist/cjs/sdk/opportunities/OpportunitiesService.js +1 -4
  62. package/dist/cjs/sdk/pools/PoolService.js +2 -1
  63. package/dist/cjs/sdk/positions/MultichainPositionsService.js +6 -29
  64. package/dist/cjs/sdk/positions/PositionsService.js +12 -6
  65. package/dist/esm/dev/AccountOpener.js +1 -1
  66. package/dist/esm/dev/withdrawalUtils.js +1 -1
  67. package/dist/esm/model/filters.js +0 -4
  68. package/dist/esm/model/filters.schema.js +10 -2
  69. package/dist/esm/model/index.js +5 -3
  70. package/dist/esm/model/liquidations.js +1 -1
  71. package/dist/esm/model/liquidations.schema.js +1 -1
  72. package/dist/esm/model/opportunities.js +1 -1
  73. package/dist/esm/model/opportunities.schema.js +4 -11
  74. package/dist/esm/model/positions.js +1 -1
  75. package/dist/esm/model/positions.schema.js +33 -3
  76. package/dist/esm/model/response.js +1 -0
  77. package/dist/esm/model/response.schema.js +58 -0
  78. package/dist/esm/new-sdk/AbstractNamespace.js +46 -128
  79. package/dist/esm/new-sdk/GearboxSDK.js +55 -42
  80. package/dist/esm/new-sdk/errors/AllSourcesFailedError.js +19 -0
  81. package/dist/esm/new-sdk/errors/MissingSourceError.js +24 -0
  82. package/dist/esm/new-sdk/errors/NoSourceServedError.js +19 -0
  83. package/dist/esm/new-sdk/errors/SourceChainMismatchError.js +33 -0
  84. package/dist/esm/new-sdk/errors/SourceUnavailableError.js +24 -0
  85. package/dist/esm/new-sdk/errors/assertSameChains.js +11 -0
  86. package/dist/esm/new-sdk/errors/everyChainFailed.js +10 -0
  87. package/dist/esm/new-sdk/errors/index.js +8 -0
  88. package/dist/esm/new-sdk/index.js +13 -3
  89. package/dist/esm/new-sdk/opportunities/OpportunitiesNamespace.js +38 -90
  90. package/dist/esm/new-sdk/positions/PositionsNamespace.js +28 -95
  91. package/dist/esm/new-sdk/types.js +1 -21
  92. package/dist/esm/new-sdk/utils/filterResponse.js +20 -0
  93. package/dist/esm/new-sdk/utils/index.js +3 -1
  94. package/dist/esm/new-sdk/utils/mergeChains.js +78 -0
  95. package/dist/esm/new-sdk/utils/types.js +1 -0
  96. package/dist/esm/offchain/AbstractOffchainNamespace.js +41 -64
  97. package/dist/esm/offchain/GearboxAPI.js +12 -8
  98. package/dist/esm/offchain/errors/OffchainInvalidJsonError.js +18 -0
  99. package/dist/esm/offchain/errors/OffchainNotConfiguredError.js +19 -0
  100. package/dist/esm/offchain/errors/OffchainNotImplementedError.js +18 -0
  101. package/dist/esm/offchain/errors/OffchainRequestFailedError.js +23 -0
  102. package/dist/esm/offchain/errors/OffchainStatusError.js +19 -0
  103. package/dist/esm/offchain/errors/OffchainTransportError.js +30 -0
  104. package/dist/esm/offchain/errors/OffchainValidationError.js +25 -0
  105. package/dist/esm/offchain/errors/backendMessage.js +27 -0
  106. package/dist/esm/offchain/errors/errorCause.js +11 -0
  107. package/dist/esm/offchain/errors/index.js +11 -0
  108. package/dist/esm/offchain/errors/readResponseBody.js +14 -0
  109. package/dist/esm/offchain/index.js +13 -2
  110. package/dist/esm/offchain/opportunities/OffchainOpportunities.js +6 -3
  111. package/dist/esm/offchain/positions/OffchainPositions.js +15 -21
  112. package/dist/esm/offchain/types.js +1 -72
  113. package/dist/esm/plugins/adapters/contracts/ERC4626AdapterContract.js +1 -1
  114. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  115. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  116. package/dist/esm/sdk/MultichainSDK.js +1 -1
  117. package/dist/esm/sdk/OnchainSDK.js +1 -1
  118. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  119. package/dist/esm/sdk/accounts/credit-account-compressor/CreditAccountCompressor.js +6 -6
  120. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +27 -21
  121. package/dist/esm/sdk/accounts/liquidations/MultichainLiquidationsService.js +38 -14
  122. package/dist/esm/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +7 -5
  123. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  124. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  125. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  126. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +4 -3
  127. package/dist/esm/sdk/base/MultichainConstruct.js +73 -34
  128. package/dist/esm/sdk/base/TokensMeta.js +2 -2
  129. package/dist/esm/sdk/chain/chains.js +11 -1
  130. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  131. package/dist/esm/sdk/chain/index.js +2 -2
  132. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  133. package/dist/esm/sdk/core/index.js +1 -1
  134. package/dist/esm/sdk/index.js +3 -3
  135. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  136. package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
  137. package/dist/esm/sdk/market/rwa/RWARegistry.js +4 -2
  138. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  139. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  140. package/dist/esm/sdk/opportunities/MultichainOpportunitiesService.js +18 -32
  141. package/dist/esm/sdk/opportunities/OpportunitiesService.js +1 -4
  142. package/dist/esm/sdk/pools/PoolService.js +3 -2
  143. package/dist/esm/sdk/positions/MultichainPositionsService.js +6 -29
  144. package/dist/esm/sdk/positions/PositionsService.js +12 -6
  145. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  146. package/dist/types/model/filters.d.ts +9 -3
  147. package/dist/types/model/filters.schema.d.ts +7 -1
  148. package/dist/types/model/index.d.ts +7 -5
  149. package/dist/types/model/liquidations.d.ts +2 -6
  150. package/dist/types/model/liquidations.schema.d.ts +1 -1
  151. package/dist/types/model/opportunities.d.ts +3 -7
  152. package/dist/types/model/opportunities.schema.d.ts +2 -2
  153. package/dist/types/model/positions.d.ts +2 -6
  154. package/dist/types/model/positions.schema.d.ts +32 -2
  155. package/dist/types/model/response.d.ts +105 -0
  156. package/dist/types/model/response.schema.d.ts +98 -0
  157. package/dist/types/new-sdk/AbstractNamespace.d.ts +33 -98
  158. package/dist/types/new-sdk/GearboxSDK.d.ts +10 -25
  159. package/dist/types/new-sdk/errors/AllSourcesFailedError.d.ts +11 -0
  160. package/dist/types/new-sdk/errors/MissingSourceError.d.ts +23 -0
  161. package/dist/types/new-sdk/errors/NoSourceServedError.d.ts +17 -0
  162. package/dist/types/new-sdk/errors/SourceChainMismatchError.d.ts +35 -0
  163. package/dist/types/new-sdk/errors/SourceUnavailableError.d.ts +22 -0
  164. package/dist/types/new-sdk/errors/assertSameChains.d.ts +11 -0
  165. package/dist/types/new-sdk/errors/everyChainFailed.d.ts +10 -0
  166. package/dist/types/new-sdk/errors/index.d.ts +8 -0
  167. package/dist/types/new-sdk/index.d.ts +17 -6
  168. package/dist/types/new-sdk/opportunities/OpportunitiesNamespace.d.ts +19 -40
  169. package/dist/types/new-sdk/opportunities/index.d.ts +2 -2
  170. package/dist/types/new-sdk/opportunities/types.d.ts +80 -26
  171. package/dist/types/new-sdk/positions/PositionsNamespace.d.ts +17 -38
  172. package/dist/types/new-sdk/positions/index.d.ts +2 -2
  173. package/dist/types/new-sdk/positions/types.d.ts +74 -24
  174. package/dist/types/new-sdk/types.d.ts +24 -77
  175. package/dist/types/new-sdk/utils/filterResponse.d.ts +16 -0
  176. package/dist/types/new-sdk/utils/history.d.ts +6 -36
  177. package/dist/types/new-sdk/utils/index.d.ts +5 -2
  178. package/dist/types/new-sdk/utils/mergeChains.d.ts +20 -0
  179. package/dist/types/new-sdk/utils/types.d.ts +11 -0
  180. package/dist/types/offchain/AbstractOffchainNamespace.d.ts +21 -28
  181. package/dist/types/offchain/GearboxAPI.d.ts +13 -9
  182. package/dist/types/offchain/errors/OffchainInvalidJsonError.d.ts +16 -0
  183. package/dist/types/offchain/errors/OffchainNotConfiguredError.d.ts +16 -0
  184. package/dist/types/offchain/errors/OffchainNotImplementedError.d.ts +15 -0
  185. package/dist/types/offchain/errors/OffchainRequestFailedError.d.ts +12 -0
  186. package/dist/types/offchain/errors/OffchainStatusError.d.ts +16 -0
  187. package/dist/types/offchain/errors/OffchainTransportError.d.ts +43 -0
  188. package/dist/types/offchain/errors/OffchainValidationError.d.ts +21 -0
  189. package/dist/types/offchain/errors/backendMessage.d.ts +9 -0
  190. package/dist/types/offchain/errors/errorCause.d.ts +22 -0
  191. package/dist/types/offchain/errors/index.d.ts +11 -0
  192. package/dist/types/offchain/errors/readResponseBody.d.ts +8 -0
  193. package/dist/types/offchain/index.d.ts +13 -2
  194. package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +9 -8
  195. package/dist/types/offchain/positions/OffchainPositions.d.ts +9 -15
  196. package/dist/types/offchain/types.d.ts +7 -88
  197. package/dist/types/sdk/accounts/credit-account-compressor/types.d.ts +4 -0
  198. package/dist/types/sdk/accounts/index.d.ts +3 -3
  199. package/dist/types/sdk/accounts/liquidations/LiquidationsService.d.ts +2 -2
  200. package/dist/types/sdk/accounts/liquidations/MultichainLiquidationsService.d.ts +15 -14
  201. package/dist/types/sdk/accounts/liquidations/index.d.ts +2 -2
  202. package/dist/types/sdk/accounts/liquidations/types.d.ts +32 -16
  203. package/dist/types/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.d.ts +4 -4
  204. package/dist/types/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.d.ts +2 -2
  205. package/dist/types/sdk/accounts/withdrawal-compressor/index.d.ts +2 -2
  206. package/dist/types/sdk/accounts/withdrawal-compressor/types.d.ts +26 -4
  207. package/dist/types/sdk/base/MultichainConstruct.d.ts +63 -14
  208. package/dist/types/sdk/base/index.d.ts +2 -2
  209. package/dist/types/sdk/chain/chains.d.ts +10 -2
  210. package/dist/types/sdk/chain/index.d.ts +2 -2
  211. package/dist/types/sdk/index.d.ts +7 -7
  212. package/dist/types/sdk/market/MarketSuite.d.ts +1 -1
  213. package/dist/types/sdk/market/rwa/RWARegistry.d.ts +2 -1
  214. package/dist/types/sdk/opportunities/MultichainOpportunitiesService.d.ts +13 -16
  215. package/dist/types/sdk/pools/types.d.ts +4 -0
  216. package/dist/types/sdk/positions/MultichainPositionsService.d.ts +2 -12
  217. package/dist/types/sdk/positions/index.d.ts +2 -2
  218. package/dist/types/sdk/positions/types.d.ts +14 -5
  219. package/dist/types/sdk/types/index.d.ts +2 -2
  220. package/dist/types/sdk/types/multichain.d.ts +16 -36
  221. package/package.json +1 -1
@@ -1,5 +1,6 @@
1
1
  import { ZodAddress } from "../sdk/utils/zod.js";
2
- import { filterable } from "./filters.schema.js";
2
+ import { isFilterSet } from "./filters.js";
3
+ import { booleanParamSchema, encodeFlag, filterable } from "./filters.schema.js";
3
4
  import { assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, tokenAmountSchema, tokenSchema } from "./primitives.schema.js";
4
5
  import { apyBreakdownSchema, pointsProgramSchema } from "./opportunities.schema.js";
5
6
  import { delayedReceivedAssetSchema, liquidationPositionSchema } from "./liquidations.schema.js";
@@ -103,10 +104,39 @@ const positionSchema = z.discriminatedUnion("kind", [
103
104
  const positionFilterSchema = z.object({
104
105
  kind: filterable(positionKindSchema).optional(),
105
106
  isZeroDebt: filterable(z.boolean()).optional(),
106
- chainIds: filterable(z.array(chainIdSchema)).optional(),
107
+ chainIds: z.array(chainIdSchema).optional(),
107
108
  underlyingType: filterable(assetTypeSchema).optional()
108
109
  });
109
110
  /**
111
+ * {@link PositionFilter} as a URL can carry it: every condition is a string,
112
+ * and a condition that does not narrow is absent rather than empty.
113
+ **/
114
+ const positionFilterQueryParamsSchema = z.object({
115
+ kind: positionKindSchema.optional(),
116
+ isZeroDebt: booleanParamSchema.optional(),
117
+ chainIds: z.string().regex(/^$|^\d+(,\d+)*$/).optional(),
118
+ underlyingType: assetTypeSchema.optional()
119
+ });
120
+ /**
121
+ * Code for {@link PositionFilter} to encode/decode to/from url query parameters.
122
+ **/
123
+ const positionFilterQuerySchema = z.codec(positionFilterQueryParamsSchema, positionFilterSchema, {
124
+ decode: (params) => {
125
+ const filter = {};
126
+ if (params.kind !== void 0) filter.kind = params.kind;
127
+ if (params.isZeroDebt !== void 0) filter.isZeroDebt = params.isZeroDebt === "true";
128
+ if (params.chainIds !== void 0) filter.chainIds = params.chainIds === "" ? [] : params.chainIds.split(",").map(Number);
129
+ if (params.underlyingType !== void 0) filter.underlyingType = params.underlyingType;
130
+ return filter;
131
+ },
132
+ encode: (filter) => ({
133
+ kind: isFilterSet(filter.kind) ? filter.kind : void 0,
134
+ isZeroDebt: encodeFlag(filter.isZeroDebt),
135
+ chainIds: filter.chainIds?.join(","),
136
+ underlyingType: isFilterSet(filter.underlyingType) ? filter.underlyingType : void 0
137
+ })
138
+ });
139
+ /**
110
140
  * {@link PoolPositionKey}
111
141
  **/
112
142
  const poolPositionKeySchema = z.object({
@@ -132,4 +162,4 @@ const positionKeySchema = z.discriminatedUnion("kind", [z.object({
132
162
  ...strategyPositionKeySchema.shape
133
163
  })]);
134
164
  //#endregion
135
- export { pnlBreakdownSchema, pointsProgramPnLSchema, pointsRewardsPnLSchema, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionKeySchema, positionKindSchema, positionSchema, rewardsPnLSchema, strategyPositionKeySchema, strategyPositionSchema, tokenRewardsPnLSchema };
165
+ export { pnlBreakdownSchema, pointsProgramPnLSchema, pointsRewardsPnLSchema, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterQueryParamsSchema, positionFilterQuerySchema, positionFilterSchema, positionKeySchema, positionKindSchema, positionSchema, rewardsPnLSchema, strategyPositionKeySchema, strategyPositionSchema, tokenRewardsPnLSchema };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import { chainIdSchema, timestampSchema } from "./primitives.schema.js";
2
+ import { z } from "zod/v4";
3
+ //#region src/model/response.schema.ts
4
+ /**
5
+ * Runtime schemas for {@link ./response.js}, see the note in
6
+ * `primitives.schema.ts` on why they are written by hand.
7
+ *
8
+ * `responseSchema(payloadSchema)` validates a successful backend 2xx body.
9
+ * HTTP and transport errors never pass through it.
10
+ **/
11
+ /**
12
+ * {@link DataSource}
13
+ **/
14
+ const dataSourceSchema = z.enum(["onchain", "offchain"]);
15
+ /**
16
+ * {@link ChainSucceeded}
17
+ *
18
+ * `source` may be omitted by the backend and decodes to `"offchain"`. The block
19
+ * has no such default: a success that omits it fails validation.
20
+ **/
21
+ const chainSucceededSchema = z.object({
22
+ chainId: chainIdSchema,
23
+ status: z.literal("success"),
24
+ source: dataSourceSchema.default("offchain"),
25
+ blockNumber: z.number().int().nonnegative(),
26
+ timestamp: timestampSchema
27
+ });
28
+ /**
29
+ * {@link ChainFailed}
30
+ *
31
+ * `error` is a `string` in a JSON body. The schema accepts `unknown` so the
32
+ * same codec also validates a locally produced envelope carrying an `Error`.
33
+ **/
34
+ const chainFailedSchema = z.object({
35
+ chainId: chainIdSchema,
36
+ status: z.literal("error"),
37
+ source: dataSourceSchema.optional(),
38
+ error: z.unknown().optional()
39
+ });
40
+ /**
41
+ * {@link ChainMetadata}
42
+ **/
43
+ const chainMetadataSchema = z.discriminatedUnion("status", [chainSucceededSchema, chainFailedSchema]);
44
+ /**
45
+ * {@link ResponseMetadata}
46
+ **/
47
+ const responseMetadataSchema = z.object({ chains: z.array(chainMetadataSchema) });
48
+ /**
49
+ * {@link DataResponse} parameterized by the payload schema.
50
+ **/
51
+ function responseSchema(payloadSchema) {
52
+ return z.object({
53
+ data: payloadSchema,
54
+ meta: responseMetadataSchema
55
+ });
56
+ }
57
+ //#endregion
58
+ export { chainFailedSchema, chainMetadataSchema, chainSucceededSchema, dataSourceSchema, responseMetadataSchema, responseSchema };
@@ -1,157 +1,75 @@
1
- import { getNetworkType } from "../sdk/chain/chains.js";
2
- import { AllSourcesFailedError } from "./types.js";
1
+ import { AllSourcesFailedError } from "./errors/AllSourcesFailedError.js";
2
+ import { everyChainFailed } from "./errors/everyChainFailed.js";
3
+ import { SourceUnavailableError } from "./errors/SourceUnavailableError.js";
4
+ import "./errors/index.js";
3
5
  //#region src/new-sdk/AbstractNamespace.ts
4
6
  /**
5
- * Shared machinery of every {@link GearboxSDK} namespace.
7
+ * Base class of every {@link GearboxSDK} namespace: holds the two source
8
+ * namespaces, exposes each on its own, and runs merged reads over both.
6
9
  *
7
- * A namespace is a stateless router: it asks the sources its mode allows, in
8
- * parallel, merges what came back and reports what did not. This class owns
9
- * that routing — per-chain failure capture, backend degradation, the response
10
- * envelope and the all-sources-failed rule — so a namespace holds nothing but
11
- * its reads and its merge policy.
12
- *
13
- * The sources are whatever it was handed, and their readiness is their owner's
14
- * business: a source that is not ready to answer fails the read it was given,
15
- * and that failure is reported like any other.
16
- *
17
- * All protocol knowledge lives in the sources: `MultichainSDK` for the chain,
18
- * `GearboxAPI` for the backend. None of it is repeated here or in a subclass.
19
- *
20
- * @typeParam ListRow - Row type of the namespace's list read.
10
+ * @typeParam Onchain - On-chain source namespace, e.g.
11
+ * `MultichainOpportunitiesService`.
12
+ * @typeParam Offchain - Backend source namespace, e.g. `OffchainOpportunities`.
21
13
  **/
22
14
  var AbstractNamespace = class {
15
+ /**
16
+ * How far the backend may lag the chain and still serve a chain.
17
+ **/
18
+ maxOffchainLagSeconds;
23
19
  logger;
20
+ #name;
24
21
  #onchain;
25
22
  #offchain;
26
- constructor(name, onchain, offchain, logger) {
23
+ constructor(name, onchain, offchain, options) {
24
+ this.#name = name;
27
25
  this.#onchain = onchain;
28
26
  this.#offchain = offchain;
29
- this.logger = logger?.child?.({ name }) ?? logger;
30
- }
31
- /**
32
- * Asks both sources in parallel and combines whatever answered.
33
- *
34
- * The action name is only used in diagnostics and in the error raised when
35
- * every source the read had failed.
36
- **/
37
- async read(action, fromChain, fromBackend, combine) {
38
- const [onchain, offchain] = await Promise.all([this.fromChain(fromChain), this.fromBackend(fromBackend)]);
39
- const meta = toMeta(onchain, offchain);
40
- this.assertAnySourceSucceeded(action, meta);
41
- return {
42
- result: combine(onchain.value, offchain.value),
43
- meta
44
- };
45
- }
46
- /**
47
- * Reads the namespace's list from both sources, unioned by
48
- * {@link AbstractNamespace.mergeList}.
49
- **/
50
- async readList(action, fromChain, fromBackend) {
51
- return this.read(action, fromChain, fromBackend, (onchain, offchain) => this.mergeList(onchain ?? [], offchain ?? []));
27
+ this.maxOffchainLagSeconds = options.maxOffchainLagSeconds;
28
+ this.logger = options.logger?.child?.({ name }) ?? options.logger;
52
29
  }
53
30
  /**
54
- * Reads one row from both sources and merges them under
55
- * {@link AbstractNamespace.mergeOne}. The key names the chain, so the
56
- * on-chain leg queries exactly one.
31
+ * The on-chain source namespace on its own. Throws
32
+ * {@link SourceUnavailableError} in `offchain` mode.
57
33
  **/
58
- async readOne(action, chainId, fromChain, fromBackend) {
59
- return this.read(action, async (sdk) => {
60
- const network = this.networkOf(chainId);
61
- if (!network) return { chains: [] };
62
- return this.onOneChain(action, network, () => fromChain(sdk));
63
- }, fromBackend, (onchain, offchain) => {
64
- if (onchain && offchain) return this.mergeOne(onchain, offchain);
65
- return onchain ?? offchain;
66
- });
34
+ get onchain() {
35
+ if (!this.#onchain) throw new SourceUnavailableError(this.#name, "onchain");
36
+ return this.#onchain;
67
37
  }
68
38
  /**
69
- * Reads something only the backend can answer.
70
- *
71
- * The fallback stands in for a backend that answered with nothing, which is
72
- * a different thing from a backend that failed and was dropped.
39
+ * The backend source namespace on its own. Throws
40
+ * {@link SourceUnavailableError} in `onchain` mode.
73
41
  **/
74
- async readOffchain(action, fromBackend, fallback) {
75
- const offchain = await this.fromBackend(fromBackend);
76
- const meta = toMeta({ chains: [] }, offchain);
77
- this.assertAnySourceSucceeded(action, meta);
78
- return {
79
- result: offchain.value ?? fallback,
80
- meta
81
- };
42
+ get offchain() {
43
+ if (!this.#offchain) throw new SourceUnavailableError(this.#name, "offchain");
44
+ return this.#offchain;
82
45
  }
83
46
  /**
84
- * Runs a read against the chain, or reports the chain as absent when the
85
- * namespace has no on-chain source at all.
47
+ * Asks both sources at once and merges what came back, failing only when no
48
+ * chain was served at all.
86
49
  **/
87
- async fromChain(run) {
88
- return this.#onchain ? run(this.#onchain) : { chains: [] };
50
+ async merged(action, query) {
51
+ const onchain = this.#onchain;
52
+ const offchain = this.#offchain;
53
+ const [fromChain, fromBackend] = await Promise.all([this.#ask(action, "onchain", onchain, query.fromChain), this.#ask(action, "offchain", offchain, query.fromBackend)]);
54
+ const merged = query.merge(fromChain.response, fromBackend.response);
55
+ if (merged && !everyChainFailed(merged.meta)) return merged;
56
+ const sole = onchain && offchain ? void 0 : fromChain.error ?? fromBackend.error;
57
+ if (sole !== void 0) throw sole;
58
+ throw new AllSourcesFailedError(action, [fromChain.error, fromBackend.error], merged?.meta);
89
59
  }
90
60
  /**
91
- * Runs a read against the backend, turning any rejection into metadata so
92
- * that a dead backend degrades a `both`-mode read instead of failing it.
61
+ * Runs one source's leg of a read, skipping a source this mode does not have
62
+ * and turning a rejection into an outcome.
93
63
  **/
94
- async fromBackend(run) {
95
- if (!this.#offchain) return {};
64
+ async #ask(action, label, source, run) {
65
+ if (source === void 0) return {};
96
66
  try {
97
- const { result, meta } = await run(this.#offchain);
98
- return {
99
- value: meta.status === "success" ? result : void 0,
100
- status: meta
101
- };
67
+ return { response: await run(source) };
102
68
  } catch (error) {
103
- this.logger?.warn(error, "offchain read failed");
104
- return { status: {
105
- status: "error",
106
- error
107
- } };
108
- }
109
- }
110
- /**
111
- * Runs a read against one chain, turning a rejection into that chain's
112
- * metadata entry.
113
- **/
114
- async onOneChain(action, network, run) {
115
- try {
116
- return {
117
- value: await run(),
118
- chains: [{
119
- network,
120
- status: "success"
121
- }]
122
- };
123
- } catch (error) {
124
- this.logger?.warn(error, `failed to ${action} on ${network}`);
125
- return { chains: [{
126
- network,
127
- status: "error",
128
- error
129
- }] };
130
- }
131
- }
132
- /**
133
- * A read that reached at least one source returns what it has; a read where
134
- * every source it had failed throws, because an empty result would otherwise
135
- * be indistinguishable from "there is nothing here".
136
- **/
137
- assertAnySourceSucceeded(action, meta) {
138
- const asked = meta.chains.length > 0 || meta.offchain !== void 0;
139
- const answered = meta.chains.some((c) => c.status === "success") || meta.offchain?.status === "success";
140
- if (asked && !answered) throw new AllSourcesFailedError(action, meta);
141
- }
142
- networkOf(chainId) {
143
- try {
144
- return getNetworkType(chainId);
145
- } catch {
146
- this.logger?.debug(`chain ${chainId} is not a Gearbox network, skipping the onchain source`);
147
- return;
69
+ this.logger?.warn(error, `failed to ${action} from the ${label} source`);
70
+ return { error };
148
71
  }
149
72
  }
150
73
  };
151
- function toMeta(onchain, offchain) {
152
- const meta = { chains: onchain.chains };
153
- if (offchain.status) meta.offchain = offchain.status;
154
- return meta;
155
- }
156
74
  //#endregion
157
75
  export { AbstractNamespace };
@@ -1,19 +1,22 @@
1
+ import { toChainIds } from "../sdk/chain/chains.js";
1
2
  import { MultichainSDK } from "../sdk/MultichainSDK.js";
2
3
  import "../sdk/index.js";
4
+ import { assertSameChains } from "./errors/assertSameChains.js";
5
+ import { MissingSourceError } from "./errors/MissingSourceError.js";
6
+ import "./errors/index.js";
3
7
  import { GearboxAPI } from "../offchain/GearboxAPI.js";
4
8
  import "../offchain/index.js";
9
+ import "./utils/mergeChains.js";
10
+ import "./utils/index.js";
5
11
  import { OpportunitiesNamespace } from "./opportunities/OpportunitiesNamespace.js";
6
12
  import "./opportunities/index.js";
7
13
  import { PositionsNamespace } from "./positions/PositionsNamespace.js";
8
14
  import "./positions/index.js";
9
15
  //#region src/new-sdk/GearboxSDK.ts
10
16
  /**
11
- * Combined entry point over both sources of Gearbox data: the chain and the
12
- * Gearbox backend.
13
- *
14
- * The {@link Mode} is fixed at construction and decides which methods exist,
15
- * not what they return, so a screen written against `both` cannot silently
16
- * degrade to a subset when someone reconfigures the SDK:
17
+ * Entry point over both sources of Gearbox data: the chain and the Gearbox
18
+ * backend. The {@link Mode} is fixed at construction and decides which methods
19
+ * exist.
17
20
  *
18
21
  * ```ts
19
22
  * const sdk = new GearboxSDK({
@@ -24,13 +27,9 @@ import "./positions/index.js";
24
27
  * });
25
28
  * await sdk.attach();
26
29
  *
27
- * const { result, meta } = await sdk.opportunities.list({ kind: "strategy" });
30
+ * const { data, meta } = await sdk.opportunities.list({ kind: "strategy" });
28
31
  * ```
29
32
  *
30
- * Every read answers with `{ result, meta }`: `meta` says which chains and
31
- * which backend answered, because a partial answer is the normal case for a
32
- * multi-chain read.
33
- *
34
33
  * @typeParam M - Mode the instance was built in.
35
34
  **/
36
35
  var GearboxSDK = class {
@@ -39,8 +38,7 @@ var GearboxSDK = class {
39
38
  **/
40
39
  mode;
41
40
  /**
42
- * Chains this instance covers. Authoritative even when an injected on-chain
43
- * SDK covers a different set.
41
+ * Chains this instance covers, which every read is scoped to.
44
42
  **/
45
43
  networks;
46
44
  /**
@@ -54,46 +52,51 @@ var GearboxSDK = class {
54
52
  #attachOptions;
55
53
  #onchain;
56
54
  #offchain;
57
- /**
58
- * Whether this instance built the on-chain SDK, and therefore attaches it.
59
- **/
60
55
  #ownsOnchain = false;
61
56
  #attached;
62
57
  constructor(options) {
63
- const { mode, networks, onchain, offchain, attach, logger } = options;
58
+ const { mode, networks, onchain, offchain, attach, logger, maxOffchainLagSeconds = 120 } = options;
64
59
  this.mode = mode;
65
60
  this.networks = [...networks];
66
61
  this.#attachOptions = attach;
67
62
  const needsOnchain = mode === "onchain" || mode === "both";
68
63
  const needsOffchain = mode === "offchain" || mode === "both";
69
- if (needsOnchain && !onchain) throw new Error(`GearboxSDK in ${mode} mode needs an onchain source`);
70
- if (needsOffchain && !offchain) throw new Error(`GearboxSDK in ${mode} mode needs an offchain source`);
64
+ if (needsOnchain && !onchain) throw new MissingSourceError(mode, "onchain");
65
+ if (needsOffchain && !offchain) throw new MissingSourceError(mode, "offchain");
71
66
  if (!needsOnchain && onchain) logger?.warn(`GearboxSDK in ${mode} mode ignores the onchain source it was given`);
72
67
  if (!needsOffchain && offchain) logger?.warn(`GearboxSDK in ${mode} mode ignores the offchain source it was given`);
73
- if (needsOnchain && onchain) if (onchain instanceof MultichainSDK) this.#onchain = onchain;
74
- else {
75
- this.#onchain = new MultichainSDK({
76
- logger,
77
- ...onchain
78
- });
79
- this.#ownsOnchain = true;
68
+ const chainIds = toChainIds(networks);
69
+ if (needsOnchain && onchain) {
70
+ if (onchain instanceof MultichainSDK) this.#onchain = onchain;
71
+ else {
72
+ this.#onchain = new MultichainSDK({
73
+ logger,
74
+ ...onchain,
75
+ chains: chainsOf(onchain.chains, networks)
76
+ });
77
+ this.#ownsOnchain = true;
78
+ }
79
+ assertSameChains("onchain", networks, [...this.#onchain.chains.keys()]);
80
80
  }
81
- if (needsOffchain && offchain) this.#offchain = offchain instanceof GearboxAPI ? offchain : new GearboxAPI({
81
+ if (needsOffchain && offchain) if (offchain instanceof GearboxAPI) {
82
+ assertSameChains("offchain", chainIds, offchain.chainIds);
83
+ this.#offchain = offchain;
84
+ } else this.#offchain = new GearboxAPI({
82
85
  logger,
83
- ...offchain
86
+ ...offchain,
87
+ chainIds
84
88
  });
85
89
  this.#attached = !this.#ownsOnchain;
86
- this.opportunities = new OpportunitiesNamespace(this.#onchain, this.#offchain, logger);
87
- this.positions = new PositionsNamespace(this.#onchain, this.#offchain, logger);
90
+ const namespaceOptions = {
91
+ maxOffchainLagSeconds,
92
+ logger
93
+ };
94
+ this.opportunities = new OpportunitiesNamespace(this.#onchain, this.#offchain, namespaceOptions);
95
+ this.positions = new PositionsNamespace(this.#onchain, this.#offchain, namespaceOptions);
88
96
  }
89
97
  /**
90
- * Attaches the on-chain SDK when this instance owns one.
91
- *
92
- * Reads issued before this resolves still reach the chain and fail there, so
93
- * in `both` mode they are served from the backend alone and report the chain
94
- * as failed in their meta, rather than blocking.
95
- *
96
- * A no-op in `offchain` mode and when an already-attached SDK was injected.
98
+ * Attaches the on-chain SDK when this instance owns one; a no-op in `offchain`
99
+ * mode and when an already-attached SDK was injected.
97
100
  **/
98
101
  async attach() {
99
102
  if (this.#attached || !this.#ownsOnchain || !this.#onchain) return;
@@ -102,17 +105,15 @@ var GearboxSDK = class {
102
105
  }
103
106
  /**
104
107
  * Whether the on-chain source is ready to be read from. Always `true` in
105
- * `offchain` mode, where there is nothing to wait for.
108
+ * `offchain` mode.
106
109
  **/
107
110
  get attached() {
108
111
  return this.mode === "offchain" ? true : this.#attached;
109
112
  }
110
113
  /**
111
114
  * The underlying on-chain SDK, for everything this facade does not expose
112
- * yet: markets, credit accounts, transaction building.
113
- *
114
- * `undefined` in `offchain` mode. Otherwise it exists from construction on,
115
- * but only answers reads once {@link attach} has resolved.
115
+ * yet: markets, credit accounts, transaction building. `undefined` in
116
+ * `offchain` mode, and only answers reads once {@link attach} has resolved.
116
117
  **/
117
118
  get onchain() {
118
119
  return this.#onchain;
@@ -124,5 +125,17 @@ var GearboxSDK = class {
124
125
  return this.#offchain;
125
126
  }
126
127
  };
128
+ /**
129
+ * Per-chain configuration of exactly the networks the SDK covers.
130
+ **/
131
+ function chainsOf(configured, networks) {
132
+ const chains = {};
133
+ for (const network of networks) {
134
+ const chain = configured[network];
135
+ if (!chain) throw new Error(`GearboxSDK covers ${network}, but its onchain source has no configuration for it`);
136
+ chains[network] = chain;
137
+ }
138
+ return chains;
139
+ }
127
140
  //#endregion
128
141
  export { GearboxSDK };
@@ -0,0 +1,19 @@
1
+ //#region src/new-sdk/errors/AllSourcesFailedError.ts
2
+ /**
3
+ * Thrown when a read had sources to ask and none of them served a single chain.
4
+ **/
5
+ var AllSourcesFailedError = class extends AggregateError {
6
+ constructor(action, sourceErrors, meta) {
7
+ const causes = [...sourceErrors, ...chainErrors(meta)].filter((reason) => reason !== void 0);
8
+ super(causes, `cannot ${action}, every source failed (${causes.join("; ")})`);
9
+ this.name = "AllSourcesFailedError";
10
+ }
11
+ };
12
+ /**
13
+ * Why each chain a merged envelope did report failed.
14
+ **/
15
+ function chainErrors(meta) {
16
+ return (meta?.chains ?? []).map((chain) => chain.status === "error" ? chain.error : void 0);
17
+ }
18
+ //#endregion
19
+ export { AllSourcesFailedError };
@@ -0,0 +1,24 @@
1
+ import { BaseError } from "viem";
2
+ //#region src/new-sdk/errors/MissingSourceError.ts
3
+ /**
4
+ * Thrown at construction when a {@link GearboxSDK} was not given a source its
5
+ * {@link Mode} reads from.
6
+ **/
7
+ var MissingSourceError = class extends BaseError {
8
+ name = "MissingSourceError";
9
+ /**
10
+ * Mode the SDK was built in.
11
+ **/
12
+ mode;
13
+ /**
14
+ * Source that mode needs and did not get.
15
+ **/
16
+ source;
17
+ constructor(mode, source) {
18
+ super(`A GearboxSDK in ${mode} mode needs an ${source} source.`);
19
+ this.mode = mode;
20
+ this.source = source;
21
+ }
22
+ };
23
+ //#endregion
24
+ export { MissingSourceError };
@@ -0,0 +1,19 @@
1
+ //#region src/new-sdk/errors/NoSourceServedError.ts
2
+ /**
3
+ * The failure of a chain no source served. It is reported in that chain's
4
+ * metadata entry rather than thrown: the other chains of the same read may
5
+ * still have been served.
6
+ **/
7
+ var NoSourceServedError = class extends AggregateError {
8
+ /**
9
+ * Chain no source served.
10
+ **/
11
+ chainId;
12
+ constructor(chainId, reasons) {
13
+ super(reasons, `no source could serve chain ${chainId}`);
14
+ this.name = "NoSourceServedError";
15
+ this.chainId = chainId;
16
+ }
17
+ };
18
+ //#endregion
19
+ export { NoSourceServedError };
@@ -0,0 +1,33 @@
1
+ import { BaseError } from "viem";
2
+ //#region src/new-sdk/errors/SourceChainMismatchError.ts
3
+ /**
4
+ * Thrown at construction when a source covers anything other than exactly the
5
+ * chains a {@link GearboxSDK} was built for, see
6
+ * {@link GearboxSDKOptions.networks}.
7
+ **/
8
+ var SourceChainMismatchError = class extends BaseError {
9
+ name = "SourceChainMismatchError";
10
+ /**
11
+ * Source whose coverage does not match.
12
+ **/
13
+ source;
14
+ /**
15
+ * Chains the SDK covers.
16
+ **/
17
+ expected;
18
+ /**
19
+ * Chains the source covers.
20
+ **/
21
+ covered;
22
+ constructor(source, expected, covered) {
23
+ super(`The ${source} source does not cover the chains this GearboxSDK was built for.`, { metaMessages: [`Expected: ${named(expected)}`, `Covered: ${named(covered)}`] });
24
+ this.source = source;
25
+ this.expected = [...expected];
26
+ this.covered = [...covered];
27
+ }
28
+ };
29
+ function named(chains) {
30
+ return chains.join(", ") || "no chain";
31
+ }
32
+ //#endregion
33
+ export { SourceChainMismatchError };
@@ -0,0 +1,24 @@
1
+ import { BaseError } from "viem";
2
+ //#region src/new-sdk/errors/SourceUnavailableError.ts
3
+ /**
4
+ * Thrown when a source branch of a namespace is read in a mode that has no such
5
+ * source, e.g. `sdk.opportunities.onchain` in `offchain` mode.
6
+ **/
7
+ var SourceUnavailableError = class extends BaseError {
8
+ name = "SourceUnavailableError";
9
+ /**
10
+ * Namespace whose branch was read.
11
+ **/
12
+ namespace;
13
+ /**
14
+ * Source this mode does not read.
15
+ **/
16
+ source;
17
+ constructor(namespace, source) {
18
+ super(`The ${namespace} namespace has no ${source} source in this mode.`);
19
+ this.namespace = namespace;
20
+ this.source = source;
21
+ }
22
+ };
23
+ //#endregion
24
+ export { SourceUnavailableError };
@@ -0,0 +1,11 @@
1
+ import { SourceChainMismatchError } from "./SourceChainMismatchError.js";
2
+ //#region src/new-sdk/errors/assertSameChains.ts
3
+ /**
4
+ * Rejects a source covering anything other than exactly the chains the SDK was
5
+ * built for. A source is not narrowed to them: it has to name them.
6
+ **/
7
+ function assertSameChains(source, expected, covered) {
8
+ if (covered.length !== expected.length || covered.some((chain) => !expected.includes(chain))) throw new SourceChainMismatchError(source, expected, covered);
9
+ }
10
+ //#endregion
11
+ export { assertSameChains };
@@ -0,0 +1,10 @@
1
+ //#region src/new-sdk/errors/everyChainFailed.ts
2
+ /**
3
+ * Whether a merged envelope covered chains and lost every one of them, which is
4
+ * what makes a read a failure rather than a partial result.
5
+ **/
6
+ function everyChainFailed(meta) {
7
+ return meta.chains.length > 0 && meta.chains.every((chain) => chain.status === "error");
8
+ }
9
+ //#endregion
10
+ export { everyChainFailed };
@@ -0,0 +1,8 @@
1
+ import { AllSourcesFailedError } from "./AllSourcesFailedError.js";
2
+ import { SourceChainMismatchError } from "./SourceChainMismatchError.js";
3
+ import { assertSameChains } from "./assertSameChains.js";
4
+ import { everyChainFailed } from "./everyChainFailed.js";
5
+ import { MissingSourceError } from "./MissingSourceError.js";
6
+ import { NoSourceServedError } from "./NoSourceServedError.js";
7
+ import { SourceUnavailableError } from "./SourceUnavailableError.js";
8
+ export { AllSourcesFailedError, MissingSourceError, NoSourceServedError, SourceChainMismatchError, SourceUnavailableError, assertSameChains, everyChainFailed };