blue-js-sdk 2.0.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 (215) hide show
  1. package/CHANGELOG.md +446 -0
  2. package/LICENSE +21 -0
  3. package/README.md +75 -0
  4. package/ai-path/ADMIN-ELEVATION.md +116 -0
  5. package/ai-path/AI-MANIFESTO.md +185 -0
  6. package/ai-path/BREAKING.md +74 -0
  7. package/ai-path/CHECKLIST.md +619 -0
  8. package/ai-path/CONNECTION-STEPS.md +724 -0
  9. package/ai-path/DECISION-TREE.md +378 -0
  10. package/ai-path/DEPENDENCIES.md +459 -0
  11. package/ai-path/E2E-FLOW.md +1555 -0
  12. package/ai-path/FAILURES.md +403 -0
  13. package/ai-path/GUIDE.md +1217 -0
  14. package/ai-path/README.md +558 -0
  15. package/ai-path/SPLIT-TUNNEL.md +266 -0
  16. package/ai-path/cli.js +535 -0
  17. package/ai-path/connect.js +884 -0
  18. package/ai-path/discover.js +178 -0
  19. package/ai-path/environment.js +266 -0
  20. package/ai-path/errors.js +86 -0
  21. package/ai-path/examples/autonomous-agent.mjs +220 -0
  22. package/ai-path/examples/multi-region.mjs +174 -0
  23. package/ai-path/examples/one-shot.mjs +31 -0
  24. package/ai-path/index.js +60 -0
  25. package/ai-path/pricing.js +136 -0
  26. package/ai-path/recommend.js +413 -0
  27. package/ai-path/run-admin.vbs +25 -0
  28. package/ai-path/setup.js +291 -0
  29. package/ai-path/wallet.js +137 -0
  30. package/app-helpers.js +363 -0
  31. package/app-settings.js +95 -0
  32. package/app-types.js +267 -0
  33. package/audit.js +847 -0
  34. package/batch.js +293 -0
  35. package/bin/setup.js +376 -0
  36. package/chain/authz.js +109 -0
  37. package/chain/broadcast.js +472 -0
  38. package/chain/client.js +160 -0
  39. package/chain/fee-grants.js +305 -0
  40. package/chain/index.js +891 -0
  41. package/chain/lcd.js +313 -0
  42. package/chain/queries.js +547 -0
  43. package/chain/rpc.js +408 -0
  44. package/chain/wallet.js +141 -0
  45. package/cli/config.js +143 -0
  46. package/cli/index.js +463 -0
  47. package/cli/output.js +182 -0
  48. package/cli.js +491 -0
  49. package/client/index.js +251 -0
  50. package/client.js +271 -0
  51. package/config/index.js +255 -0
  52. package/connection/connect.js +849 -0
  53. package/connection/disconnect.js +180 -0
  54. package/connection/discovery.js +321 -0
  55. package/connection/index.js +76 -0
  56. package/connection/proxy.js +148 -0
  57. package/connection/resilience.js +428 -0
  58. package/connection/security.js +232 -0
  59. package/connection/state.js +369 -0
  60. package/connection/tunnel.js +691 -0
  61. package/consumer.js +132 -0
  62. package/cosmjs-setup.js +1884 -0
  63. package/defaults.js +366 -0
  64. package/disk-cache.js +107 -0
  65. package/dist/client.d.ts +108 -0
  66. package/dist/client.d.ts.map +1 -0
  67. package/dist/client.js +400 -0
  68. package/dist/client.js.map +1 -0
  69. package/dist/index.d.ts +8 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +8 -0
  72. package/dist/index.js.map +1 -0
  73. package/errors/index.js +112 -0
  74. package/errors.js +218 -0
  75. package/examples/README.md +64 -0
  76. package/examples/connect-direct.mjs +106 -0
  77. package/examples/connect-plan.mjs +125 -0
  78. package/examples/error-handling.mjs +109 -0
  79. package/examples/query-nodes.mjs +94 -0
  80. package/examples/wallet-basics.mjs +61 -0
  81. package/generated/amino/amino.ts +9 -0
  82. package/generated/cosmos/base/v1beta1/coin.ts +365 -0
  83. package/generated/cosmos_proto/cosmos.ts +323 -0
  84. package/generated/gogoproto/gogo.ts +9 -0
  85. package/generated/google/protobuf/descriptor.ts +7601 -0
  86. package/generated/google/protobuf/duration.ts +208 -0
  87. package/generated/google/protobuf/timestamp.ts +238 -0
  88. package/generated/sentinel/lease/v1/events.ts +924 -0
  89. package/generated/sentinel/lease/v1/lease.ts +292 -0
  90. package/generated/sentinel/lease/v1/msg.ts +949 -0
  91. package/generated/sentinel/lease/v1/params.ts +164 -0
  92. package/generated/sentinel/node/v3/events.ts +881 -0
  93. package/generated/sentinel/node/v3/msg.ts +1002 -0
  94. package/generated/sentinel/node/v3/node.ts +263 -0
  95. package/generated/sentinel/node/v3/params.ts +183 -0
  96. package/generated/sentinel/plan/v3/events.ts +675 -0
  97. package/generated/sentinel/plan/v3/msg.ts +1191 -0
  98. package/generated/sentinel/plan/v3/plan.ts +283 -0
  99. package/generated/sentinel/provider/v2/events.ts +171 -0
  100. package/generated/sentinel/provider/v2/msg.ts +480 -0
  101. package/generated/sentinel/provider/v2/params.ts +131 -0
  102. package/generated/sentinel/provider/v2/provider.ts +246 -0
  103. package/generated/sentinel/session/v3/events.ts +480 -0
  104. package/generated/sentinel/session/v3/msg.ts +616 -0
  105. package/generated/sentinel/session/v3/params.ts +260 -0
  106. package/generated/sentinel/session/v3/proof.ts +180 -0
  107. package/generated/sentinel/session/v3/session.ts +384 -0
  108. package/generated/sentinel/subscription/v3/events.ts +1181 -0
  109. package/generated/sentinel/subscription/v3/msg.ts +1305 -0
  110. package/generated/sentinel/subscription/v3/params.ts +167 -0
  111. package/generated/sentinel/subscription/v3/subscription.ts +315 -0
  112. package/generated/sentinel/types/v1/bandwidth.ts +124 -0
  113. package/generated/sentinel/types/v1/price.ts +149 -0
  114. package/generated/sentinel/types/v1/renewal.ts +87 -0
  115. package/generated/sentinel/types/v1/status.ts +54 -0
  116. package/generated/typeRegistry.ts +27 -0
  117. package/index.js +486 -0
  118. package/node-connect.js +3015 -0
  119. package/operator.js +134 -0
  120. package/package.json +113 -0
  121. package/plan-operations.js +199 -0
  122. package/preflight.js +352 -0
  123. package/pricing/index.js +262 -0
  124. package/proto/amino/amino.proto +84 -0
  125. package/proto/cosmos/base/v1beta1/coin.proto +61 -0
  126. package/proto/cosmos_proto/cosmos.proto +112 -0
  127. package/proto/gogoproto/gogo.proto +145 -0
  128. package/proto/google/api/annotations.proto +31 -0
  129. package/proto/google/api/http.proto +370 -0
  130. package/proto/google/protobuf/any.proto +106 -0
  131. package/proto/google/protobuf/duration.proto +115 -0
  132. package/proto/google/protobuf/timestamp.proto +145 -0
  133. package/proto/sentinel/lease/v1/events.proto +52 -0
  134. package/proto/sentinel/lease/v1/genesis.proto +15 -0
  135. package/proto/sentinel/lease/v1/lease.proto +25 -0
  136. package/proto/sentinel/lease/v1/msg.proto +62 -0
  137. package/proto/sentinel/lease/v1/params.proto +17 -0
  138. package/proto/sentinel/node/v3/events.proto +50 -0
  139. package/proto/sentinel/node/v3/genesis.proto +15 -0
  140. package/proto/sentinel/node/v3/msg.proto +63 -0
  141. package/proto/sentinel/node/v3/node.proto +27 -0
  142. package/proto/sentinel/node/v3/params.proto +21 -0
  143. package/proto/sentinel/node/v3/querier.proto +63 -0
  144. package/proto/sentinel/plan/v3/events.proto +41 -0
  145. package/proto/sentinel/plan/v3/genesis.proto +21 -0
  146. package/proto/sentinel/plan/v3/msg.proto +83 -0
  147. package/proto/sentinel/plan/v3/plan.proto +32 -0
  148. package/proto/sentinel/plan/v3/querier.proto +53 -0
  149. package/proto/sentinel/provider/v2/events.proto +16 -0
  150. package/proto/sentinel/provider/v2/genesis.proto +15 -0
  151. package/proto/sentinel/provider/v2/msg.proto +35 -0
  152. package/proto/sentinel/provider/v2/params.proto +17 -0
  153. package/proto/sentinel/provider/v2/provider.proto +24 -0
  154. package/proto/sentinel/provider/v3/genesis.proto +15 -0
  155. package/proto/sentinel/provider/v3/params.proto +13 -0
  156. package/proto/sentinel/session/v3/events.proto +30 -0
  157. package/proto/sentinel/session/v3/genesis.proto +15 -0
  158. package/proto/sentinel/session/v3/msg.proto +50 -0
  159. package/proto/sentinel/session/v3/params.proto +25 -0
  160. package/proto/sentinel/session/v3/proof.proto +25 -0
  161. package/proto/sentinel/session/v3/querier.proto +100 -0
  162. package/proto/sentinel/session/v3/session.proto +50 -0
  163. package/proto/sentinel/subscription/v2/allocation.proto +21 -0
  164. package/proto/sentinel/subscription/v2/payout.proto +22 -0
  165. package/proto/sentinel/subscription/v3/events.proto +65 -0
  166. package/proto/sentinel/subscription/v3/genesis.proto +17 -0
  167. package/proto/sentinel/subscription/v3/msg.proto +83 -0
  168. package/proto/sentinel/subscription/v3/params.proto +21 -0
  169. package/proto/sentinel/subscription/v3/subscription.proto +33 -0
  170. package/proto/sentinel/types/v1/bandwidth.proto +19 -0
  171. package/proto/sentinel/types/v1/price.proto +21 -0
  172. package/proto/sentinel/types/v1/renewal.proto +21 -0
  173. package/proto/sentinel/types/v1/status.proto +16 -0
  174. package/protocol/encoding.js +341 -0
  175. package/protocol/events.js +361 -0
  176. package/protocol/handshake.js +297 -0
  177. package/protocol/index.js +15 -0
  178. package/protocol/messages.js +346 -0
  179. package/protocol/plans.js +199 -0
  180. package/protocol/v2ray.js +268 -0
  181. package/protocol/v3.js +723 -0
  182. package/protocol/wireguard.js +125 -0
  183. package/security/index.js +132 -0
  184. package/session-manager.js +329 -0
  185. package/session-tracker.js +80 -0
  186. package/setup.js +376 -0
  187. package/speedtest/index.js +528 -0
  188. package/speedtest.js +567 -0
  189. package/src/client.ts +502 -0
  190. package/src/index.ts +20 -0
  191. package/state/index.js +347 -0
  192. package/state.js +516 -0
  193. package/test-all-chain-ops.js +493 -0
  194. package/test-all-logic.js +199 -0
  195. package/test-all-msg-types.js +292 -0
  196. package/test-every-connection.js +208 -0
  197. package/test-feegrant-connect.js +98 -0
  198. package/test-logic.js +148 -0
  199. package/test-mainnet.js +176 -0
  200. package/test-plan-lifecycle.js +335 -0
  201. package/tls-trust.js +132 -0
  202. package/tsconfig.build.json +20 -0
  203. package/tsconfig.json +34 -0
  204. package/types/chain.d.ts +746 -0
  205. package/types/connection.d.ts +425 -0
  206. package/types/errors.d.ts +174 -0
  207. package/types/index.d.ts +1380 -0
  208. package/types/nodes.d.ts +187 -0
  209. package/types/pricing.d.ts +156 -0
  210. package/types/protocol.d.ts +332 -0
  211. package/types/session.d.ts +236 -0
  212. package/types/settings.d.ts +192 -0
  213. package/v3protocol.js +1053 -0
  214. package/wallet/index.js +153 -0
  215. package/wireguard.js +307 -0
@@ -0,0 +1,346 @@
1
+ /**
2
+ * Sentinel SDK — Protocol / Message Builders
3
+ *
4
+ * Returns proper EncodeObject ({ typeUrl, value }) for each Sentinel message type.
5
+ * These are ready for CosmJS signAndBroadcast() — no wrapping needed.
6
+ *
7
+ * The encodeMsg*() functions in encoding.js return raw Uint8Array (protobuf bytes).
8
+ * These buildMsg*() functions return { typeUrl, value: object } that CosmJS can encode
9
+ * via the Registry. Use these for all external/consumer usage.
10
+ *
11
+ * Usage:
12
+ * import { buildMsgStartSession } from './protocol/messages.js';
13
+ * const msg = buildMsgStartSession({ from, nodeAddress, gigabytes: 1, maxPrice });
14
+ * const result = await client.signAndBroadcast(address, [msg], fee);
15
+ */
16
+
17
+ // ─── Type URL Constants ────────────────────────────────────────────────────
18
+
19
+ export const TYPE_URLS = {
20
+ // Node sessions
21
+ START_SESSION: '/sentinel.node.v3.MsgStartSessionRequest',
22
+ CANCEL_SESSION: '/sentinel.session.v3.MsgCancelSessionRequest',
23
+ UPDATE_SESSION: '/sentinel.session.v3.MsgUpdateSessionRequest',
24
+ // Subscriptions
25
+ START_SUBSCRIPTION: '/sentinel.subscription.v3.MsgStartSubscriptionRequest',
26
+ CANCEL_SUBSCRIPTION: '/sentinel.subscription.v3.MsgCancelSubscriptionRequest',
27
+ RENEW_SUBSCRIPTION: '/sentinel.subscription.v3.MsgRenewSubscriptionRequest',
28
+ SHARE_SUBSCRIPTION: '/sentinel.subscription.v3.MsgShareSubscriptionRequest',
29
+ UPDATE_SUBSCRIPTION: '/sentinel.subscription.v3.MsgUpdateSubscriptionRequest',
30
+ SUB_START_SESSION: '/sentinel.subscription.v3.MsgStartSessionRequest',
31
+ // Plans
32
+ PLAN_START_SESSION: '/sentinel.plan.v3.MsgStartSessionRequest',
33
+ CREATE_PLAN: '/sentinel.plan.v3.MsgCreatePlanRequest',
34
+ UPDATE_PLAN_DETAILS: '/sentinel.plan.v3.MsgUpdatePlanDetailsRequest',
35
+ UPDATE_PLAN_STATUS: '/sentinel.plan.v3.MsgUpdatePlanStatusRequest',
36
+ LINK_NODE: '/sentinel.plan.v3.MsgLinkNodeRequest',
37
+ UNLINK_NODE: '/sentinel.plan.v3.MsgUnlinkNodeRequest',
38
+ // Provider
39
+ REGISTER_PROVIDER: '/sentinel.provider.v3.MsgRegisterProviderRequest',
40
+ UPDATE_PROVIDER: '/sentinel.provider.v3.MsgUpdateProviderDetailsRequest',
41
+ UPDATE_PROVIDER_STATUS: '/sentinel.provider.v3.MsgUpdateProviderStatusRequest',
42
+ // Lease
43
+ START_LEASE: '/sentinel.lease.v1.MsgStartLeaseRequest',
44
+ END_LEASE: '/sentinel.lease.v1.MsgEndLeaseRequest',
45
+ // Node operator
46
+ REGISTER_NODE: '/sentinel.node.v3.MsgRegisterNodeRequest',
47
+ UPDATE_NODE_DETAILS: '/sentinel.node.v3.MsgUpdateNodeDetailsRequest',
48
+ UPDATE_NODE_STATUS: '/sentinel.node.v3.MsgUpdateNodeStatusRequest',
49
+ };
50
+
51
+ // ─── Session Message Builders ──────────────────────────────────────────────
52
+
53
+ /**
54
+ * Build MsgStartSessionRequest (direct node session).
55
+ * @param {{ from: string, nodeAddress: string, gigabytes?: number, hours?: number, maxPrice?: { denom: string, amount: string } }} opts
56
+ * @returns {{ typeUrl: string, value: object }}
57
+ */
58
+ export function buildMsgStartSession({ from, nodeAddress, gigabytes = 1, hours = 0, maxPrice }) {
59
+ return {
60
+ typeUrl: TYPE_URLS.START_SESSION,
61
+ value: {
62
+ from,
63
+ node_address: nodeAddress,
64
+ gigabytes: gigabytes || 0,
65
+ hours: hours || 0,
66
+ max_price: maxPrice || undefined,
67
+ },
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Build MsgCancelSessionRequest (end/cancel a session).
73
+ * @param {{ from: string, id: number|bigint }} opts
74
+ * @returns {{ typeUrl: string, value: object }}
75
+ */
76
+ export function buildMsgCancelSession({ from, id }) {
77
+ return {
78
+ typeUrl: TYPE_URLS.CANCEL_SESSION,
79
+ value: { from, id: Number(id) },
80
+ };
81
+ }
82
+
83
+ /** Alias for backwards compatibility. */
84
+ export const buildMsgEndSession = buildMsgCancelSession;
85
+
86
+ /**
87
+ * Build MsgUpdateSessionRequest (node reports bandwidth).
88
+ * @param {{ from: string, id: number|bigint, downloadBytes: number, uploadBytes: number }} opts
89
+ * @returns {{ typeUrl: string, value: object }}
90
+ */
91
+ export function buildMsgUpdateSession({ from, id, downloadBytes, uploadBytes }) {
92
+ return {
93
+ typeUrl: TYPE_URLS.UPDATE_SESSION,
94
+ value: { from, id: Number(id), download_bytes: downloadBytes, upload_bytes: uploadBytes },
95
+ };
96
+ }
97
+
98
+ // ─── Subscription Message Builders ─────────────────────────────────────────
99
+
100
+ /**
101
+ * Build MsgStartSubscriptionRequest (subscribe to a plan).
102
+ * @param {{ from: string, id: number|bigint, denom?: string, renewalPricePolicy?: number }} opts
103
+ * @returns {{ typeUrl: string, value: object }}
104
+ */
105
+ export function buildMsgStartSubscription({ from, id, denom = 'udvpn', renewalPricePolicy = 0 }) {
106
+ return {
107
+ typeUrl: TYPE_URLS.START_SUBSCRIPTION,
108
+ value: { from, id: Number(id), denom, renewal_price_policy: renewalPricePolicy },
109
+ };
110
+ }
111
+
112
+ /**
113
+ * Build MsgStartSessionRequest via subscription.
114
+ * @param {{ from: string, id: number|bigint, nodeAddress: string }} opts
115
+ * @returns {{ typeUrl: string, value: object }}
116
+ */
117
+ export function buildMsgSubStartSession({ from, id, nodeAddress }) {
118
+ return {
119
+ typeUrl: TYPE_URLS.SUB_START_SESSION,
120
+ value: { from, id: Number(id), node_address: nodeAddress },
121
+ };
122
+ }
123
+
124
+ /**
125
+ * Build MsgCancelSubscriptionRequest.
126
+ * @param {{ from: string, id: number|bigint }} opts
127
+ * @returns {{ typeUrl: string, value: object }}
128
+ */
129
+ export function buildMsgCancelSubscription({ from, id }) {
130
+ return {
131
+ typeUrl: TYPE_URLS.CANCEL_SUBSCRIPTION,
132
+ value: { from, id: Number(id) },
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Build MsgRenewSubscriptionRequest.
138
+ * @param {{ from: string, id: number|bigint, denom?: string }} opts
139
+ * @returns {{ typeUrl: string, value: object }}
140
+ */
141
+ export function buildMsgRenewSubscription({ from, id, denom = 'udvpn' }) {
142
+ return {
143
+ typeUrl: TYPE_URLS.RENEW_SUBSCRIPTION,
144
+ value: { from, id: Number(id), denom },
145
+ };
146
+ }
147
+
148
+ /**
149
+ * Build MsgShareSubscriptionRequest.
150
+ * @param {{ from: string, id: number|bigint, accAddress: string, bytes: number }} opts
151
+ * @returns {{ typeUrl: string, value: object }}
152
+ */
153
+ export function buildMsgShareSubscription({ from, id, accAddress, bytes }) {
154
+ return {
155
+ typeUrl: TYPE_URLS.SHARE_SUBSCRIPTION,
156
+ value: { from, id: Number(id), acc_address: accAddress, bytes },
157
+ };
158
+ }
159
+
160
+ /**
161
+ * Build MsgUpdateSubscriptionRequest.
162
+ * @param {{ from: string, id: number|bigint, renewalPricePolicy: number }} opts
163
+ * @returns {{ typeUrl: string, value: object }}
164
+ */
165
+ export function buildMsgUpdateSubscription({ from, id, renewalPricePolicy }) {
166
+ return {
167
+ typeUrl: TYPE_URLS.UPDATE_SUBSCRIPTION,
168
+ value: { from, id: Number(id), renewal_price_policy: renewalPricePolicy },
169
+ };
170
+ }
171
+
172
+ // ─── Plan Message Builders ─────────────────────────────────────────────────
173
+
174
+ /**
175
+ * Build MsgStartSessionRequest via plan (creates subscription + starts session).
176
+ * @param {{ from: string, id: number|bigint, denom?: string, renewalPricePolicy?: number, nodeAddress: string }} opts
177
+ * @returns {{ typeUrl: string, value: object }}
178
+ */
179
+ export function buildMsgPlanStartSession({ from, id, denom = 'udvpn', renewalPricePolicy = 0, nodeAddress }) {
180
+ return {
181
+ typeUrl: TYPE_URLS.PLAN_START_SESSION,
182
+ value: { from, id: Number(id), denom, renewal_price_policy: renewalPricePolicy, node_address: nodeAddress },
183
+ };
184
+ }
185
+
186
+ /**
187
+ * Build MsgCreatePlanRequest.
188
+ * @param {{ from: string, bytes: string|number, duration: { seconds: number }, prices?: Array, private?: boolean }} opts
189
+ * @returns {{ typeUrl: string, value: object }}
190
+ */
191
+ export function buildMsgCreatePlan({ from, bytes, duration, prices = [], isPrivate = false }) {
192
+ return {
193
+ typeUrl: TYPE_URLS.CREATE_PLAN,
194
+ value: { from, bytes: String(bytes), duration, prices, private: isPrivate },
195
+ };
196
+ }
197
+
198
+ /**
199
+ * Build MsgUpdatePlanDetailsRequest.
200
+ * @param {{ from: string, id: number|bigint, bytes?: string|number, duration?: object, prices?: Array }} opts
201
+ * @returns {{ typeUrl: string, value: object }}
202
+ */
203
+ export function buildMsgUpdatePlanDetails({ from, id, bytes, duration, prices = [] }) {
204
+ return {
205
+ typeUrl: TYPE_URLS.UPDATE_PLAN_DETAILS,
206
+ value: { from, id: Number(id), bytes: bytes ? String(bytes) : undefined, duration, prices },
207
+ };
208
+ }
209
+
210
+ /**
211
+ * Build MsgUpdatePlanStatusRequest.
212
+ * @param {{ from: string, id: number|bigint, status: number }} opts
213
+ * @returns {{ typeUrl: string, value: object }}
214
+ */
215
+ export function buildMsgUpdatePlanStatus({ from, id, status }) {
216
+ return {
217
+ typeUrl: TYPE_URLS.UPDATE_PLAN_STATUS,
218
+ value: { from, id: Number(id), status },
219
+ };
220
+ }
221
+
222
+ /**
223
+ * Build MsgLinkNodeRequest.
224
+ * @param {{ from: string, id: number|bigint, nodeAddress: string }} opts
225
+ * @returns {{ typeUrl: string, value: object }}
226
+ */
227
+ export function buildMsgLinkNode({ from, id, nodeAddress }) {
228
+ return {
229
+ typeUrl: TYPE_URLS.LINK_NODE,
230
+ value: { from, id: Number(id), node_address: nodeAddress },
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Build MsgUnlinkNodeRequest.
236
+ * @param {{ from: string, id: number|bigint, nodeAddress: string }} opts
237
+ * @returns {{ typeUrl: string, value: object }}
238
+ */
239
+ export function buildMsgUnlinkNode({ from, id, nodeAddress }) {
240
+ return {
241
+ typeUrl: TYPE_URLS.UNLINK_NODE,
242
+ value: { from, id: Number(id), node_address: nodeAddress },
243
+ };
244
+ }
245
+
246
+ // ─── Provider Message Builders ─────────────────────────────────────────────
247
+
248
+ /**
249
+ * Build MsgRegisterProviderRequest.
250
+ * @param {{ from: string, name: string, identity?: string, website?: string, description?: string }} opts
251
+ * @returns {{ typeUrl: string, value: object }}
252
+ */
253
+ export function buildMsgRegisterProvider({ from, name, identity = '', website = '', description = '' }) {
254
+ return {
255
+ typeUrl: TYPE_URLS.REGISTER_PROVIDER,
256
+ value: { from, name, identity, website, description },
257
+ };
258
+ }
259
+
260
+ /**
261
+ * Build MsgUpdateProviderDetailsRequest.
262
+ * @param {{ from: string, name?: string, identity?: string, website?: string, description?: string }} opts
263
+ * @returns {{ typeUrl: string, value: object }}
264
+ */
265
+ export function buildMsgUpdateProviderDetails({ from, name, identity, website, description }) {
266
+ return {
267
+ typeUrl: TYPE_URLS.UPDATE_PROVIDER,
268
+ value: { from, name, identity, website, description },
269
+ };
270
+ }
271
+
272
+ /**
273
+ * Build MsgUpdateProviderStatusRequest.
274
+ * @param {{ from: string, status: number }} opts
275
+ * @returns {{ typeUrl: string, value: object }}
276
+ */
277
+ export function buildMsgUpdateProviderStatus({ from, status }) {
278
+ return {
279
+ typeUrl: TYPE_URLS.UPDATE_PROVIDER_STATUS,
280
+ value: { from, status },
281
+ };
282
+ }
283
+
284
+ // ─── Lease Message Builders ────────────────────────────────────────────────
285
+
286
+ /**
287
+ * Build MsgStartLeaseRequest.
288
+ * @param {{ from: string, nodeAddress: string, hours: number, maxPrice: object, renewalPricePolicy?: number }} opts
289
+ * @returns {{ typeUrl: string, value: object }}
290
+ */
291
+ export function buildMsgStartLease({ from, nodeAddress, hours, maxPrice, renewalPricePolicy = 0 }) {
292
+ return {
293
+ typeUrl: TYPE_URLS.START_LEASE,
294
+ value: { from, node_address: nodeAddress, hours, max_price: maxPrice, renewal_price_policy: renewalPricePolicy },
295
+ };
296
+ }
297
+
298
+ /**
299
+ * Build MsgEndLeaseRequest.
300
+ * @param {{ from: string, id: number|bigint }} opts
301
+ * @returns {{ typeUrl: string, value: object }}
302
+ */
303
+ export function buildMsgEndLease({ from, id }) {
304
+ return {
305
+ typeUrl: TYPE_URLS.END_LEASE,
306
+ value: { from, id: Number(id) },
307
+ };
308
+ }
309
+
310
+ // ─── Node Operator Message Builders ────────────────────────────────────────
311
+
312
+ /**
313
+ * Build MsgRegisterNodeRequest.
314
+ * @param {{ from: string, gigabytePrices?: Array, hourlyPrices?: Array, remoteAddrs?: string[] }} opts
315
+ * @returns {{ typeUrl: string, value: object }}
316
+ */
317
+ export function buildMsgRegisterNode({ from, gigabytePrices = [], hourlyPrices = [], remoteAddrs = [] }) {
318
+ return {
319
+ typeUrl: TYPE_URLS.REGISTER_NODE,
320
+ value: { from, gigabyte_prices: gigabytePrices, hourly_prices: hourlyPrices, remote_addrs: remoteAddrs },
321
+ };
322
+ }
323
+
324
+ /**
325
+ * Build MsgUpdateNodeDetailsRequest.
326
+ * @param {{ from: string, gigabytePrices?: Array, hourlyPrices?: Array, remoteAddrs?: string[] }} opts
327
+ * @returns {{ typeUrl: string, value: object }}
328
+ */
329
+ export function buildMsgUpdateNodeDetails({ from, gigabytePrices = [], hourlyPrices = [], remoteAddrs = [] }) {
330
+ return {
331
+ typeUrl: TYPE_URLS.UPDATE_NODE_DETAILS,
332
+ value: { from, gigabyte_prices: gigabytePrices, hourly_prices: hourlyPrices, remote_addrs: remoteAddrs },
333
+ };
334
+ }
335
+
336
+ /**
337
+ * Build MsgUpdateNodeStatusRequest.
338
+ * @param {{ from: string, status: number }} opts
339
+ * @returns {{ typeUrl: string, value: object }}
340
+ */
341
+ export function buildMsgUpdateNodeStatus({ from, status }) {
342
+ return {
343
+ typeUrl: TYPE_URLS.UPDATE_NODE_STATUS,
344
+ value: { from, status },
345
+ };
346
+ }
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Plan, Provider & Lease Operations for Sentinel dVPN
3
+ *
4
+ * Contains all encoder functions for plan management, provider registration,
5
+ * and node leasing. These are the 10 message types NOT in v3protocol.js.
6
+ *
7
+ * v3protocol.js handles: direct session, subscription, sub-session (3 types)
8
+ * This file handles: provider (3), plan (4), lease (2), plan-session (1) = 10 types
9
+ */
10
+
11
+ // ─── Protobuf Encoding Primitives ────────────────────────────────────────────
12
+ // Shared with v3.js — single source of truth for protobuf encoding.
13
+ import { encodeVarint, protoString, protoInt64, protoEmbedded, decToScaledInt, encodePrice } from './v3.js';
14
+
15
+ // protoUint64 is identical to protoInt64 — both use varint wire type 0
16
+ function protoUint64(fieldNum, n) {
17
+ return protoInt64(fieldNum, n);
18
+ }
19
+
20
+ function protoBool(fieldNum, val) {
21
+ if (!val) return Buffer.alloc(0); // false = omit (protobuf default)
22
+ return Buffer.concat([encodeVarint((BigInt(fieldNum) << 3n) | 0n), encodeVarint(1)]);
23
+ }
24
+
25
+ // decToScaledInt and encodePrice imported from v3.js (single source of truth)
26
+
27
+ /**
28
+ * Encode google.protobuf.Duration { seconds, nanos }
29
+ * Used by MsgCreatePlanRequest for plan duration.
30
+ */
31
+ function encodeDuration({ seconds, nanos = 0 }) {
32
+ return Buffer.concat([
33
+ protoInt64(1, seconds),
34
+ nanos ? protoInt64(2, nanos) : Buffer.alloc(0),
35
+ ]);
36
+ }
37
+
38
+ // ─── Provider Messages ───────────────────────────────────────────────────────
39
+
40
+ /**
41
+ * MsgRegisterProviderRequest (sentinel.provider.v3)
42
+ * Register a new provider. One wallet = one provider.
43
+ * from: sent prefix (account address)
44
+ */
45
+ export function encodeMsgRegisterProvider({ from, name, identity, website, description }) {
46
+ return Uint8Array.from(Buffer.concat([
47
+ protoString(1, from),
48
+ protoString(2, name),
49
+ protoString(3, identity || ''),
50
+ protoString(4, website || ''),
51
+ protoString(5, description || ''),
52
+ ]));
53
+ }
54
+
55
+ /**
56
+ * MsgUpdateProviderDetailsRequest (sentinel.provider.v3)
57
+ * Update existing provider info.
58
+ * from: sentprov prefix (provider address)
59
+ */
60
+ export function encodeMsgUpdateProviderDetails({ from, name, identity, website, description }) {
61
+ return Uint8Array.from(Buffer.concat([
62
+ protoString(1, from),
63
+ protoString(2, name || ''),
64
+ protoString(3, identity || ''),
65
+ protoString(4, website || ''),
66
+ protoString(5, description || ''),
67
+ ]));
68
+ }
69
+
70
+ /**
71
+ * MsgUpdateProviderStatusRequest (sentinel.provider.v3)
72
+ * Activate/deactivate provider. Status: 1=active, 2=inactive_pending, 3=inactive
73
+ * from: sent prefix (account address)
74
+ */
75
+ export function encodeMsgUpdateProviderStatus({ from, status }) {
76
+ return Uint8Array.from(Buffer.concat([
77
+ protoString(1, from),
78
+ protoInt64(2, status),
79
+ ]));
80
+ }
81
+
82
+ // ─── Plan Messages ───────────────────────────────────────────────────────────
83
+
84
+ /**
85
+ * MsgCreatePlanRequest (sentinel.plan.v3)
86
+ * Create a new subscription plan.
87
+ * from: sentprov prefix (provider address)
88
+ * bytes: total bandwidth as string (e.g. "10000000000" for 10GB)
89
+ * duration: { seconds: N } — plan validity period
90
+ * prices: [{ denom, base_value, quote_value }] — subscription cost
91
+ * isPrivate: boolean
92
+ *
93
+ * NOTE: Plans start INACTIVE by default — must send MsgUpdatePlanStatusRequest separately!
94
+ */
95
+ export function encodeMsgCreatePlan({ from, bytes, duration, prices, isPrivate }) {
96
+ const parts = [protoString(1, from)];
97
+ if (bytes) parts.push(protoString(2, String(bytes)));
98
+ if (duration) parts.push(protoEmbedded(3, encodeDuration(
99
+ typeof duration === 'number' ? { seconds: duration } : duration
100
+ )));
101
+ for (const p of (prices || [])) {
102
+ parts.push(protoEmbedded(4, encodePrice(p)));
103
+ }
104
+ if (isPrivate) parts.push(protoBool(5, true));
105
+ return Uint8Array.from(Buffer.concat(parts));
106
+ }
107
+
108
+ /**
109
+ * MsgUpdatePlanStatusRequest (sentinel.plan.v3)
110
+ * Activate/deactivate a plan. Status: 1=active, 2=inactive_pending, 3=inactive
111
+ * from: sentprov prefix (provider address)
112
+ */
113
+ export function encodeMsgUpdatePlanStatus({ from, id, status }) {
114
+ return Uint8Array.from(Buffer.concat([
115
+ protoString(1, from),
116
+ protoUint64(2, id),
117
+ protoInt64(3, status),
118
+ ]));
119
+ }
120
+
121
+ /**
122
+ * MsgLinkNodeRequest (sentinel.plan.v3)
123
+ * Link a leased node to a plan. Requires active lease for the node.
124
+ * from: sentprov prefix (provider address)
125
+ */
126
+ export function encodeMsgLinkNode({ from, id, nodeAddress }) {
127
+ return Uint8Array.from(Buffer.concat([
128
+ protoString(1, from),
129
+ protoUint64(2, id),
130
+ protoString(3, nodeAddress),
131
+ ]));
132
+ }
133
+
134
+ /**
135
+ * MsgUnlinkNodeRequest (sentinel.plan.v3)
136
+ * Remove a node from a plan.
137
+ * from: sentprov prefix (provider address)
138
+ */
139
+ export function encodeMsgUnlinkNode({ from, id, nodeAddress }) {
140
+ return Uint8Array.from(Buffer.concat([
141
+ protoString(1, from),
142
+ protoUint64(2, id),
143
+ protoString(3, nodeAddress),
144
+ ]));
145
+ }
146
+
147
+ /**
148
+ * MsgStartSessionRequest (sentinel.plan.v3) — COMBINED subscribe + session
149
+ * Subscribes to a plan AND starts a session in one TX.
150
+ * from: sent prefix (account address)
151
+ */
152
+ export function encodeMsgPlanStartSession({ from, id, denom = 'udvpn', renewalPricePolicy = 0, nodeAddress }) {
153
+ const parts = [
154
+ protoString(1, from),
155
+ protoUint64(2, id),
156
+ protoString(3, denom),
157
+ ];
158
+ if (renewalPricePolicy) parts.push(protoInt64(4, renewalPricePolicy));
159
+ if (nodeAddress) parts.push(protoString(5, nodeAddress));
160
+ return Uint8Array.from(Buffer.concat(parts));
161
+ }
162
+
163
+ // ─── Lease Messages ──────────────────────────────────────────────────────────
164
+
165
+ /**
166
+ * MsgStartLeaseRequest (sentinel.lease.v1)
167
+ * Lease a node from its operator. Provider pays node's hourly price.
168
+ * from: sentprov prefix (provider address)
169
+ *
170
+ * CRITICAL: maxPrice must EXACTLY match the node's hourly_prices from LCD.
171
+ * Any mismatch → "invalid price" error.
172
+ */
173
+ export function encodeMsgStartLease({ from, nodeAddress, hours, maxPrice, renewalPricePolicy = 0 }) {
174
+ const parts = [
175
+ protoString(1, from),
176
+ protoString(2, nodeAddress),
177
+ protoInt64(3, hours),
178
+ ];
179
+ if (maxPrice) parts.push(protoEmbedded(4, encodePrice(maxPrice)));
180
+ if (renewalPricePolicy) parts.push(protoInt64(5, renewalPricePolicy));
181
+ return Uint8Array.from(Buffer.concat(parts));
182
+ }
183
+
184
+ /**
185
+ * MsgEndLeaseRequest (sentinel.lease.v1)
186
+ * End an active lease.
187
+ * from: sentprov prefix (provider address)
188
+ */
189
+ export function encodeMsgEndLease({ from, id }) {
190
+ return Uint8Array.from(Buffer.concat([
191
+ protoString(1, from),
192
+ protoUint64(2, id),
193
+ ]));
194
+ }
195
+
196
+ // ─── Exported Helpers ────────────────────────────────────────────────────────
197
+
198
+ export { encodePrice, encodeDuration, decToScaledInt };
199
+ export { encodeVarint, protoString, protoInt64, protoUint64, protoBool, protoEmbedded };