@lightconexyz/lightcone-sdk 0.6.1 → 0.8.1-rc.2

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 (222) hide show
  1. package/README.md +26 -2
  2. package/dist/auth/client.d.ts +3 -3
  3. package/dist/auth/client.d.ts.map +1 -1
  4. package/dist/auth/client.js +19 -36
  5. package/dist/auth/client.js.map +1 -1
  6. package/dist/auth/index.d.ts +102 -46
  7. package/dist/auth/index.d.ts.map +1 -1
  8. package/dist/auth/index.js +91 -7
  9. package/dist/auth/index.js.map +1 -1
  10. package/dist/client.d.ts +17 -9
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +36 -17
  13. package/dist/client.js.map +1 -1
  14. package/dist/context.d.ts +7 -1
  15. package/dist/context.d.ts.map +1 -1
  16. package/dist/context.js +60 -6
  17. package/dist/context.js.map +1 -1
  18. package/dist/domain/index.d.ts +0 -1
  19. package/dist/domain/index.d.ts.map +1 -1
  20. package/dist/domain/index.js +1 -2
  21. package/dist/domain/index.js.map +1 -1
  22. package/dist/domain/market/client.js +1 -1
  23. package/dist/domain/market/client.js.map +1 -1
  24. package/dist/domain/market/convert.js +1 -1
  25. package/dist/domain/market/convert.js.map +1 -1
  26. package/dist/domain/market/index.d.ts +8 -1
  27. package/dist/domain/market/index.d.ts.map +1 -1
  28. package/dist/domain/market/index.js +12 -0
  29. package/dist/domain/market/index.js.map +1 -1
  30. package/dist/domain/market/outcome.d.ts +1 -0
  31. package/dist/domain/market/outcome.d.ts.map +1 -1
  32. package/dist/domain/market/outcome.js +1 -0
  33. package/dist/domain/market/outcome.js.map +1 -1
  34. package/dist/domain/market/tokens.d.ts +4 -0
  35. package/dist/domain/market/tokens.d.ts.map +1 -1
  36. package/dist/domain/market/tokens.js +14 -1
  37. package/dist/domain/market/tokens.js.map +1 -1
  38. package/dist/domain/market/wire.d.ts +24 -2
  39. package/dist/domain/market/wire.d.ts.map +1 -1
  40. package/dist/domain/market/wire.js +5 -0
  41. package/dist/domain/market/wire.js.map +1 -1
  42. package/dist/domain/metrics/client.d.ts +11 -5
  43. package/dist/domain/metrics/client.d.ts.map +1 -1
  44. package/dist/domain/metrics/client.js +52 -5
  45. package/dist/domain/metrics/client.js.map +1 -1
  46. package/dist/domain/metrics/wire.d.ts +112 -5
  47. package/dist/domain/metrics/wire.d.ts.map +1 -1
  48. package/dist/domain/metrics/wire.js.map +1 -1
  49. package/dist/domain/notification/client.d.ts +2 -2
  50. package/dist/domain/notification/client.d.ts.map +1 -1
  51. package/dist/domain/notification/client.js +3 -3
  52. package/dist/domain/notification/client.js.map +1 -1
  53. package/dist/domain/notification/index.d.ts +3 -1
  54. package/dist/domain/notification/index.d.ts.map +1 -1
  55. package/dist/domain/notification/index.js.map +1 -1
  56. package/dist/domain/order/client.d.ts +14 -10
  57. package/dist/domain/order/client.d.ts.map +1 -1
  58. package/dist/domain/order/client.js +20 -13
  59. package/dist/domain/order/client.js.map +1 -1
  60. package/dist/domain/order/convert.d.ts +1 -1
  61. package/dist/domain/order/convert.d.ts.map +1 -1
  62. package/dist/domain/order/convert.js +2 -2
  63. package/dist/domain/order/convert.js.map +1 -1
  64. package/dist/domain/order/index.d.ts +2 -1
  65. package/dist/domain/order/index.d.ts.map +1 -1
  66. package/dist/domain/order/index.js +11 -3
  67. package/dist/domain/order/index.js.map +1 -1
  68. package/dist/domain/orderbook/aggregation.d.ts +50 -0
  69. package/dist/domain/orderbook/aggregation.d.ts.map +1 -0
  70. package/dist/domain/orderbook/aggregation.js +85 -0
  71. package/dist/domain/orderbook/aggregation.js.map +1 -0
  72. package/dist/domain/orderbook/client.d.ts +17 -3
  73. package/dist/domain/orderbook/client.d.ts.map +1 -1
  74. package/dist/domain/orderbook/client.js +41 -3
  75. package/dist/domain/orderbook/client.js.map +1 -1
  76. package/dist/domain/orderbook/index.d.ts +1 -0
  77. package/dist/domain/orderbook/index.d.ts.map +1 -1
  78. package/dist/domain/orderbook/index.js +1 -0
  79. package/dist/domain/orderbook/index.js.map +1 -1
  80. package/dist/domain/orderbook/state.d.ts +29 -31
  81. package/dist/domain/orderbook/state.d.ts.map +1 -1
  82. package/dist/domain/orderbook/state.js +20 -67
  83. package/dist/domain/orderbook/state.js.map +1 -1
  84. package/dist/domain/orderbook/wire.d.ts +32 -0
  85. package/dist/domain/orderbook/wire.d.ts.map +1 -1
  86. package/dist/domain/orderbook/wire.js.map +1 -1
  87. package/dist/domain/position/builders.d.ts +11 -8
  88. package/dist/domain/position/builders.d.ts.map +1 -1
  89. package/dist/domain/position/builders.js +31 -25
  90. package/dist/domain/position/builders.js.map +1 -1
  91. package/dist/domain/position/client.d.ts +21 -15
  92. package/dist/domain/position/client.d.ts.map +1 -1
  93. package/dist/domain/position/client.js +43 -22
  94. package/dist/domain/position/client.js.map +1 -1
  95. package/dist/domain/referral/client.d.ts +2 -2
  96. package/dist/domain/referral/client.d.ts.map +1 -1
  97. package/dist/domain/referral/client.js +3 -3
  98. package/dist/domain/referral/client.js.map +1 -1
  99. package/dist/domain/trade/client.d.ts +1 -0
  100. package/dist/domain/trade/client.d.ts.map +1 -1
  101. package/dist/domain/trade/client.js +14 -0
  102. package/dist/domain/trade/client.js.map +1 -1
  103. package/dist/domain/trade/wire.d.ts +6 -0
  104. package/dist/domain/trade/wire.d.ts.map +1 -1
  105. package/dist/domain/trade/wire.js.map +1 -1
  106. package/dist/env.d.ts +24 -4
  107. package/dist/env.d.ts.map +1 -1
  108. package/dist/env.js +47 -13
  109. package/dist/env.js.map +1 -1
  110. package/dist/http/client.d.ts +8 -11
  111. package/dist/http/client.d.ts.map +1 -1
  112. package/dist/http/client.js +71 -34
  113. package/dist/http/client.js.map +1 -1
  114. package/dist/index.d.ts +3 -2
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +8 -1
  117. package/dist/index.js.map +1 -1
  118. package/dist/prelude.d.ts +15 -13
  119. package/dist/prelude.d.ts.map +1 -1
  120. package/dist/prelude.js +26 -9
  121. package/dist/prelude.js.map +1 -1
  122. package/dist/privy/index.d.ts +1 -1
  123. package/dist/privy/index.js.map +1 -1
  124. package/dist/program/accounts.d.ts +12 -7
  125. package/dist/program/accounts.d.ts.map +1 -1
  126. package/dist/program/accounts.js +38 -16
  127. package/dist/program/accounts.js.map +1 -1
  128. package/dist/program/builder.d.ts +0 -4
  129. package/dist/program/builder.d.ts.map +1 -1
  130. package/dist/program/builder.js +0 -8
  131. package/dist/program/builder.js.map +1 -1
  132. package/dist/program/constants.d.ts +20 -7
  133. package/dist/program/constants.d.ts.map +1 -1
  134. package/dist/program/constants.js +21 -8
  135. package/dist/program/constants.js.map +1 -1
  136. package/dist/program/error.d.ts +25 -1
  137. package/dist/program/error.d.ts.map +1 -1
  138. package/dist/program/error.js +72 -0
  139. package/dist/program/error.js.map +1 -1
  140. package/dist/program/index.d.ts +7 -7
  141. package/dist/program/index.d.ts.map +1 -1
  142. package/dist/program/index.js +36 -9
  143. package/dist/program/index.js.map +1 -1
  144. package/dist/program/instructions.d.ts +184 -71
  145. package/dist/program/instructions.d.ts.map +1 -1
  146. package/dist/program/instructions.js +573 -140
  147. package/dist/program/instructions.js.map +1 -1
  148. package/dist/program/orders.js +2 -2
  149. package/dist/program/orders.js.map +1 -1
  150. package/dist/program/pda.d.ts +21 -3
  151. package/dist/program/pda.d.ts.map +1 -1
  152. package/dist/program/pda.js +43 -6
  153. package/dist/program/pda.js.map +1 -1
  154. package/dist/program/types.d.ts +139 -21
  155. package/dist/program/types.d.ts.map +1 -1
  156. package/dist/program/types.js.map +1 -1
  157. package/dist/program/utils.d.ts +31 -2
  158. package/dist/program/utils.d.ts.map +1 -1
  159. package/dist/program/utils.js +132 -5
  160. package/dist/program/utils.js.map +1 -1
  161. package/dist/rpc.d.ts +6 -1
  162. package/dist/rpc.d.ts.map +1 -1
  163. package/dist/rpc.js +9 -7
  164. package/dist/rpc.js.map +1 -1
  165. package/dist/rpcFailover.d.ts +22 -0
  166. package/dist/rpcFailover.d.ts.map +1 -0
  167. package/dist/rpcFailover.js +71 -0
  168. package/dist/rpcFailover.js.map +1 -0
  169. package/dist/shared/fmt/constants.d.ts +5 -0
  170. package/dist/shared/fmt/constants.d.ts.map +1 -0
  171. package/dist/shared/fmt/constants.js +25 -0
  172. package/dist/shared/fmt/constants.js.map +1 -0
  173. package/dist/shared/fmt/decimal.d.ts +7 -0
  174. package/dist/shared/fmt/decimal.d.ts.map +1 -1
  175. package/dist/shared/fmt/decimal.js +28 -20
  176. package/dist/shared/fmt/decimal.js.map +1 -1
  177. package/dist/shared/fmt/index.d.ts +1 -0
  178. package/dist/shared/fmt/index.d.ts.map +1 -1
  179. package/dist/shared/fmt/index.js +2 -1
  180. package/dist/shared/fmt/index.js.map +1 -1
  181. package/dist/shared/fmt/num.d.ts +7 -0
  182. package/dist/shared/fmt/num.d.ts.map +1 -1
  183. package/dist/shared/fmt/num.js +27 -15
  184. package/dist/shared/fmt/num.js.map +1 -1
  185. package/dist/shared/fmt/str.d.ts +8 -0
  186. package/dist/shared/fmt/str.d.ts.map +1 -0
  187. package/dist/shared/fmt/str.js +17 -0
  188. package/dist/shared/fmt/str.js.map +1 -0
  189. package/dist/shared/index.d.ts +1 -1
  190. package/dist/shared/index.d.ts.map +1 -1
  191. package/dist/shared/index.js +11 -1
  192. package/dist/shared/index.js.map +1 -1
  193. package/dist/shared/rejection.d.ts.map +1 -1
  194. package/dist/shared/rejection.js +11 -0
  195. package/dist/shared/rejection.js.map +1 -1
  196. package/dist/shared/types.d.ts +41 -0
  197. package/dist/shared/types.d.ts.map +1 -1
  198. package/dist/shared/types.js +85 -1
  199. package/dist/shared/types.js.map +1 -1
  200. package/dist/ws/client.node.js +1 -1
  201. package/dist/ws/client.node.js.map +1 -1
  202. package/dist/ws/index.d.ts +25 -2
  203. package/dist/ws/index.d.ts.map +1 -1
  204. package/dist/ws/index.js +23 -2
  205. package/dist/ws/index.js.map +1 -1
  206. package/dist/ws/subscriptions.d.ts +12 -0
  207. package/dist/ws/subscriptions.d.ts.map +1 -1
  208. package/dist/ws/subscriptions.js +14 -4
  209. package/dist/ws/subscriptions.js.map +1 -1
  210. package/package.json +1 -1
  211. package/dist/domain/admin/client.d.ts +0 -53
  212. package/dist/domain/admin/client.d.ts.map +0 -1
  213. package/dist/domain/admin/client.js +0 -199
  214. package/dist/domain/admin/client.js.map +0 -1
  215. package/dist/domain/admin/index.d.ts +0 -16
  216. package/dist/domain/admin/index.d.ts.map +0 -1
  217. package/dist/domain/admin/index.js +0 -19
  218. package/dist/domain/admin/index.js.map +0 -1
  219. package/dist/domain/admin/wire.d.ts +0 -425
  220. package/dist/domain/admin/wire.d.ts.map +0 -1
  221. package/dist/domain/admin/wire.js +0 -3
  222. package/dist/domain/admin/wire.js.map +0 -1
package/README.md CHANGED
@@ -177,6 +177,12 @@ ws.subscribe({
177
177
  });
178
178
  ```
179
179
 
180
+ Book streams are snapshot-only: every `book_update` frame carries the full top-20 levels per side (~50ms conflation) and replaces the previous book wholesale (`OrderbookState` handles this; never gate on `seq` — the initial snapshot after every (re)subscribe is `seq: 0`). Subscriptions accept an optional Hyperliquid-style aggregation (`nSigFigs` 2–5, `mantissa` 1/2/5 only with `nSigFigs: 5`; validate with `validateAggregation`). Each `(orderbook, aggregation)` pair is a distinct subscription, so one connection can hold the full-precision and a grouped view of the same book simultaneously — incoming frames are tagged with snake_case `n_sig_figs`/`mantissa` (absent = full precision); key state by `aggregationFromFrame(frame.n_sig_figs, frame.mantissa)`. See [`examples/ws_book_and_trades.ts`](examples/ws_book_and_trades.ts).
181
+
182
+ ```typescript
183
+ ws.subscribe({ type: "book_update", orderbook_ids: [orderbook.orderbookId], nSigFigs: 5, mantissa: 2 });
184
+ ```
185
+
180
186
  ### Step 5: Cancel an Order
181
187
 
182
188
  ```typescript
@@ -218,7 +224,7 @@ Authentication is only required for user-specific endpoints. Authentication is s
218
224
 
219
225
  ### Cookie handling
220
226
 
221
- After login succeeds, the SDK stores the session token internally and attaches it as `Cookie: auth_token=…` on every authenticated request. Behaviour depends on the runtime:
227
+ After login succeeds, the SDK stores the session token internally and attaches it as `Cookie: lightcone-token=…` on every authenticated request. Behaviour depends on the runtime:
222
228
 
223
229
  - **Node / non-browser**: token is stored on the `LightconeHttp` instance and added as a `Cookie` header per request.
224
230
  - **Browser**: requests use `credentials: "include"` and the runtime supplies the cookie automatically — the SDK's internal store is unused.
@@ -271,6 +277,8 @@ const localClient = LightconeClient.builder()
271
277
 
272
278
  Each environment configures the API URL, WebSocket URL, Solana RPC URL, and on-chain program ID automatically. Individual URL overrides (`.baseUrl()`, `.wsUrl()`, `.rpcUrl()`) take precedence when called after `.env()`.
273
279
 
280
+ The Solana RPC URL can also be overridden via the `SDK_RPC_URL` environment variable, which takes precedence over the environment default. This is useful for pointing all examples at a private RPC to avoid public devnet rate limits.
281
+
274
282
  ## Examples
275
283
 
276
284
  All examples are runnable with `npx tsx examples/<name>.ts`. Examples default to the production environment and read the wallet keypair from `~/.config/solana/id.json`.
@@ -288,9 +296,10 @@ All examples are runnable with `npx tsx examples/<name>.ts`. Examples default to
288
296
  |---------|-------------|
289
297
  | [`markets`](examples/markets.ts) | Featured markets, paginated listing, fetch by pubkey, search, platform deposit assets via `globalDepositAssets()` |
290
298
  | [`orderbook`](examples/orderbook.ts) | Fetch orderbook depth (bids/asks) and decimal precision metadata |
291
- | [`trades`](examples/trades.ts) | Recent trade history with cursor-based pagination |
299
+ | [`trades`](examples/trades.ts) | Recent trade history with cursor-based pagination (per-orderbook and market-wide) |
292
300
  | [`price_history`](examples/price_history.ts) | Historical candlestick data (OHLCV) at various resolutions |
293
301
  | [`positions`](examples/positions.ts) | User positions across all markets and per-market |
302
+ | [`metrics_all`](examples/metrics_all.ts) | Exercise every endpoint on `client.metrics()` - platform, markets, categories, orderbook, leaderboard, history |
294
303
 
295
304
  ### Placing Orders
296
305
 
@@ -371,6 +380,17 @@ Machine-readable rejection codes expose a human-readable `.label()` method. Unre
371
380
  | `NOT_ORDER_MAKER` | "Not Order Maker" | Caller is not the order maker |
372
381
  | `ORDER_ALREADY_FILLED` | "Order Already Filled" | Order has already been fully filled |
373
382
  | `ORDER_ALREADY_CANCELLED` | "Order Already Cancelled" | Order was already cancelled |
383
+ | `DUPLICATE_ORDER` | "Duplicate Order" | Order already exists on this orderbook |
384
+ | `POST_ONLY_WOULD_CROSS` | "Post Only Would Cross" | Post-only order would cross resting liquidity |
385
+ | `FOK_NO_FILL` | "FOK No Fill" | Fill-or-kill order could not be fully filled |
386
+ | `IOC_NO_FILL` | "IOC No Fill" | Immediate-or-cancel order got no fill |
387
+ | `WOULD_CROSS_UNAVAILABLE_LIQUIDITY` | "Would Cross Unavailable Liquidity" | Would cross liquidity unavailable for matching |
388
+ | `WOULD_CROSS_BOOK` | "Would Cross Book" | Order remainder would leave orderbook crossed |
389
+ | `MARKET_NOT_FOUND` | "Market Not Found" | Market does not exist |
390
+ | `ORDERBOOK_NOT_FOUND` | "Orderbook Not Found" | Orderbook does not exist |
391
+ | `TOKEN_PAIR_MISMATCH` | "Token Pair Mismatch" | Token pair doesn't match orderbook |
392
+ | `INSUFFICIENT_MARKET_FEE_BUFFER` | "Insufficient Market Fee Buffer" | Not enough market fee buffer |
393
+ | `SIGNATURE_EXPIRED` | "Signature Expired" | Order signature has expired |
374
394
 
375
395
  ```typescript
376
396
  import { SdkError } from "@lightconexyz/lightcone-sdk";
@@ -417,3 +437,7 @@ The SDK generates a UUID v4 `x-request-id` header on every HTTP request. On reje
417
437
  - **GET requests**: `RetryPolicy.Idempotent` - retries on transport failures and 502/503/504, backs off on 429 with exponential backoff + jitter.
418
438
  - **POST requests** (order submit, cancel, auth): `RetryPolicy.None` - no automatic retry. Non-idempotent actions are never retried to prevent duplicate side effects.
419
439
  - Customizable per-call with `RetryPolicy.custom(config)`.
440
+
441
+ ## Trigger Orders
442
+
443
+ Trigger orders (stop-limit, take-profit-limit) are under development and not yet available. Internal types exist in the source for internal use only.
@@ -1,5 +1,5 @@
1
1
  import { type LightconeHttp } from "../http";
2
- import type { AuthCredentials, User } from "./index";
2
+ import type { AuthCredentials, SessionResponse } from "./index";
3
3
  interface AuthState {
4
4
  getCredentials(): AuthCredentials | undefined;
5
5
  setCredentials(credentials: AuthCredentials | undefined): void;
@@ -13,8 +13,8 @@ export declare class Auth {
13
13
  private readonly client;
14
14
  constructor(client: ClientContext);
15
15
  getNonce(): Promise<string>;
16
- loginWithMessage(message: string, signatureBs58: string, pubkeyBytes: Uint8Array, useEmbeddedWallet?: boolean): Promise<User>;
17
- checkSession(): Promise<User>;
16
+ loginWithMessage(message: string, signatureBs58: string, pubkeyBytes: Uint8Array, useEmbeddedWallet?: boolean): Promise<SessionResponse>;
17
+ checkSession(): Promise<SessionResponse>;
18
18
  logout(): Promise<void>;
19
19
  disconnectX(): Promise<void>;
20
20
  connectXUrl(): string;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAE1D,OAAO,KAAK,EAAE,eAAe,EAA0D,IAAI,EAAE,MAAM,SAAS,CAAC;AAE7G,UAAU,SAAS;IACjB,cAAc,IAAI,eAAe,GAAG,SAAS,CAAC;IAC9C,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAC/D,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,qBAAa,IAAI;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAE5C,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAM3B,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,UAAU,EACvB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,IAAI,CAAC;IAmCV,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA8B7B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAavB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC,WAAW,IAAI,MAAM;IAIrB,WAAW,IAAI,eAAe,GAAG,SAAS;IAI1C,eAAe,IAAI,OAAO;CAO3B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,KAAK,EAAE,eAAe,EAA+B,eAAe,EAAE,MAAM,SAAS,CAAC;AAE7F,UAAU,SAAS;IACjB,cAAc,IAAI,eAAe,GAAG,SAAS,CAAC;IAC9C,cAAc,CAAC,WAAW,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAC/D,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,qBAAa,IAAI;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAE5C,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAM3B,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,UAAU,EACvB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,OAAO,CAAC,eAAe,CAAC;IAoBrB,YAAY,IAAI,OAAO,CAAC,eAAe,CAAC;IAgBxC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAavB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC,WAAW,IAAI,MAAM;IAIrB,WAAW,IAAI,eAAe,GAAG,SAAS;IAI1C,eAAe,IAAI,OAAO;CAO3B"}
@@ -4,6 +4,7 @@ exports.Auth = void 0;
4
4
  const error_1 = require("../error");
5
5
  const http_1 = require("../http");
6
6
  const shared_1 = require("../shared");
7
+ const index_1 = require("./index");
7
8
  class Auth {
8
9
  client;
9
10
  constructor(client) {
@@ -22,51 +23,22 @@ class Auth {
22
23
  pubkey_bytes: Array.from(pubkeyBytes),
23
24
  use_embedded_wallet: useEmbeddedWallet,
24
25
  };
25
- const response = await this.client.http.post(url, body, http_1.RetryPolicy.None);
26
- const credentials = {
27
- user_id: response.user_id,
28
- wallet_address: (0, shared_1.asPubkeyStr)(response.wallet_address),
29
- expires_at: parseExpiry(response.expires_at),
30
- };
31
- this.client.authState.setCredentials(credentials);
32
- return {
33
- id: response.user_id,
34
- wallet_address: response.wallet_address,
35
- linked_account: response.linked_account,
36
- privy_id: response.privy_id,
37
- embedded_wallet: response.embedded_wallet,
38
- x_username: response.x_username,
39
- x_user_id: response.x_user_id,
40
- x_display_name: response.x_display_name,
41
- google_email: response.google_email,
42
- };
26
+ const session = await this.client.http.post(url, body, http_1.RetryPolicy.None);
27
+ this.client.authState.setCredentials(credentialsFromSession(session));
28
+ return session;
43
29
  }
44
30
  async checkSession() {
45
31
  const url = `${this.client.http.baseUrl()}/api/auth/me`;
46
- let response;
32
+ let session;
47
33
  try {
48
- response = await this.client.http.get(url, http_1.RetryPolicy.Idempotent);
34
+ session = await this.client.http.get(url, http_1.RetryPolicy.Idempotent);
49
35
  }
50
36
  catch (error) {
51
37
  this.client.authState.setCredentials(undefined);
52
38
  throw error_1.SdkError.from(error);
53
39
  }
54
- this.client.authState.setCredentials({
55
- user_id: response.user_id,
56
- wallet_address: (0, shared_1.asPubkeyStr)(response.wallet_address),
57
- expires_at: parseExpiry(response.expires_at),
58
- });
59
- return {
60
- id: response.user_id,
61
- wallet_address: response.wallet_address,
62
- linked_account: response.linked_account,
63
- privy_id: response.privy_id,
64
- embedded_wallet: response.embedded_wallet,
65
- x_username: response.x_username,
66
- x_user_id: response.x_user_id,
67
- x_display_name: response.x_display_name,
68
- google_email: response.google_email,
69
- };
40
+ this.client.authState.setCredentials(credentialsFromSession(session));
41
+ return session;
70
42
  }
71
43
  async logout() {
72
44
  const url = `${this.client.http.baseUrl()}/api/auth/logout`;
@@ -99,6 +71,17 @@ class Auth {
99
71
  }
100
72
  }
101
73
  exports.Auth = Auth;
74
+ /**
75
+ * Derive session credentials from the envelope. The trading wallet comes from
76
+ * the identity + auth method.
77
+ */
78
+ function credentialsFromSession(session) {
79
+ return {
80
+ user_id: session.user.user_id,
81
+ wallet_address: (0, shared_1.asPubkeyStr)((0, index_1.tradingWallet)(session.user, session.auth_method)),
82
+ expires_at: parseExpiry(session.expires_at),
83
+ };
84
+ }
102
85
  function parseExpiry(timestamp) {
103
86
  if (timestamp > 1_000_000_000_000) {
104
87
  return new Date(timestamp);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":";;;AAAA,oCAAoC;AACpC,kCAA0D;AAC1D,sCAAwC;AAcxC,MAAa,IAAI;IACc;IAA7B,YAA6B,MAAqB;QAArB,WAAM,GAAN,MAAM,CAAe;IAAG,CAAC;IAEtD,KAAK,CAAC,QAAQ;QACZ,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC;QAC3D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAgB,GAAG,EAAE,kBAAW,CAAC,IAAI,CAAC,CAAC;QAClF,OAAO,QAAQ,CAAC,KAAK,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,OAAe,EACf,aAAqB,EACrB,WAAuB,EACvB,iBAA2B;QAE3B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,0CAA0C,CAAC;QACpF,MAAM,IAAI,GAAiB;YACzB,OAAO;YACP,cAAc,EAAE,aAAa;YAC7B,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;YACrC,mBAAmB,EAAE,iBAAiB;SACvC,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAC1C,GAAG,EACH,IAAI,EACJ,kBAAW,CAAC,IAAI,CACjB,CAAC;QAEF,MAAM,WAAW,GAAoB;YACnC,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,cAAc,EAAE,IAAA,oBAAW,EAAC,QAAQ,CAAC,cAAc,CAAC;YACpD,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;SAC7C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;QAElD,OAAO;YACL,EAAE,EAAE,QAAQ,CAAC,OAAO;YACpB,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,YAAY,EAAE,QAAQ,CAAC,YAAY;SACpC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;QAExD,IAAI,QAAoB,CAAC;QACzB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAa,GAAG,EAAE,kBAAW,CAAC,UAAU,CAAC,CAAC;QACjF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAChD,MAAM,gBAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC;YACnC,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,cAAc,EAAE,IAAA,oBAAW,EAAC,QAAQ,CAAC,cAAc,CAAC;YACpD,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;SAC7C,CAAC,CAAC;QAEH,OAAO;YACL,EAAE,EAAE,QAAQ,CAAC,OAAO;YACpB,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;YACzC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,YAAY,EAAE,QAAQ,CAAC,YAAY;SACpC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC;QAC5D,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAA8C,GAAG,EAAE,EAAE,EAAE,kBAAW,CAAC,IAAI,CAAC,CAAC;QACtG,CAAC;QAAC,MAAM,CAAC;YACP,8EAA8E;QAChF,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAChD,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,wBAAwB,CAAC;QAClE,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAA8C,GAAG,EAAE,EAAE,EAAE,kBAAW,CAAC,IAAI,CAAC,CAAC;IACtG,CAAC;IAED,WAAW;QACT,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,wBAAwB,CAAC;IAC/D,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;IAChD,CAAC;IAED,eAAe;QACb,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IACvD,CAAC;CACF;AAhHD,oBAgHC;AAED,SAAS,WAAW,CAAC,SAAiB;IACpC,IAAI,SAAS,GAAG,iBAAiB,EAAE,CAAC;QAClC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;AACpC,CAAC","sourcesContent":["import { SdkError } from \"../error\";\nimport { RetryPolicy, type LightconeHttp } from \"../http\";\nimport { asPubkeyStr } from \"../shared\";\nimport type { AuthCredentials, LoginRequest, LoginResponse, MeResponse, NonceResponse, User } from \"./index\";\n\ninterface AuthState {\n getCredentials(): AuthCredentials | undefined;\n setCredentials(credentials: AuthCredentials | undefined): void;\n clearCaches(): Promise<void>;\n}\n\ninterface ClientContext {\n http: LightconeHttp;\n authState: AuthState;\n}\n\nexport class Auth {\n constructor(private readonly client: ClientContext) {}\n\n async getNonce(): Promise<string> {\n const url = `${this.client.http.baseUrl()}/api/auth/nonce`;\n const response = await this.client.http.get<NonceResponse>(url, RetryPolicy.None);\n return response.nonce;\n }\n\n async loginWithMessage(\n message: string,\n signatureBs58: string,\n pubkeyBytes: Uint8Array,\n useEmbeddedWallet?: boolean\n ): Promise<User> {\n const url = `${this.client.http.baseUrl()}/api/auth/login_or_register_with_message`;\n const body: LoginRequest = {\n message,\n signature_bs58: signatureBs58,\n pubkey_bytes: Array.from(pubkeyBytes),\n use_embedded_wallet: useEmbeddedWallet,\n };\n\n const response = await this.client.http.post<LoginResponse, LoginRequest>(\n url,\n body,\n RetryPolicy.None\n );\n\n const credentials: AuthCredentials = {\n user_id: response.user_id,\n wallet_address: asPubkeyStr(response.wallet_address),\n expires_at: parseExpiry(response.expires_at),\n };\n this.client.authState.setCredentials(credentials);\n\n return {\n id: response.user_id,\n wallet_address: response.wallet_address,\n linked_account: response.linked_account,\n privy_id: response.privy_id,\n embedded_wallet: response.embedded_wallet,\n x_username: response.x_username,\n x_user_id: response.x_user_id,\n x_display_name: response.x_display_name,\n google_email: response.google_email,\n };\n }\n\n async checkSession(): Promise<User> {\n const url = `${this.client.http.baseUrl()}/api/auth/me`;\n\n let response: MeResponse;\n try {\n response = await this.client.http.get<MeResponse>(url, RetryPolicy.Idempotent);\n } catch (error) {\n this.client.authState.setCredentials(undefined);\n throw SdkError.from(error);\n }\n\n this.client.authState.setCredentials({\n user_id: response.user_id,\n wallet_address: asPubkeyStr(response.wallet_address),\n expires_at: parseExpiry(response.expires_at),\n });\n\n return {\n id: response.user_id,\n wallet_address: response.wallet_address,\n linked_account: response.linked_account,\n privy_id: response.privy_id,\n embedded_wallet: response.embedded_wallet,\n x_username: response.x_username,\n x_user_id: response.x_user_id,\n x_display_name: response.x_display_name,\n google_email: response.google_email,\n };\n }\n\n async logout(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/logout`;\n try {\n await this.client.http.post<{ success: boolean }, Record<string, never>>(url, {}, RetryPolicy.None);\n } catch {\n // Backend cookie clear can fail in local/dev setups; still clear local state.\n }\n\n await this.client.http.clearAuthToken();\n this.client.authState.setCredentials(undefined);\n await this.client.authState.clearCaches();\n }\n\n async disconnectX(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/disconnect_x`;\n await this.client.http.post<{ success: boolean }, Record<string, never>>(url, {}, RetryPolicy.None);\n }\n\n connectXUrl(): string {\n return `${this.client.http.baseUrl()}/api/auth/oauth/link/x`;\n }\n\n credentials(): AuthCredentials | undefined {\n return this.client.authState.getCredentials();\n }\n\n isAuthenticated(): boolean {\n const credentials = this.credentials();\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n }\n}\n\nfunction parseExpiry(timestamp: number): Date {\n if (timestamp > 1_000_000_000_000) {\n return new Date(timestamp);\n }\n return new Date(timestamp * 1000);\n}\n"]}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { SdkError } from \"../error\";\nimport { RetryPolicy, type LightconeHttp } from \"../http\";\nimport { asPubkeyStr } from \"../shared\";\nimport { tradingWallet } from \"./index\";\nimport type { AuthCredentials, LoginRequest, NonceResponse, SessionResponse } from \"./index\";\n\ninterface AuthState {\n getCredentials(): AuthCredentials | undefined;\n setCredentials(credentials: AuthCredentials | undefined): void;\n clearCaches(): Promise<void>;\n}\n\ninterface ClientContext {\n http: LightconeHttp;\n authState: AuthState;\n}\n\nexport class Auth {\n constructor(private readonly client: ClientContext) {}\n\n async getNonce(): Promise<string> {\n const url = `${this.client.http.baseUrl()}/api/auth/nonce`;\n const response = await this.client.http.get<NonceResponse>(url, RetryPolicy.None);\n return response.nonce;\n }\n\n async loginWithMessage(\n message: string,\n signatureBs58: string,\n pubkeyBytes: Uint8Array,\n useEmbeddedWallet?: boolean\n ): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/login_or_register_with_message`;\n const body: LoginRequest = {\n message,\n signature_bs58: signatureBs58,\n pubkey_bytes: Array.from(pubkeyBytes),\n use_embedded_wallet: useEmbeddedWallet,\n };\n\n const session = await this.client.http.post<SessionResponse, LoginRequest>(\n url,\n body,\n RetryPolicy.None\n );\n\n this.client.authState.setCredentials(credentialsFromSession(session));\n\n return session;\n }\n\n async checkSession(): Promise<SessionResponse> {\n const url = `${this.client.http.baseUrl()}/api/auth/me`;\n\n let session: SessionResponse;\n try {\n session = await this.client.http.get<SessionResponse>(url, RetryPolicy.Idempotent);\n } catch (error) {\n this.client.authState.setCredentials(undefined);\n throw SdkError.from(error);\n }\n\n this.client.authState.setCredentials(credentialsFromSession(session));\n\n return session;\n }\n\n async logout(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/logout`;\n try {\n await this.client.http.post<{ success: boolean }, Record<string, never>>(url, {}, RetryPolicy.None);\n } catch {\n // Backend cookie clear can fail in local/dev setups; still clear local state.\n }\n\n await this.client.http.clearAuthToken();\n this.client.authState.setCredentials(undefined);\n await this.client.authState.clearCaches();\n }\n\n async disconnectX(): Promise<void> {\n const url = `${this.client.http.baseUrl()}/api/auth/disconnect_x`;\n await this.client.http.post<{ success: boolean }, Record<string, never>>(url, {}, RetryPolicy.None);\n }\n\n connectXUrl(): string {\n return `${this.client.http.baseUrl()}/api/auth/oauth/link/x`;\n }\n\n credentials(): AuthCredentials | undefined {\n return this.client.authState.getCredentials();\n }\n\n isAuthenticated(): boolean {\n const credentials = this.credentials();\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n }\n}\n\n/**\n * Derive session credentials from the envelope. The trading wallet comes from\n * the identity + auth method.\n */\nfunction credentialsFromSession(session: SessionResponse): AuthCredentials {\n return {\n user_id: session.user.user_id,\n wallet_address: asPubkeyStr(tradingWallet(session.user, session.auth_method)),\n expires_at: parseExpiry(session.expires_at),\n };\n}\n\nfunction parseExpiry(timestamp: number): Date {\n if (timestamp > 1_000_000_000_000) {\n return new Date(timestamp);\n }\n return new Date(timestamp * 1000);\n}\n"]}
@@ -1,37 +1,117 @@
1
1
  import type { PubkeyStr } from "../shared";
2
2
  export * from "./client";
3
3
  export * from "./native";
4
- export interface User {
5
- id: string;
6
- wallet_address: string;
7
- linked_account: LinkedAccount;
8
- privy_id?: string;
9
- embedded_wallet?: EmbeddedWallet;
10
- x_username?: string;
11
- x_user_id?: string;
12
- x_display_name?: string;
13
- google_email?: string;
14
- }
15
- export interface LinkedAccount {
16
- id: string;
17
- type: LinkedAccountType;
18
- chain?: ChainType;
19
- address: string;
20
- }
21
- export declare enum LinkedAccountType {
22
- Wallet = "wallet",
23
- TwitterOauth = "twitter_oauth",
24
- GoogleOauth = "google_oauth"
4
+ /**
5
+ * How a session authenticated, as reported by the backend (derived from which
6
+ * token verified the request).
7
+ */
8
+ export declare enum AuthMethod {
9
+ Privy = "privy",
10
+ Lightcone = "lightcone"
25
11
  }
26
12
  export declare enum ChainType {
27
13
  Solana = "solana",
28
14
  Ethereum = "ethereum"
29
15
  }
30
- export interface EmbeddedWallet {
16
+ /** A Privy-managed embedded wallet. */
17
+ export interface PrivyEmbeddedWallet {
31
18
  privy_id: string;
32
19
  chain: ChainType;
33
20
  address: string;
34
21
  }
22
+ /** Privy account data attached to an identity. */
23
+ export interface UserPrivyData {
24
+ /** The Privy DID (`did:privy:...`). */
25
+ id: string;
26
+ /**
27
+ * Always present: Privy registration provisions the embedded wallet in the
28
+ * same transaction that creates the user.
29
+ */
30
+ wallet: PrivyEmbeddedWallet;
31
+ }
32
+ /**
33
+ * X account data — the same shape whether X is the login identity or a
34
+ * connected account on a Google/wallet identity.
35
+ */
36
+ export interface XAccountData {
37
+ /** X numeric user id (Privy `subject`); absent on legacy rows. */
38
+ user_id?: string;
39
+ username: string;
40
+ display_name?: string;
41
+ avatar_url?: string;
42
+ }
43
+ /** Google account data for a Google login identity. */
44
+ export interface GoogleAccountData {
45
+ email: string;
46
+ name?: string;
47
+ given_name?: string;
48
+ family_name?: string;
49
+ avatar_url?: string;
50
+ }
51
+ /**
52
+ * The login identity — how the user authenticates. `type` narrows the variant.
53
+ *
54
+ * Privy data lives on the variant because its presence is determined by the
55
+ * identity type: Google/X login only exists via Privy OAuth (guaranteed DID +
56
+ * embedded wallet), while wallet users opt into Privy (SIWS) or stay
57
+ * self-custody.
58
+ */
59
+ export type UserIdentity = {
60
+ type: "google";
61
+ account: GoogleAccountData;
62
+ privy: UserPrivyData;
63
+ } | {
64
+ type: "x";
65
+ account: XAccountData;
66
+ privy: UserPrivyData;
67
+ } | {
68
+ type: "wallet";
69
+ address: string;
70
+ chain: ChainType;
71
+ privy?: UserPrivyData;
72
+ };
73
+ /** Full user profile — the `user` object of {@link SessionResponse}. */
74
+ export interface User {
75
+ user_id: string;
76
+ identity: UserIdentity;
77
+ /** X account connected by a non-X-identity user; absent when identity is X. */
78
+ connected_x?: XAccountData;
79
+ }
80
+ /**
81
+ * Session envelope returned by `loginWithMessage`, `register-privy`, and
82
+ * `GET /api/auth/me`. There is no `wallet_address` field — derive the
83
+ * session's trading wallet with {@link tradingWallet}.
84
+ */
85
+ export interface SessionResponse {
86
+ user: User;
87
+ expires_at: number;
88
+ auth_method: AuthMethod;
89
+ is_beta: boolean;
90
+ }
91
+ /** Human-readable login-method label ("Google" / "X" / "Solana"). */
92
+ export declare function identityText(identity: UserIdentity): "Google" | "X" | "Solana";
93
+ /** Privy account data, regardless of identity type. */
94
+ export declare function userPrivy(user: User): UserPrivyData | undefined;
95
+ /** The X account, whether it is the login identity or a connected account. */
96
+ export declare function userXAccount(user: User): XAccountData | undefined;
97
+ /**
98
+ * The wallet a session operates as.
99
+ *
100
+ * Google/X identities only exist via Privy registration, which always
101
+ * provisions an embedded wallet — that wallet is the answer regardless of
102
+ * auth method. Wallet identities depend on the session: a Privy (SIWS)
103
+ * session trades via the embedded wallet, a Lightcone session trades via the
104
+ * wallet that signed in.
105
+ */
106
+ export declare function tradingWallet(user: User, authMethod: AuthMethod): string;
107
+ /**
108
+ * Best display name for the user. Google: `name`, falling back to the email;
109
+ * X: `display_name`, falling back to the username; wallet identities show the
110
+ * shortened address (`FRGk...WcPR`).
111
+ */
112
+ export declare function displayName(user: User): string;
113
+ /** Avatar URL from the login identity's OAuth provider, if any. */
114
+ export declare function avatarUrl(user: User): string | undefined;
35
115
  export interface AuthCredentials {
36
116
  user_id: string;
37
117
  wallet_address: PubkeyStr;
@@ -45,30 +125,6 @@ export interface LoginRequest {
45
125
  pubkey_bytes: number[];
46
126
  use_embedded_wallet?: boolean;
47
127
  }
48
- export interface LoginResponse {
49
- user_id: string;
50
- wallet_address: string;
51
- expires_at: number;
52
- linked_account: LinkedAccount;
53
- privy_id?: string;
54
- embedded_wallet?: EmbeddedWallet;
55
- x_username?: string;
56
- x_user_id?: string;
57
- x_display_name?: string;
58
- google_email?: string;
59
- }
60
- export interface MeResponse {
61
- user_id: string;
62
- wallet_address: string;
63
- linked_account: LinkedAccount;
64
- privy_id?: string;
65
- embedded_wallet?: EmbeddedWallet;
66
- x_username?: string;
67
- x_user_id?: string;
68
- x_display_name?: string;
69
- google_email?: string;
70
- expires_at: number;
71
- }
72
128
  export interface NonceResponse {
73
129
  nonce: string;
74
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oBAAY,iBAAiB;IAC3B,MAAM,WAAW;IACjB,YAAY,kBAAkB;IAC9B,WAAW,iBAAiB;CAC7B;AAED,oBAAY,SAAS;IACnB,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,SAAS,CAAC;IAC1B,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,WAAW,CAAC,EAAE,eAAe,GAAG,OAAO,CAKtE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAE/D;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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"}
@@ -14,22 +14,106 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.ChainType = exports.LinkedAccountType = void 0;
17
+ exports.ChainType = exports.AuthMethod = void 0;
18
+ exports.identityText = identityText;
19
+ exports.userPrivy = userPrivy;
20
+ exports.userXAccount = userXAccount;
21
+ exports.tradingWallet = tradingWallet;
22
+ exports.displayName = displayName;
23
+ exports.avatarUrl = avatarUrl;
18
24
  exports.isAuthenticated = isAuthenticated;
19
25
  exports.generateSigninMessage = generateSigninMessage;
26
+ const str_1 = require("../shared/fmt/str");
20
27
  __exportStar(require("./client"), exports);
21
28
  __exportStar(require("./native"), exports);
22
- var LinkedAccountType;
23
- (function (LinkedAccountType) {
24
- LinkedAccountType["Wallet"] = "wallet";
25
- LinkedAccountType["TwitterOauth"] = "twitter_oauth";
26
- LinkedAccountType["GoogleOauth"] = "google_oauth";
27
- })(LinkedAccountType || (exports.LinkedAccountType = LinkedAccountType = {}));
29
+ /**
30
+ * How a session authenticated, as reported by the backend (derived from which
31
+ * token verified the request).
32
+ */
33
+ var AuthMethod;
34
+ (function (AuthMethod) {
35
+ AuthMethod["Privy"] = "privy";
36
+ AuthMethod["Lightcone"] = "lightcone";
37
+ })(AuthMethod || (exports.AuthMethod = AuthMethod = {}));
28
38
  var ChainType;
29
39
  (function (ChainType) {
30
40
  ChainType["Solana"] = "solana";
31
41
  ChainType["Ethereum"] = "ethereum";
32
42
  })(ChainType || (exports.ChainType = ChainType = {}));
43
+ /** Human-readable login-method label ("Google" / "X" / "Solana"). */
44
+ function identityText(identity) {
45
+ switch (identity.type) {
46
+ case "google":
47
+ return "Google";
48
+ case "x":
49
+ return "X";
50
+ case "wallet":
51
+ return "Solana";
52
+ default: {
53
+ const exhaustive = identity;
54
+ throw new Error(`Unknown identity: ${JSON.stringify(exhaustive)}`);
55
+ }
56
+ }
57
+ }
58
+ /** Privy account data, regardless of identity type. */
59
+ function userPrivy(user) {
60
+ switch (user.identity.type) {
61
+ case "google":
62
+ case "x":
63
+ return user.identity.privy;
64
+ case "wallet":
65
+ return user.identity.privy;
66
+ }
67
+ }
68
+ /** The X account, whether it is the login identity or a connected account. */
69
+ function userXAccount(user) {
70
+ return user.identity.type === "x" ? user.identity.account : user.connected_x;
71
+ }
72
+ /**
73
+ * The wallet a session operates as.
74
+ *
75
+ * Google/X identities only exist via Privy registration, which always
76
+ * provisions an embedded wallet — that wallet is the answer regardless of
77
+ * auth method. Wallet identities depend on the session: a Privy (SIWS)
78
+ * session trades via the embedded wallet, a Lightcone session trades via the
79
+ * wallet that signed in.
80
+ */
81
+ function tradingWallet(user, authMethod) {
82
+ switch (user.identity.type) {
83
+ case "google":
84
+ case "x":
85
+ return user.identity.privy.wallet.address;
86
+ case "wallet":
87
+ return authMethod === AuthMethod.Privy
88
+ ? (user.identity.privy?.wallet.address ?? user.identity.address)
89
+ : user.identity.address;
90
+ }
91
+ }
92
+ /**
93
+ * Best display name for the user. Google: `name`, falling back to the email;
94
+ * X: `display_name`, falling back to the username; wallet identities show the
95
+ * shortened address (`FRGk...WcPR`).
96
+ */
97
+ function displayName(user) {
98
+ switch (user.identity.type) {
99
+ case "google":
100
+ return user.identity.account.name ?? user.identity.account.email;
101
+ case "x":
102
+ return user.identity.account.display_name ?? user.identity.account.username;
103
+ case "wallet":
104
+ return (0, str_1.shorten)(user.identity.address, 8);
105
+ }
106
+ }
107
+ /** Avatar URL from the login identity's OAuth provider, if any. */
108
+ function avatarUrl(user) {
109
+ switch (user.identity.type) {
110
+ case "google":
111
+ case "x":
112
+ return user.identity.account.avatar_url;
113
+ case "wallet":
114
+ return undefined;
115
+ }
116
+ }
33
117
  function isAuthenticated(credentials) {
34
118
  if (!credentials) {
35
119
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AA+CA,0CAKC;AAED,sDAEC;AAtDD,2CAAyB;AACzB,2CAAyB;AAqBzB,IAAY,iBAIX;AAJD,WAAY,iBAAiB;IAC3B,sCAAiB,CAAA;IACjB,mDAA8B,CAAA;IAC9B,iDAA4B,CAAA;AAC9B,CAAC,EAJW,iBAAiB,iCAAjB,iBAAiB,QAI5B;AAED,IAAY,SAGX;AAHD,WAAY,SAAS;IACnB,8BAAiB,CAAA;IACjB,kCAAqB,CAAA;AACvB,CAAC,EAHW,SAAS,yBAAT,SAAS,QAGpB;AAcD,SAAgB,eAAe,CAAC,WAA6B;IAC3D,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;AACvD,CAAC;AAED,SAAgB,qBAAqB,CAAC,KAAa;IACjD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;AAC3E,CAAC","sourcesContent":["import type { PubkeyStr } from \"../shared\";\n\nexport * from \"./client\";\nexport * from \"./native\";\n\nexport interface User {\n id: string;\n wallet_address: string;\n linked_account: LinkedAccount;\n privy_id?: string;\n embedded_wallet?: EmbeddedWallet;\n x_username?: string;\n x_user_id?: string;\n x_display_name?: string;\n google_email?: string;\n}\n\nexport interface LinkedAccount {\n id: string;\n type: LinkedAccountType;\n chain?: ChainType;\n address: string;\n}\n\nexport enum LinkedAccountType {\n Wallet = \"wallet\",\n TwitterOauth = \"twitter_oauth\",\n GoogleOauth = \"google_oauth\",\n}\n\nexport enum ChainType {\n Solana = \"solana\",\n Ethereum = \"ethereum\",\n}\n\nexport interface EmbeddedWallet {\n privy_id: string;\n chain: ChainType;\n address: string;\n}\n\nexport interface AuthCredentials {\n user_id: string;\n wallet_address: PubkeyStr;\n expires_at: Date;\n}\n\nexport function isAuthenticated(credentials?: AuthCredentials): boolean {\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n}\n\nexport function generateSigninMessage(nonce: string): Uint8Array {\n return new TextEncoder().encode(`Sign in to Lightcone\\nNonce: ${nonce}`);\n}\n\nexport interface LoginRequest {\n message: string;\n signature_bs58: string;\n pubkey_bytes: number[];\n use_embedded_wallet?: boolean;\n}\n\nexport interface LoginResponse {\n user_id: string;\n wallet_address: string;\n expires_at: number;\n linked_account: LinkedAccount;\n privy_id?: string;\n embedded_wallet?: EmbeddedWallet;\n x_username?: string;\n x_user_id?: string;\n x_display_name?: string;\n google_email?: string;\n}\n\nexport interface MeResponse {\n user_id: string;\n wallet_address: string;\n linked_account: LinkedAccount;\n privy_id?: string;\n embedded_wallet?: EmbeddedWallet;\n x_username?: string;\n x_user_id?: string;\n x_display_name?: string;\n google_email?: string;\n expires_at: number;\n}\n\nexport interface NonceResponse {\n nonce: string;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PubkeyStr } from \"../shared\";\nimport { shorten } from \"../shared/fmt/str\";\n\nexport * from \"./client\";\nexport * from \"./native\";\n\n/**\n * How a session authenticated, as reported by the backend (derived from which\n * token verified the request).\n */\nexport enum AuthMethod {\n Privy = \"privy\",\n Lightcone = \"lightcone\",\n}\n\nexport enum ChainType {\n Solana = \"solana\",\n Ethereum = \"ethereum\",\n}\n\n/** A Privy-managed embedded wallet. */\nexport interface PrivyEmbeddedWallet {\n privy_id: string;\n chain: ChainType;\n address: string;\n}\n\n/** Privy account data attached to an identity. */\nexport interface UserPrivyData {\n /** The Privy DID (`did:privy:...`). */\n id: string;\n /**\n * Always present: Privy registration provisions the embedded wallet in the\n * same transaction that creates the user.\n */\n wallet: PrivyEmbeddedWallet;\n}\n\n/**\n * X account data — the same shape whether X is the login identity or a\n * connected account on a Google/wallet identity.\n */\nexport interface XAccountData {\n /** X numeric user id (Privy `subject`); absent on legacy rows. */\n user_id?: string;\n username: string;\n display_name?: string;\n avatar_url?: string;\n}\n\n/** Google account data for a Google login identity. */\nexport interface GoogleAccountData {\n email: string;\n name?: string;\n given_name?: string;\n family_name?: string;\n avatar_url?: string;\n}\n\n/**\n * The login identity — how the user authenticates. `type` narrows the variant.\n *\n * Privy data lives on the variant because its presence is determined by the\n * identity type: Google/X login only exists via Privy OAuth (guaranteed DID +\n * embedded wallet), while wallet users opt into Privy (SIWS) or stay\n * self-custody.\n */\nexport type UserIdentity =\n | { type: \"google\"; account: GoogleAccountData; privy: UserPrivyData }\n | { type: \"x\"; account: XAccountData; privy: UserPrivyData }\n | { type: \"wallet\"; address: string; chain: ChainType; privy?: UserPrivyData };\n\n/** Full user profile — the `user` object of {@link SessionResponse}. */\nexport interface User {\n user_id: string;\n identity: UserIdentity;\n /** X account connected by a non-X-identity user; absent when identity is X. */\n connected_x?: XAccountData;\n}\n\n/**\n * Session envelope returned by `loginWithMessage`, `register-privy`, and\n * `GET /api/auth/me`. There is no `wallet_address` field — derive the\n * session's trading wallet with {@link tradingWallet}.\n */\nexport interface SessionResponse {\n user: User;\n expires_at: number;\n auth_method: AuthMethod;\n is_beta: boolean;\n}\n\n/** Human-readable login-method label (\"Google\" / \"X\" / \"Solana\"). */\nexport function identityText(identity: UserIdentity): \"Google\" | \"X\" | \"Solana\" {\n switch (identity.type) {\n case \"google\":\n return \"Google\";\n case \"x\":\n return \"X\";\n case \"wallet\":\n return \"Solana\";\n default: {\n const exhaustive: never = identity;\n throw new Error(`Unknown identity: ${JSON.stringify(exhaustive)}`);\n }\n }\n}\n\n/** Privy account data, regardless of identity type. */\nexport function userPrivy(user: User): UserPrivyData | undefined {\n switch (user.identity.type) {\n case \"google\":\n case \"x\":\n return user.identity.privy;\n case \"wallet\":\n return user.identity.privy;\n }\n}\n\n/** The X account, whether it is the login identity or a connected account. */\nexport function userXAccount(user: User): XAccountData | undefined {\n return user.identity.type === \"x\" ? user.identity.account : user.connected_x;\n}\n\n/**\n * The wallet a session operates as.\n *\n * Google/X identities only exist via Privy registration, which always\n * provisions an embedded wallet — that wallet is the answer regardless of\n * auth method. Wallet identities depend on the session: a Privy (SIWS)\n * session trades via the embedded wallet, a Lightcone session trades via the\n * wallet that signed in.\n */\nexport function tradingWallet(user: User, authMethod: AuthMethod): string {\n switch (user.identity.type) {\n case \"google\":\n case \"x\":\n return user.identity.privy.wallet.address;\n case \"wallet\":\n return authMethod === AuthMethod.Privy\n ? (user.identity.privy?.wallet.address ?? user.identity.address)\n : user.identity.address;\n }\n}\n\n/**\n * Best display name for the user. Google: `name`, falling back to the email;\n * X: `display_name`, falling back to the username; wallet identities show the\n * shortened address (`FRGk...WcPR`).\n */\nexport function displayName(user: User): string {\n switch (user.identity.type) {\n case \"google\":\n return user.identity.account.name ?? user.identity.account.email;\n case \"x\":\n return user.identity.account.display_name ?? user.identity.account.username;\n case \"wallet\":\n return shorten(user.identity.address, 8);\n }\n}\n\n/** Avatar URL from the login identity's OAuth provider, if any. */\nexport function avatarUrl(user: User): string | undefined {\n switch (user.identity.type) {\n case \"google\":\n case \"x\":\n return user.identity.account.avatar_url;\n case \"wallet\":\n return undefined;\n }\n}\n\nexport interface AuthCredentials {\n user_id: string;\n wallet_address: PubkeyStr;\n expires_at: Date;\n}\n\nexport function isAuthenticated(credentials?: AuthCredentials): boolean {\n if (!credentials) {\n return false;\n }\n return Date.now() < credentials.expires_at.getTime();\n}\n\nexport function generateSigninMessage(nonce: string): Uint8Array {\n return new TextEncoder().encode(`Sign in to Lightcone\\nNonce: ${nonce}`);\n}\n\nexport interface LoginRequest {\n message: string;\n signature_bs58: string;\n pubkey_bytes: number[];\n use_embedded_wallet?: boolean;\n}\n\nexport interface NonceResponse {\n nonce: string;\n}\n"]}
package/dist/client.d.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
2
2
  import { Auth, type AuthCredentials } from "./auth";
3
3
  import type { ClientContext } from "./context";
4
- import { Admin } from "./domain/admin";
5
4
  import type { FaucetResponse } from "./domain/faucet";
6
5
  import { Markets } from "./domain/market";
7
6
  import { Metrics } from "./domain/metrics";
@@ -16,6 +15,7 @@ import { LightconeHttp } from "./http";
16
15
  import { LightconeEnv } from "./env";
17
16
  import { Privy } from "./privy";
18
17
  import { Rpc } from "./rpc";
18
+ import { RpcFailoverState } from "./rpcFailover";
19
19
  import { DepositSource, type PubkeyStr } from "./shared";
20
20
  import { type ExternalSigner, type SigningStrategy } from "./shared/signing";
21
21
  import { WsClient, type WsConfig } from "./ws";
@@ -29,17 +29,23 @@ declare class AuthState {
29
29
  export declare class LightconeClient implements ClientContext {
30
30
  readonly http: LightconeHttp;
31
31
  readonly programId: PublicKey;
32
- readonly connection?: Connection;
32
+ readonly primaryConnection?: Connection;
33
+ readonly backupConnection?: Connection;
34
+ readonly rpcFailoverState: RpcFailoverState;
33
35
  private depositSourceValue;
34
36
  private signingStrategyValue?;
35
37
  private orderNonceValue;
36
38
  private readonly wsConfigValue;
37
39
  private readonly authStateStore;
40
+ /** @deprecated Use primaryConnection — kept for ClientContext compat. */
41
+ get connection(): Connection | undefined;
38
42
  constructor(params: {
39
43
  http: LightconeHttp;
40
44
  wsConfig: WsConfig;
41
45
  programId?: PublicKey;
42
- connection?: Connection;
46
+ primaryConnection?: Connection;
47
+ backupConnection?: Connection;
48
+ rpcFailoverState?: RpcFailoverState;
43
49
  depositSource?: DepositSource;
44
50
  signingStrategy?: SigningStrategy;
45
51
  orderNonce?: number;
@@ -55,16 +61,16 @@ export declare class LightconeClient implements ClientContext {
55
61
  setOrderNonce(nonce: number): void;
56
62
  clearOrderNonce(): void;
57
63
  /**
58
- * Get the current `auth_token` cookie value, if any. Populated by the SDK
64
+ * Get the current `lightcone-token` cookie value, if any. Populated by the SDK
59
65
  * after a successful login, then attached on every authed request. Useful
60
- * for forwarding the token through the `*WithAuth` methods, or
66
+ * for forwarding the token through the `*WithCookies` methods, or
61
67
  * persisting the session across processes.
62
68
  */
63
69
  authToken(): Promise<string | undefined>;
64
70
  /**
65
- * Clear the cached `auth_token`. Subsequent authed calls will go out
71
+ * Clear the cached `lightcone-token`. Subsequent authed calls will go out
66
72
  * without a `Cookie` header (and 401) unless they use a
67
- * `*WithAuth` variant.
73
+ * `*WithCookies` variant.
68
74
  */
69
75
  clearAuthToken(): Promise<void>;
70
76
  signAndSubmitTx(tx: Transaction): Promise<string>;
@@ -90,7 +96,6 @@ export declare class LightconeClient implements ClientContext {
90
96
  * `POST /api/claim`
91
97
  */
92
98
  claim(walletAddress: PubkeyStr): Promise<FaucetResponse>;
93
- admin(): Admin;
94
99
  auth(): Auth;
95
100
  privy(): Privy;
96
101
  referrals(): Referrals;
@@ -106,7 +111,8 @@ export declare class LightconeClientBuilder {
106
111
  private programIdValue;
107
112
  private depositSourceValue;
108
113
  private signingStrategyValue?;
109
- private rpcUrlValue?;
114
+ private primaryRpcUrlValue?;
115
+ private backupRpcUrlValue?;
110
116
  /**
111
117
  * Set the deployment environment. Configures the API URL, WebSocket URL,
112
118
  * RPC URL, and program ID for the given environment.
@@ -127,6 +133,8 @@ export declare class LightconeClientBuilder {
127
133
  externalSigner(signer: ExternalSigner): LightconeClientBuilder;
128
134
  privyWalletId(walletId: string): LightconeClientBuilder;
129
135
  rpcUrl(url: string): LightconeClientBuilder;
136
+ /** Set a backup Solana RPC URL for automatic failover. */
137
+ backupRpcUrl(url: string): LightconeClientBuilder;
130
138
  build(): LightconeClient;
131
139
  }
132
140
  export {};