@morpho-org/midnight-sdk 0.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 (157) hide show
  1. package/README.md +252 -0
  2. package/lib/cjs/abis.d.ts +3170 -0
  3. package/lib/cjs/abis.js +4073 -0
  4. package/lib/cjs/api/MidnightApi.d.ts +532 -0
  5. package/lib/cjs/api/MidnightApi.js +713 -0
  6. package/lib/cjs/api/helpers.d.ts +20 -0
  7. package/lib/cjs/api/helpers.js +189 -0
  8. package/lib/cjs/api/index.d.ts +2 -0
  9. package/lib/cjs/api/index.js +21 -0
  10. package/lib/cjs/api/types.d.ts +453 -0
  11. package/lib/cjs/api/types.js +2 -0
  12. package/lib/cjs/constants.d.ts +168 -0
  13. package/lib/cjs/constants.js +187 -0
  14. package/lib/cjs/errors.d.ts +253 -0
  15. package/lib/cjs/errors.js +309 -0
  16. package/lib/cjs/fetch/Market.d.ts +65 -0
  17. package/lib/cjs/fetch/Market.js +117 -0
  18. package/lib/cjs/fetch/Offer.d.ts +74 -0
  19. package/lib/cjs/fetch/Offer.js +119 -0
  20. package/lib/cjs/fetch/Position.d.ts +85 -0
  21. package/lib/cjs/fetch/Position.js +148 -0
  22. package/lib/cjs/fetch/Ratifier.d.ts +38 -0
  23. package/lib/cjs/fetch/Ratifier.js +57 -0
  24. package/lib/cjs/fetch/index.d.ts +5 -0
  25. package/lib/cjs/fetch/index.js +21 -0
  26. package/lib/cjs/fetch/types.d.ts +57 -0
  27. package/lib/cjs/fetch/types.js +2 -0
  28. package/lib/cjs/fetch/utils.d.ts +8 -0
  29. package/lib/cjs/fetch/utils.js +18 -0
  30. package/lib/cjs/index.d.ts +18 -0
  31. package/lib/cjs/index.js +57 -0
  32. package/lib/cjs/market/Market.d.ts +613 -0
  33. package/lib/cjs/market/Market.js +503 -0
  34. package/lib/cjs/market/MarketUtils.d.ts +189 -0
  35. package/lib/cjs/market/MarketUtils.js +303 -0
  36. package/lib/cjs/market/Position.d.ts +424 -0
  37. package/lib/cjs/market/Position.js +425 -0
  38. package/lib/cjs/market/PositionUtils.d.ts +115 -0
  39. package/lib/cjs/market/PositionUtils.js +194 -0
  40. package/lib/cjs/market/index.d.ts +4 -0
  41. package/lib/cjs/market/index.js +20 -0
  42. package/lib/cjs/math/ConsumableUnitsLib.d.ts +57 -0
  43. package/lib/cjs/math/ConsumableUnitsLib.js +77 -0
  44. package/lib/cjs/math/TakeAmountsLib.d.ts +175 -0
  45. package/lib/cjs/math/TakeAmountsLib.js +199 -0
  46. package/lib/cjs/math/TickLib.d.ts +200 -0
  47. package/lib/cjs/math/TickLib.js +272 -0
  48. package/lib/cjs/math/index.d.ts +3 -0
  49. package/lib/cjs/math/index.js +19 -0
  50. package/lib/cjs/offers/Offer.d.ts +534 -0
  51. package/lib/cjs/offers/Offer.js +343 -0
  52. package/lib/cjs/offers/OfferUtils.d.ts +565 -0
  53. package/lib/cjs/offers/OfferUtils.js +659 -0
  54. package/lib/cjs/offers/index.d.ts +2 -0
  55. package/lib/cjs/offers/index.js +18 -0
  56. package/lib/cjs/package.json +1 -0
  57. package/lib/cjs/queries/GetPosition.d.ts +55 -0
  58. package/lib/cjs/queries/GetPosition.js +74 -0
  59. package/lib/cjs/queries/index.d.ts +1 -0
  60. package/lib/cjs/queries/index.js +37 -0
  61. package/lib/cjs/signatures/EcrecoverRatifierUtils.d.ts +733 -0
  62. package/lib/cjs/signatures/EcrecoverRatifierUtils.js +618 -0
  63. package/lib/cjs/signatures/Group.d.ts +178 -0
  64. package/lib/cjs/signatures/Group.js +193 -0
  65. package/lib/cjs/signatures/GroupUtils.d.ts +191 -0
  66. package/lib/cjs/signatures/GroupUtils.js +127 -0
  67. package/lib/cjs/signatures/Payload.d.ts +283 -0
  68. package/lib/cjs/signatures/Payload.js +570 -0
  69. package/lib/cjs/signatures/RatifierUtils.d.ts +109 -0
  70. package/lib/cjs/signatures/RatifierUtils.js +76 -0
  71. package/lib/cjs/signatures/SetterRatifierUtils.d.ts +243 -0
  72. package/lib/cjs/signatures/SetterRatifierUtils.js +217 -0
  73. package/lib/cjs/signatures/Tree.d.ts +241 -0
  74. package/lib/cjs/signatures/Tree.js +263 -0
  75. package/lib/cjs/signatures/TreeUtils.d.ts +573 -0
  76. package/lib/cjs/signatures/TreeUtils.js +461 -0
  77. package/lib/cjs/signatures/index.d.ts +7 -0
  78. package/lib/cjs/signatures/index.js +23 -0
  79. package/lib/esm/abis.d.ts +3170 -0
  80. package/lib/esm/abis.js +4070 -0
  81. package/lib/esm/api/MidnightApi.d.ts +532 -0
  82. package/lib/esm/api/MidnightApi.js +709 -0
  83. package/lib/esm/api/helpers.d.ts +20 -0
  84. package/lib/esm/api/helpers.js +180 -0
  85. package/lib/esm/api/index.d.ts +2 -0
  86. package/lib/esm/api/index.js +2 -0
  87. package/lib/esm/api/types.d.ts +453 -0
  88. package/lib/esm/api/types.js +1 -0
  89. package/lib/esm/constants.d.ts +168 -0
  90. package/lib/esm/constants.js +184 -0
  91. package/lib/esm/errors.d.ts +253 -0
  92. package/lib/esm/errors.js +291 -0
  93. package/lib/esm/fetch/Market.d.ts +65 -0
  94. package/lib/esm/fetch/Market.js +113 -0
  95. package/lib/esm/fetch/Offer.d.ts +74 -0
  96. package/lib/esm/fetch/Offer.js +116 -0
  97. package/lib/esm/fetch/Position.d.ts +85 -0
  98. package/lib/esm/fetch/Position.js +144 -0
  99. package/lib/esm/fetch/Ratifier.d.ts +38 -0
  100. package/lib/esm/fetch/Ratifier.js +54 -0
  101. package/lib/esm/fetch/index.d.ts +5 -0
  102. package/lib/esm/fetch/index.js +5 -0
  103. package/lib/esm/fetch/types.d.ts +57 -0
  104. package/lib/esm/fetch/types.js +1 -0
  105. package/lib/esm/fetch/utils.d.ts +8 -0
  106. package/lib/esm/fetch/utils.js +12 -0
  107. package/lib/esm/index.d.ts +18 -0
  108. package/lib/esm/index.js +18 -0
  109. package/lib/esm/market/Market.d.ts +613 -0
  110. package/lib/esm/market/Market.js +498 -0
  111. package/lib/esm/market/MarketUtils.d.ts +189 -0
  112. package/lib/esm/market/MarketUtils.js +300 -0
  113. package/lib/esm/market/Position.d.ts +424 -0
  114. package/lib/esm/market/Position.js +420 -0
  115. package/lib/esm/market/PositionUtils.d.ts +115 -0
  116. package/lib/esm/market/PositionUtils.js +191 -0
  117. package/lib/esm/market/index.d.ts +4 -0
  118. package/lib/esm/market/index.js +4 -0
  119. package/lib/esm/math/ConsumableUnitsLib.d.ts +57 -0
  120. package/lib/esm/math/ConsumableUnitsLib.js +74 -0
  121. package/lib/esm/math/TakeAmountsLib.d.ts +175 -0
  122. package/lib/esm/math/TakeAmountsLib.js +196 -0
  123. package/lib/esm/math/TickLib.d.ts +200 -0
  124. package/lib/esm/math/TickLib.js +269 -0
  125. package/lib/esm/math/index.d.ts +3 -0
  126. package/lib/esm/math/index.js +3 -0
  127. package/lib/esm/offers/Offer.d.ts +534 -0
  128. package/lib/esm/offers/Offer.js +339 -0
  129. package/lib/esm/offers/OfferUtils.d.ts +565 -0
  130. package/lib/esm/offers/OfferUtils.js +656 -0
  131. package/lib/esm/offers/index.d.ts +2 -0
  132. package/lib/esm/offers/index.js +2 -0
  133. package/lib/esm/package.json +1 -0
  134. package/lib/esm/queries/GetPosition.d.ts +55 -0
  135. package/lib/esm/queries/GetPosition.js +71 -0
  136. package/lib/esm/queries/index.d.ts +1 -0
  137. package/lib/esm/queries/index.js +1 -0
  138. package/lib/esm/signatures/EcrecoverRatifierUtils.d.ts +733 -0
  139. package/lib/esm/signatures/EcrecoverRatifierUtils.js +615 -0
  140. package/lib/esm/signatures/Group.d.ts +178 -0
  141. package/lib/esm/signatures/Group.js +189 -0
  142. package/lib/esm/signatures/GroupUtils.d.ts +191 -0
  143. package/lib/esm/signatures/GroupUtils.js +124 -0
  144. package/lib/esm/signatures/Payload.d.ts +283 -0
  145. package/lib/esm/signatures/Payload.js +564 -0
  146. package/lib/esm/signatures/RatifierUtils.d.ts +109 -0
  147. package/lib/esm/signatures/RatifierUtils.js +73 -0
  148. package/lib/esm/signatures/SetterRatifierUtils.d.ts +243 -0
  149. package/lib/esm/signatures/SetterRatifierUtils.js +214 -0
  150. package/lib/esm/signatures/Tree.d.ts +241 -0
  151. package/lib/esm/signatures/Tree.js +259 -0
  152. package/lib/esm/signatures/TreeUtils.d.ts +573 -0
  153. package/lib/esm/signatures/TreeUtils.js +458 -0
  154. package/lib/esm/signatures/index.d.ts +7 -0
  155. package/lib/esm/signatures/index.js +7 -0
  156. package/package.json +69 -0
  157. package/src/index.ts +19 -0
@@ -0,0 +1,178 @@
1
+ import type { Hash } from "viem";
2
+ import { type IOffer, Offer } from "../offers/index.js";
3
+ import { type GroupInput, type IGroup } from "./GroupUtils.js";
4
+ /**
5
+ * Protocol offer group with one shared consumption group id.
6
+ *
7
+ * Create a group after building related offers and before building the tree to
8
+ * publish. Offers inside one group must share maker, side, and loan token. The
9
+ * constructor hashes every offer to derive the group id, then copies each offer
10
+ * with that id. Offers inside one group must also share cap mode and value
11
+ * because Midnight tracks one consumed scalar per maker and group; group
12
+ * creation is resource-intensive compared to offer construction.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
17
+ * import { zeroAddress } from "viem";
18
+ *
19
+ * const offer = Offer.create({
20
+ * market: {
21
+ * loanToken: "0x0000000000000000000000000000000000006000",
22
+ * collateralParams: [
23
+ * {
24
+ * token: "0x0000000000000000000000000000000000007000",
25
+ * lltv: 770000000000000000n,
26
+ * maxLif: 1061007957559681697n,
27
+ * oracle: "0x0000000000000000000000000000000000008000",
28
+ * },
29
+ * ],
30
+ * maturity: 54_000n,
31
+ * rcfThreshold: 0n,
32
+ * enterGate: zeroAddress,
33
+ * liquidatorGate: zeroAddress,
34
+ * },
35
+ * buy: true,
36
+ * maker: "0x0000000000000000000000000000000000009000",
37
+ * tick: 5_000n,
38
+ * expiry: 3_600n,
39
+ * ratifier: "0x0000000000000000000000000000000000004000",
40
+ * maxUnits: 100n,
41
+ * });
42
+ * const group = Group.create([offer]);
43
+ * console.log(group.offers.length);
44
+ * ```
45
+ */
46
+ export declare class Group implements IGroup {
47
+ private readonly _offers;
48
+ /** Content-addressed group id. */
49
+ readonly id: Hash;
50
+ private constructor();
51
+ /**
52
+ * Offers in this protocol group.
53
+ *
54
+ * Returns a fresh array so callers cannot mutate the group's offer list.
55
+ *
56
+ * @returns Offers in caller order.
57
+ * @example
58
+ * ```ts
59
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
60
+ * import { zeroAddress } from "viem";
61
+ *
62
+ * const offer = Offer.create({
63
+ * market: {
64
+ * loanToken: "0x0000000000000000000000000000000000006000",
65
+ * collateralParams: [
66
+ * {
67
+ * token: "0x0000000000000000000000000000000000007000",
68
+ * lltv: 770000000000000000n,
69
+ * maxLif: 1061007957559681697n,
70
+ * oracle: "0x0000000000000000000000000000000000008000",
71
+ * },
72
+ * ],
73
+ * maturity: 54_000n,
74
+ * rcfThreshold: 0n,
75
+ * enterGate: zeroAddress,
76
+ * liquidatorGate: zeroAddress,
77
+ * },
78
+ * buy: true,
79
+ * maker: "0x0000000000000000000000000000000000009000",
80
+ * tick: 5_000n,
81
+ * expiry: 3_600n,
82
+ * ratifier: "0x0000000000000000000000000000000000004000",
83
+ * maxUnits: 100n,
84
+ * });
85
+ * const group = Group.create([offer]);
86
+ * console.log(group.offers.length);
87
+ * ```
88
+ */
89
+ get offers(): readonly Offer[];
90
+ /**
91
+ * Returns a group instance from group or standalone offer input.
92
+ *
93
+ * Use at boundaries that accept either a prebuilt `Group`, a plain `IGroup`,
94
+ * or a standalone offer that should form its own group. Existing `Group`
95
+ * instances are returned as-is.
96
+ *
97
+ * @param entry - Group object or standalone offer.
98
+ * @returns Group instance.
99
+ * @throws {InvalidOfferGroupError} when group mechanics are invalid.
100
+ * @example
101
+ * ```ts
102
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
103
+ * import { zeroAddress } from "viem";
104
+ *
105
+ * const offer = Offer.create({
106
+ * market: {
107
+ * loanToken: "0x0000000000000000000000000000000000006000",
108
+ * collateralParams: [
109
+ * {
110
+ * token: "0x0000000000000000000000000000000000007000",
111
+ * lltv: 770000000000000000n,
112
+ * maxLif: 1061007957559681697n,
113
+ * oracle: "0x0000000000000000000000000000000000008000",
114
+ * },
115
+ * ],
116
+ * maturity: 54_000n,
117
+ * rcfThreshold: 0n,
118
+ * enterGate: zeroAddress,
119
+ * liquidatorGate: zeroAddress,
120
+ * },
121
+ * buy: true,
122
+ * maker: "0x0000000000000000000000000000000000009000",
123
+ * tick: 5_000n,
124
+ * expiry: 3_600n,
125
+ * ratifier: "0x0000000000000000000000000000000000004000",
126
+ * maxUnits: 100n,
127
+ * });
128
+ * const group = Group.from(offer);
129
+ * console.log(group.offers.length);
130
+ * ```
131
+ */
132
+ static from(entry: GroupInput): Group;
133
+ /**
134
+ * Creates a protocol-valid offer group.
135
+ *
136
+ * Use after `Offer.create` for laddered offers with the same cap mode and
137
+ * value that should consume from one group id. Pass the returned group into
138
+ * `Tree.create` alongside other groups or standalone offers. This hashes every
139
+ * offer and copies the validated offers into group-owned instances, so it is
140
+ * resource-intensive and should be done once per group definition.
141
+ *
142
+ * @param offers - Iterable of offers to group.
143
+ * @returns Group instance.
144
+ * @throws {InvalidOfferGroupError} when group mechanics are invalid.
145
+ * @example
146
+ * ```ts
147
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
148
+ * import { zeroAddress } from "viem";
149
+ *
150
+ * const offer = Offer.create({
151
+ * market: {
152
+ * loanToken: "0x0000000000000000000000000000000000006000",
153
+ * collateralParams: [
154
+ * {
155
+ * token: "0x0000000000000000000000000000000000007000",
156
+ * lltv: 770000000000000000n,
157
+ * maxLif: 1061007957559681697n,
158
+ * oracle: "0x0000000000000000000000000000000000008000",
159
+ * },
160
+ * ],
161
+ * maturity: 54_000n,
162
+ * rcfThreshold: 0n,
163
+ * enterGate: zeroAddress,
164
+ * liquidatorGate: zeroAddress,
165
+ * },
166
+ * buy: true,
167
+ * maker: "0x0000000000000000000000000000000000009000",
168
+ * tick: 5_000n,
169
+ * expiry: 3_600n,
170
+ * ratifier: "0x0000000000000000000000000000000000004000",
171
+ * maxUnits: 100n,
172
+ * });
173
+ * const group = Group.create([offer]);
174
+ * console.log(group.offers.length);
175
+ * ```
176
+ */
177
+ static create(offers: Iterable<IOffer>): Group;
178
+ }
@@ -0,0 +1,189 @@
1
+ import { Offer, OfferUtils } from "../offers/index.js";
2
+ import { GroupUtils } from "./GroupUtils.js";
3
+ /**
4
+ * Protocol offer group with one shared consumption group id.
5
+ *
6
+ * Create a group after building related offers and before building the tree to
7
+ * publish. Offers inside one group must share maker, side, and loan token. The
8
+ * constructor hashes every offer to derive the group id, then copies each offer
9
+ * with that id. Offers inside one group must also share cap mode and value
10
+ * because Midnight tracks one consumed scalar per maker and group; group
11
+ * creation is resource-intensive compared to offer construction.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
16
+ * import { zeroAddress } from "viem";
17
+ *
18
+ * const offer = Offer.create({
19
+ * market: {
20
+ * loanToken: "0x0000000000000000000000000000000000006000",
21
+ * collateralParams: [
22
+ * {
23
+ * token: "0x0000000000000000000000000000000000007000",
24
+ * lltv: 770000000000000000n,
25
+ * maxLif: 1061007957559681697n,
26
+ * oracle: "0x0000000000000000000000000000000000008000",
27
+ * },
28
+ * ],
29
+ * maturity: 54_000n,
30
+ * rcfThreshold: 0n,
31
+ * enterGate: zeroAddress,
32
+ * liquidatorGate: zeroAddress,
33
+ * },
34
+ * buy: true,
35
+ * maker: "0x0000000000000000000000000000000000009000",
36
+ * tick: 5_000n,
37
+ * expiry: 3_600n,
38
+ * ratifier: "0x0000000000000000000000000000000000004000",
39
+ * maxUnits: 100n,
40
+ * });
41
+ * const group = Group.create([offer]);
42
+ * console.log(group.offers.length);
43
+ * ```
44
+ */
45
+ export class Group {
46
+ _offers;
47
+ /** Content-addressed group id. */
48
+ id;
49
+ constructor(offers) {
50
+ const validatedOffers = OfferUtils.validateOfferGroup({ offers });
51
+ this.id = GroupUtils.hash(validatedOffers);
52
+ this._offers = validatedOffers.map((offer) => new Offer({ ...offer, group: this.id }));
53
+ }
54
+ /**
55
+ * Offers in this protocol group.
56
+ *
57
+ * Returns a fresh array so callers cannot mutate the group's offer list.
58
+ *
59
+ * @returns Offers in caller order.
60
+ * @example
61
+ * ```ts
62
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
63
+ * import { zeroAddress } from "viem";
64
+ *
65
+ * const offer = Offer.create({
66
+ * market: {
67
+ * loanToken: "0x0000000000000000000000000000000000006000",
68
+ * collateralParams: [
69
+ * {
70
+ * token: "0x0000000000000000000000000000000000007000",
71
+ * lltv: 770000000000000000n,
72
+ * maxLif: 1061007957559681697n,
73
+ * oracle: "0x0000000000000000000000000000000000008000",
74
+ * },
75
+ * ],
76
+ * maturity: 54_000n,
77
+ * rcfThreshold: 0n,
78
+ * enterGate: zeroAddress,
79
+ * liquidatorGate: zeroAddress,
80
+ * },
81
+ * buy: true,
82
+ * maker: "0x0000000000000000000000000000000000009000",
83
+ * tick: 5_000n,
84
+ * expiry: 3_600n,
85
+ * ratifier: "0x0000000000000000000000000000000000004000",
86
+ * maxUnits: 100n,
87
+ * });
88
+ * const group = Group.create([offer]);
89
+ * console.log(group.offers.length);
90
+ * ```
91
+ */
92
+ get offers() {
93
+ return [...this._offers];
94
+ }
95
+ /**
96
+ * Returns a group instance from group or standalone offer input.
97
+ *
98
+ * Use at boundaries that accept either a prebuilt `Group`, a plain `IGroup`,
99
+ * or a standalone offer that should form its own group. Existing `Group`
100
+ * instances are returned as-is.
101
+ *
102
+ * @param entry - Group object or standalone offer.
103
+ * @returns Group instance.
104
+ * @throws {InvalidOfferGroupError} when group mechanics are invalid.
105
+ * @example
106
+ * ```ts
107
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
108
+ * import { zeroAddress } from "viem";
109
+ *
110
+ * const offer = Offer.create({
111
+ * market: {
112
+ * loanToken: "0x0000000000000000000000000000000000006000",
113
+ * collateralParams: [
114
+ * {
115
+ * token: "0x0000000000000000000000000000000000007000",
116
+ * lltv: 770000000000000000n,
117
+ * maxLif: 1061007957559681697n,
118
+ * oracle: "0x0000000000000000000000000000000000008000",
119
+ * },
120
+ * ],
121
+ * maturity: 54_000n,
122
+ * rcfThreshold: 0n,
123
+ * enterGate: zeroAddress,
124
+ * liquidatorGate: zeroAddress,
125
+ * },
126
+ * buy: true,
127
+ * maker: "0x0000000000000000000000000000000000009000",
128
+ * tick: 5_000n,
129
+ * expiry: 3_600n,
130
+ * ratifier: "0x0000000000000000000000000000000000004000",
131
+ * maxUnits: 100n,
132
+ * });
133
+ * const group = Group.from(offer);
134
+ * console.log(group.offers.length);
135
+ * ```
136
+ */
137
+ static from(entry) {
138
+ return entry instanceof Group
139
+ ? entry
140
+ : new Group("offers" in entry ? entry.offers : [entry]);
141
+ }
142
+ /**
143
+ * Creates a protocol-valid offer group.
144
+ *
145
+ * Use after `Offer.create` for laddered offers with the same cap mode and
146
+ * value that should consume from one group id. Pass the returned group into
147
+ * `Tree.create` alongside other groups or standalone offers. This hashes every
148
+ * offer and copies the validated offers into group-owned instances, so it is
149
+ * resource-intensive and should be done once per group definition.
150
+ *
151
+ * @param offers - Iterable of offers to group.
152
+ * @returns Group instance.
153
+ * @throws {InvalidOfferGroupError} when group mechanics are invalid.
154
+ * @example
155
+ * ```ts
156
+ * import { Group, Offer } from "@morpho-org/midnight-sdk";
157
+ * import { zeroAddress } from "viem";
158
+ *
159
+ * const offer = Offer.create({
160
+ * market: {
161
+ * loanToken: "0x0000000000000000000000000000000000006000",
162
+ * collateralParams: [
163
+ * {
164
+ * token: "0x0000000000000000000000000000000000007000",
165
+ * lltv: 770000000000000000n,
166
+ * maxLif: 1061007957559681697n,
167
+ * oracle: "0x0000000000000000000000000000000000008000",
168
+ * },
169
+ * ],
170
+ * maturity: 54_000n,
171
+ * rcfThreshold: 0n,
172
+ * enterGate: zeroAddress,
173
+ * liquidatorGate: zeroAddress,
174
+ * },
175
+ * buy: true,
176
+ * maker: "0x0000000000000000000000000000000000009000",
177
+ * tick: 5_000n,
178
+ * expiry: 3_600n,
179
+ * ratifier: "0x0000000000000000000000000000000000004000",
180
+ * maxUnits: 100n,
181
+ * });
182
+ * const group = Group.create([offer]);
183
+ * console.log(group.offers.length);
184
+ * ```
185
+ */
186
+ static create(offers) {
187
+ return new Group(offers);
188
+ }
189
+ }
@@ -0,0 +1,191 @@
1
+ import { type Hash } from "viem";
2
+ import { type IOffer, type OfferStruct } from "../offers/index.js";
3
+ /**
4
+ * Plain offer group shape accepted by group and tree utilities.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { Offer, type IGroup } from "@morpho-org/midnight-sdk";
9
+ * import { zeroAddress } from "viem";
10
+ *
11
+ * const group: IGroup = {
12
+ * offers: [
13
+ * Offer.create({
14
+ * market: {
15
+ * loanToken: "0x0000000000000000000000000000000000006000",
16
+ * collateralParams: [
17
+ * {
18
+ * token: "0x0000000000000000000000000000000000007000",
19
+ * lltv: 770000000000000000n,
20
+ * maxLif: 1061007957559681697n,
21
+ * oracle: "0x0000000000000000000000000000000000008000",
22
+ * },
23
+ * ],
24
+ * maturity: 54_000n,
25
+ * rcfThreshold: 0n,
26
+ * enterGate: zeroAddress,
27
+ * liquidatorGate: zeroAddress,
28
+ * },
29
+ * buy: true,
30
+ * maker: "0x0000000000000000000000000000000000009000",
31
+ * tick: 5_000n,
32
+ * group: zeroHash,
33
+ * expiry: 3_600n,
34
+ * ratifier: "0x0000000000000000000000000000000000004000",
35
+ * maxUnits: 100n,
36
+ * }),
37
+ * ],
38
+ * };
39
+ * console.log(group.offers.length);
40
+ * ```
41
+ */
42
+ export interface IGroup {
43
+ /** Offers in this protocol group. The group id is derived from this list. */
44
+ readonly offers: readonly IOffer[];
45
+ }
46
+ /**
47
+ * Group object or standalone offer accepted by tree helpers.
48
+ *
49
+ * Use standalone offers for independent consumption groups. Use `Group.create`
50
+ * first when multiple offers from the same maker, side, loan token, cap mode,
51
+ * and cap value should share one consumption group.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import { Offer, type GroupInput } from "@morpho-org/midnight-sdk";
56
+ * import { zeroAddress } from "viem";
57
+ *
58
+ * const input: GroupInput = Offer.create({
59
+ * market: {
60
+ * loanToken: "0x0000000000000000000000000000000000006000",
61
+ * collateralParams: [
62
+ * {
63
+ * token: "0x0000000000000000000000000000000000007000",
64
+ * lltv: 770000000000000000n,
65
+ * maxLif: 1061007957559681697n,
66
+ * oracle: "0x0000000000000000000000000000000000008000",
67
+ * },
68
+ * ],
69
+ * maturity: 54_000n,
70
+ * rcfThreshold: 0n,
71
+ * enterGate: zeroAddress,
72
+ * liquidatorGate: zeroAddress,
73
+ * },
74
+ * buy: true,
75
+ * maker: "0x0000000000000000000000000000000000009000",
76
+ * tick: 5_000n,
77
+ * expiry: 3_600n,
78
+ * ratifier: "0x0000000000000000000000000000000000004000",
79
+ * maxUnits: 100n,
80
+ * });
81
+ * console.log(input);
82
+ * ```
83
+ */
84
+ export type GroupInput = IGroup | IOffer;
85
+ /**
86
+ * Make-side helpers for Midnight offer groups.
87
+ *
88
+ * Groups sit between `Offer.create` and `Tree.create`: they assign a
89
+ * content-addressed group id to offers that share one consumption bucket. One
90
+ * group must use one cap mode and value because Midnight tracks a single
91
+ * consumed scalar per maker and group. Tree helpers derive that id for explicit
92
+ * groups and preserve it on grouped offer copies.
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * import { GroupUtils } from "@morpho-org/midnight-sdk";
97
+ *
98
+ * console.log(typeof GroupUtils.hash);
99
+ * ```
100
+ */
101
+ export declare namespace GroupUtils {
102
+ /**
103
+ * Derives the deterministic content-addressed id for a group of offers.
104
+ *
105
+ * This mirrors the router implementation: hash each offer with `group = 0`,
106
+ * sort those hashes, concatenate them, then keccak the result.
107
+ *
108
+ * @param offers - Offers to hash as one group.
109
+ * @returns Content-addressed group id.
110
+ * @throws {InvalidOfferGroupError} when `offers` is empty.
111
+ * @example
112
+ * ```ts
113
+ * import { GroupUtils, Offer } from "@morpho-org/midnight-sdk";
114
+ * import { zeroAddress } from "viem";
115
+ *
116
+ * const offer = Offer.create({
117
+ * market: {
118
+ * loanToken: "0x0000000000000000000000000000000000006000",
119
+ * collateralParams: [
120
+ * {
121
+ * token: "0x0000000000000000000000000000000000007000",
122
+ * lltv: 770000000000000000n,
123
+ * maxLif: 1061007957559681697n,
124
+ * oracle: "0x0000000000000000000000000000000000008000",
125
+ * },
126
+ * ],
127
+ * maturity: 54_000n,
128
+ * rcfThreshold: 0n,
129
+ * enterGate: zeroAddress,
130
+ * liquidatorGate: zeroAddress,
131
+ * },
132
+ * buy: true,
133
+ * maker: "0x0000000000000000000000000000000000009000",
134
+ * tick: 5_000n,
135
+ * expiry: 3_600n,
136
+ * ratifier: "0x0000000000000000000000000000000000004000",
137
+ * maxUnits: 100n,
138
+ * });
139
+ * const id = GroupUtils.hash([offer]);
140
+ * console.log(id);
141
+ * ```
142
+ */
143
+ function hash(offers: Iterable<IOffer>): Hash;
144
+ /**
145
+ * Converts a group into ABI-compatible offers carrying the derived group id.
146
+ *
147
+ * Use after `Group.create` for custom encoders that need offer structs with
148
+ * their final group id. The id is derived from the full offer list and
149
+ * applied while encoding, so plain groups cannot drift from offer fields.
150
+ *
151
+ * This helper is encode-only and does not validate protocol group mechanics.
152
+ * Validate with `Group.create` or {@link OfferUtils.validateOfferGroup}
153
+ * before relying on the output for signing, tree roots, or calldata.
154
+ *
155
+ * @param group - Group to encode.
156
+ * @returns ABI-compatible offers in caller order.
157
+ * @throws {InvalidOfferGroupError} when the group has no offers.
158
+ * @example
159
+ * ```ts
160
+ * import { Group, GroupUtils, Offer } from "@morpho-org/midnight-sdk";
161
+ * import { zeroAddress } from "viem";
162
+ *
163
+ * const offer = Offer.create({
164
+ * market: {
165
+ * loanToken: "0x0000000000000000000000000000000000006000",
166
+ * collateralParams: [
167
+ * {
168
+ * token: "0x0000000000000000000000000000000000007000",
169
+ * lltv: 770000000000000000n,
170
+ * maxLif: 1061007957559681697n,
171
+ * oracle: "0x0000000000000000000000000000000000008000",
172
+ * },
173
+ * ],
174
+ * maturity: 54_000n,
175
+ * rcfThreshold: 0n,
176
+ * enterGate: zeroAddress,
177
+ * liquidatorGate: zeroAddress,
178
+ * },
179
+ * buy: true,
180
+ * maker: "0x0000000000000000000000000000000000009000",
181
+ * tick: 5_000n,
182
+ * expiry: 3_600n,
183
+ * ratifier: "0x0000000000000000000000000000000000004000",
184
+ * maxUnits: 100n,
185
+ * });
186
+ * const structs = GroupUtils.toStructs(Group.create([offer]));
187
+ * console.log(structs.length);
188
+ * ```
189
+ */
190
+ function toStructs(group: IGroup): readonly OfferStruct[];
191
+ }
@@ -0,0 +1,124 @@
1
+ import { concat, keccak256 } from "viem";
2
+ import { InvalidOfferGroupError } from "../errors.js";
3
+ import { OfferUtils } from "../offers/index.js";
4
+ /**
5
+ * Make-side helpers for Midnight offer groups.
6
+ *
7
+ * Groups sit between `Offer.create` and `Tree.create`: they assign a
8
+ * content-addressed group id to offers that share one consumption bucket. One
9
+ * group must use one cap mode and value because Midnight tracks a single
10
+ * consumed scalar per maker and group. Tree helpers derive that id for explicit
11
+ * groups and preserve it on grouped offer copies.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * import { GroupUtils } from "@morpho-org/midnight-sdk";
16
+ *
17
+ * console.log(typeof GroupUtils.hash);
18
+ * ```
19
+ */
20
+ export var GroupUtils;
21
+ (function (GroupUtils) {
22
+ /**
23
+ * Derives the deterministic content-addressed id for a group of offers.
24
+ *
25
+ * This mirrors the router implementation: hash each offer with `group = 0`,
26
+ * sort those hashes, concatenate them, then keccak the result.
27
+ *
28
+ * @param offers - Offers to hash as one group.
29
+ * @returns Content-addressed group id.
30
+ * @throws {InvalidOfferGroupError} when `offers` is empty.
31
+ * @example
32
+ * ```ts
33
+ * import { GroupUtils, Offer } from "@morpho-org/midnight-sdk";
34
+ * import { zeroAddress } from "viem";
35
+ *
36
+ * const offer = Offer.create({
37
+ * market: {
38
+ * loanToken: "0x0000000000000000000000000000000000006000",
39
+ * collateralParams: [
40
+ * {
41
+ * token: "0x0000000000000000000000000000000000007000",
42
+ * lltv: 770000000000000000n,
43
+ * maxLif: 1061007957559681697n,
44
+ * oracle: "0x0000000000000000000000000000000000008000",
45
+ * },
46
+ * ],
47
+ * maturity: 54_000n,
48
+ * rcfThreshold: 0n,
49
+ * enterGate: zeroAddress,
50
+ * liquidatorGate: zeroAddress,
51
+ * },
52
+ * buy: true,
53
+ * maker: "0x0000000000000000000000000000000000009000",
54
+ * tick: 5_000n,
55
+ * expiry: 3_600n,
56
+ * ratifier: "0x0000000000000000000000000000000000004000",
57
+ * maxUnits: 100n,
58
+ * });
59
+ * const id = GroupUtils.hash([offer]);
60
+ * console.log(id);
61
+ * ```
62
+ */
63
+ function hash(offers) {
64
+ const offerInputs = Array.from(offers);
65
+ if (offerInputs.length === 0) {
66
+ throw new InvalidOfferGroupError("Provide at least one offer in the group.");
67
+ }
68
+ const offerHashes = offerInputs.map((offer) => OfferUtils.groupHash(offer));
69
+ const sorted = offerHashes.length > 1 ? [...offerHashes].sort() : offerHashes;
70
+ return keccak256(concat(sorted));
71
+ }
72
+ GroupUtils.hash = hash;
73
+ /**
74
+ * Converts a group into ABI-compatible offers carrying the derived group id.
75
+ *
76
+ * Use after `Group.create` for custom encoders that need offer structs with
77
+ * their final group id. The id is derived from the full offer list and
78
+ * applied while encoding, so plain groups cannot drift from offer fields.
79
+ *
80
+ * This helper is encode-only and does not validate protocol group mechanics.
81
+ * Validate with `Group.create` or {@link OfferUtils.validateOfferGroup}
82
+ * before relying on the output for signing, tree roots, or calldata.
83
+ *
84
+ * @param group - Group to encode.
85
+ * @returns ABI-compatible offers in caller order.
86
+ * @throws {InvalidOfferGroupError} when the group has no offers.
87
+ * @example
88
+ * ```ts
89
+ * import { Group, GroupUtils, Offer } from "@morpho-org/midnight-sdk";
90
+ * import { zeroAddress } from "viem";
91
+ *
92
+ * const offer = Offer.create({
93
+ * market: {
94
+ * loanToken: "0x0000000000000000000000000000000000006000",
95
+ * collateralParams: [
96
+ * {
97
+ * token: "0x0000000000000000000000000000000000007000",
98
+ * lltv: 770000000000000000n,
99
+ * maxLif: 1061007957559681697n,
100
+ * oracle: "0x0000000000000000000000000000000000008000",
101
+ * },
102
+ * ],
103
+ * maturity: 54_000n,
104
+ * rcfThreshold: 0n,
105
+ * enterGate: zeroAddress,
106
+ * liquidatorGate: zeroAddress,
107
+ * },
108
+ * buy: true,
109
+ * maker: "0x0000000000000000000000000000000000009000",
110
+ * tick: 5_000n,
111
+ * expiry: 3_600n,
112
+ * ratifier: "0x0000000000000000000000000000000000004000",
113
+ * maxUnits: 100n,
114
+ * });
115
+ * const structs = GroupUtils.toStructs(Group.create([offer]));
116
+ * console.log(structs.length);
117
+ * ```
118
+ */
119
+ function toStructs(group) {
120
+ const groupId = hash(group.offers);
121
+ return group.offers.map((offer) => OfferUtils.toStruct({ offer, group: groupId }));
122
+ }
123
+ GroupUtils.toStructs = toStructs;
124
+ })(GroupUtils || (GroupUtils = {}));