@temple-digital-group/temple-canton-js 1.0.39-beta.6 → 2.0.0-beta.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.
package/README.md CHANGED
@@ -40,12 +40,7 @@ setWalletAdapter(loop);
40
40
  | ---------------- | -------- | --------------------------------------------------------------- |
41
41
  | `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
42
42
  | `WALLET_ADAPTER` | Yes | Loop SDK instance — auto-detects server/client mode for signing |
43
- | `API_EMAIL` | No | Temple REST API email (triggers login at init) |
44
- | `API_PASSWORD` | No | Temple REST API password (required with `API_EMAIL`) |
45
-
46
- > You can optionally pass `API_EMAIL`/`API_PASSWORD` to authenticate with the REST API at init time.
47
-
48
- > **Legacy:** `initializeConfig()` is still available as a sync-only alternative (no REST API auth). `initialize()` is the recommended approach.
43
+ | `API_KEY` | No | Temple REST API key for authenticated endpoints |
49
44
 
50
45
  ## Supported Instruments
51
46
 
@@ -301,21 +296,17 @@ const counts = await getUtxoCount(partyId, "USDCx", walletProvider);
301
296
  | ------------------------------------------------------------------------------------------ | -------- | ------------------------------ |
302
297
  | `mergeAmuletHoldingsForParty(party, returnCommand, provider, maxUtxos, amuletDisclosures)` | **W** | Merge Amulet holdings into one |
303
298
  | `mergeUtilityHoldingsForParty(party, utilityAsset, returnCommand, provider, maxUtxos)` | **W** | Merge utility holdings into one |
304
- | `splitAmuletHoldingForParty(party, outputQuantity)` | | Split an Amulet holding |
305
- | `unlockLockedAmulets(party)` | | Unlock locked Amulet holdings |
306
299
 
307
300
  ### Temple REST API
308
301
 
309
- > These functions call the Temple REST API. Pass `API_EMAIL`/`API_PASSWORD` in `initialize()`, or call `login()` directly — tokens are stored and auto-refreshed.
302
+ > These functions call the Temple REST API. Pass `API_KEY` in `initialize()` or call `setApiKey()` to authenticate.
310
303
 
311
304
  #### Auth
312
305
 
313
306
  | Function | Description |
314
307
  | ----------------------------------- | --------------------------------------------------- |
315
- | `login(email, password)` | Login and store access/refresh tokens and user profile |
316
- | `refreshAccessToken(refreshToken?)` | Refresh the access token (auto-called when expired) |
317
- | `logout()` | Clear stored tokens |
318
- | `getUserId()` | Get the stored user ID from login |
308
+ | `setApiKey(key)` | Set the API key for REST API authentication |
309
+ | `getUserId()` | Get the stored user ID |
319
310
 
320
311
  #### Market Data
321
312
 
@@ -1,32 +1,13 @@
1
- import type { ApiError, LoginUser, LoginResponse, RefreshResponse, Ticker, OrderBook, OrderBookOptions, SymbolConfig, OpenInterest, Trade, RecentTradesOptions, ActiveOrder, ActiveOrdersOptions, CancelOrderResponse, CancelAllOrdersOptions, CancelAllOrdersResponse, CreateOrderRequestOpts, CreateOrderRequestResponse, DelegationResponse, WithdrawalResponse, WithdrawalStatusResponse, TradingBalanceResponse, AmuletDisclosure, DisclosuresResponse } from "./types.js";
2
- export type { ApiError, LoginUser, LoginResponse, RefreshResponse, Ticker, OrderBook, OrderBookOptions, SymbolConfig, OpenInterest, Trade, RecentTradesOptions, ActiveOrder, ActiveOrdersOptions, CancelOrderResponse, CancelAllOrdersOptions, CancelAllOrdersResponse, CreateOrderRequestResponse, DelegationResponse, WithdrawalResponse, WithdrawalStatusResponse, TradingBalanceResponse, AmuletDisclosure, DisclosuresResponse, };
3
- export { setApiKey, getUserId } from "./tokenStore.js";
1
+ import type { ApiError, Ticker, OrderBook, OrderBookOptions, SymbolConfig, OpenInterest, Trade, RecentTradesOptions, ActiveOrder, ActiveOrdersOptions, CancelOrderResponse, CancelAllOrdersOptions, CancelAllOrdersResponse, CreateOrderRequestOpts, CreateOrderRequestResponse, DelegationResponse, WithdrawalResponse, WithdrawalStatusResponse, TradingBalanceResponse, AmuletDisclosure, DisclosuresResponse } from "./types.js";
2
+ export type { ApiError, Ticker, OrderBook, OrderBookOptions, SymbolConfig, OpenInterest, Trade, RecentTradesOptions, ActiveOrder, ActiveOrdersOptions, CancelOrderResponse, CancelAllOrdersOptions, CancelAllOrdersResponse, CreateOrderRequestResponse, DelegationResponse, WithdrawalResponse, WithdrawalStatusResponse, TradingBalanceResponse, AmuletDisclosure, DisclosuresResponse, };
3
+ export { getUserId } from "./tokenStore.js";
4
4
  export { setWalletAdapter } from "../../src/config/index.js";
5
5
  /**
6
- * Initialize the Temple SDK — sets config and optionally authenticates with the REST API.
7
- * Pass `API_EMAIL`/`API_PASSWORD` or `API_KEY` to authenticate eagerly at init time.
6
+ * Initialize the Temple SDK — sets config and authenticates with the REST API via API key.
8
7
  *
9
- * @returns The login response on success, or an ApiError on failure.
10
- * Returns `null` if no API credentials were provided (config-only init).
8
+ * @returns null (config-only init). Throws no errors.
11
9
  */
12
- export declare function initialize(cfg: Record<string, unknown>): Promise<LoginResponse | ApiError | null>;
13
- /**
14
- * Login to the Temple REST API with email and password.
15
- * Stores tokens automatically for subsequent API calls.
16
- * @param email - User email
17
- * @param password - User password
18
- */
19
- export declare function login(email: string, password: string): Promise<LoginResponse | ApiError>;
20
- /**
21
- * Refresh the access token using the stored or provided refresh token.
22
- * Updates the token store automatically on success.
23
- * @param refreshTokenOverride - Optional explicit refresh token (uses stored one if omitted)
24
- */
25
- export declare function refreshAccessToken(refreshTokenOverride?: string): Promise<RefreshResponse | ApiError>;
26
- /**
27
- * Logout: clear all stored REST API tokens.
28
- */
29
- export declare function logout(): void;
10
+ export declare function initialize(cfg: Record<string, unknown>): Promise<null>;
30
11
  /**
31
12
  * Get ticker data for one or all trading pairs.
32
13
  * @param symbol - Optional symbol filter (e.g., "Amulet/USDCx")
@@ -77,7 +58,6 @@ export declare function cancelAllOrders(options?: CancelAllOrdersOptions): Promi
77
58
  export declare function getDisclosures(partyId: string): Promise<DisclosuresResponse | ApiError>;
78
59
  /**
79
60
  * Get the user's trading delegation status.
80
- * The user ID is extracted from the JWT token automatically.
81
61
  */
82
62
  export declare function getDelegation(): Promise<DelegationResponse | ApiError>;
83
63
  /**
package/dist/api/index.js CHANGED
@@ -1,36 +1,26 @@
1
1
  import axios from "axios";
2
2
  import config, { initializeConfig, setWalletAdapter } from "../../src/config/index.js";
3
- import { setTokens, getAccessToken, getRefreshToken, getApiKey, setApiKey as setApiKeyFromConfig, isTokenExpired, clearTokens, getAuthHeader, } from "./tokenStore.js";
4
- export { setApiKey, getUserId } from "./tokenStore.js";
3
+ import { getAuthHeader, setUserId, } from "./tokenStore.js";
4
+ export { getUserId } from "./tokenStore.js";
5
5
  export { setWalletAdapter } from "../../src/config/index.js";
6
6
  // ── Initialization ──
7
7
  /**
8
- * Initialize the Temple SDK — sets config and optionally authenticates with the REST API.
9
- * Pass `API_EMAIL`/`API_PASSWORD` or `API_KEY` to authenticate eagerly at init time.
8
+ * Initialize the Temple SDK — sets config and authenticates with the REST API via API key.
10
9
  *
11
- * @returns The login response on success, or an ApiError on failure.
12
- * Returns `null` if no API credentials were provided (config-only init).
10
+ * @returns null (config-only init). Throws no errors.
13
11
  */
14
12
  export async function initialize(cfg) {
15
13
  initializeConfig(cfg);
16
14
  if (cfg.WALLET_ADAPTER) {
17
15
  setWalletAdapter(cfg.WALLET_ADAPTER);
18
16
  }
19
- const apiKey = cfg.API_KEY;
20
- if (apiKey) {
21
- setApiKeyFromConfig(apiKey);
22
- return null;
23
- }
24
- const email = cfg.API_EMAIL;
25
- const password = cfg.API_PASSWORD;
26
- if (email && password) {
27
- return login(email, password);
17
+ const userIdValue = cfg.USER_ID;
18
+ if (userIdValue) {
19
+ setUserId(userIdValue);
28
20
  }
29
21
  return null;
30
22
  }
31
23
  // ── Internal helpers ──
32
- /** Pending auto-login promise for dedup. */
33
- let autoLoginPromise = null;
34
24
  function handleApiError(error, context) {
35
25
  const err = error;
36
26
  const status = err.response?.status ?? null;
@@ -42,49 +32,13 @@ function handleApiError(error, context) {
42
32
  console.error(`[Temple API] ${context}: ${message}${status ? ` (HTTP ${status})` : ""}`);
43
33
  return { error: true, status, code, message };
44
34
  }
45
- /** Pending refresh promise for dedup. */
46
- let refreshPromise = null;
47
- async function ensureAuthenticated() {
48
- // API key takes priority — no login needed
49
- const configApiKey = config.API_KEY;
50
- if (!getApiKey() && configApiKey) {
51
- setApiKeyFromConfig(configApiKey);
52
- }
53
- if (getApiKey())
35
+ function ensureAuthenticated() {
36
+ if (config.API_KEY)
54
37
  return null;
55
- // Auto-login from config if no token exists
56
- if (!getAccessToken()) {
57
- const email = config.API_EMAIL;
58
- const password = config.API_PASSWORD;
59
- if (email && password) {
60
- if (!autoLoginPromise) {
61
- autoLoginPromise = login(email, password).finally(() => {
62
- autoLoginPromise = null;
63
- });
64
- }
65
- const result = await autoLoginPromise;
66
- if ("error" in result && result.error)
67
- return result;
68
- }
69
- else {
70
- return { error: true, status: 401, code: "NOT_AUTHENTICATED", message: "Not logged in. Call login() or provide API_EMAIL/API_PASSWORD in config." };
71
- }
72
- }
73
- // Auto-refresh if expired
74
- if (isTokenExpired()) {
75
- if (!refreshPromise) {
76
- refreshPromise = refreshAccessToken().finally(() => {
77
- refreshPromise = null;
78
- });
79
- }
80
- const result = await refreshPromise;
81
- if ("error" in result && result.error)
82
- return result;
83
- }
84
- return null;
38
+ return { error: true, status: 401, code: "NOT_AUTHENTICATED", message: "API key required. Pass API_KEY in initialize()." };
85
39
  }
86
40
  async function authenticatedGet(path, params) {
87
- const authError = await ensureAuthenticated();
41
+ const authError = ensureAuthenticated();
88
42
  if (authError)
89
43
  return authError;
90
44
  const headers = {
@@ -111,7 +65,7 @@ async function authenticatedGet(path, params) {
111
65
  }
112
66
  }
113
67
  async function authenticatedPost(path, body) {
114
- const authError = await ensureAuthenticated();
68
+ const authError = ensureAuthenticated();
115
69
  if (authError)
116
70
  return authError;
117
71
  const headers = {
@@ -126,56 +80,6 @@ async function authenticatedPost(path, body) {
126
80
  return handleApiError(error, `POST ${path}`);
127
81
  }
128
82
  }
129
- // ── Auth ──
130
- /**
131
- * Login to the Temple REST API with email and password.
132
- * Stores tokens automatically for subsequent API calls.
133
- * @param email - User email
134
- * @param password - User password
135
- */
136
- export async function login(email, password) {
137
- if (!email || !password) {
138
- return { error: true, status: null, code: "INVALID_PARAMS", message: "Email and password are required." };
139
- }
140
- try {
141
- const response = await axios.post(`${config.API_BASE_URL}/auth/login`, {
142
- email,
143
- password,
144
- });
145
- setTokens(response.data);
146
- return response.data;
147
- }
148
- catch (error) {
149
- return handleApiError(error, "login");
150
- }
151
- }
152
- /**
153
- * Refresh the access token using the stored or provided refresh token.
154
- * Updates the token store automatically on success.
155
- * @param refreshTokenOverride - Optional explicit refresh token (uses stored one if omitted)
156
- */
157
- export async function refreshAccessToken(refreshTokenOverride) {
158
- const token = refreshTokenOverride ?? getRefreshToken();
159
- if (!token) {
160
- return { error: true, status: null, code: "NO_REFRESH_TOKEN", message: "No refresh token available. Call login() first." };
161
- }
162
- try {
163
- const response = await axios.post(`${config.API_BASE_URL}/auth/refresh`, {
164
- refresh_token: token,
165
- });
166
- setTokens(response.data);
167
- return response.data;
168
- }
169
- catch (error) {
170
- return handleApiError(error, "refreshAccessToken");
171
- }
172
- }
173
- /**
174
- * Logout: clear all stored REST API tokens.
175
- */
176
- export function logout() {
177
- clearTokens();
178
- }
179
83
  // ── Helpers ──
180
84
  /** Normalize CC → Amulet in symbol strings (e.g. "CC/SBC" → "Amulet/SBC", "CC" → "Amulet") */
181
85
  function normalizeSymbol(symbol) {
@@ -281,7 +185,6 @@ export async function getDisclosures(partyId) {
281
185
  // ── Delegation ──
282
186
  /**
283
187
  * Get the user's trading delegation status.
284
- * The user ID is extracted from the JWT token automatically.
285
188
  */
286
189
  export async function getDelegation() {
287
190
  return authenticatedGet("/api/trading/delegation");
@@ -1,38 +1,14 @@
1
- import type { TokenData, AuthHeaders } from "./types.js";
1
+ import type { AuthHeaders } from "./types.js";
2
2
  /**
3
- * Store tokens received from login or refresh.
4
- */
5
- export declare function setTokens(data: TokenData): void;
6
- /**
7
- * Get the current access token, or null if not logged in.
8
- */
9
- export declare function getAccessToken(): string | null;
10
- /**
11
- * Get the stored refresh token, or null if not logged in.
12
- */
13
- export declare function getRefreshToken(): string | null;
14
- /**
15
- * Check if the current access token is expired (with 60-second buffer).
16
- */
17
- export declare function isTokenExpired(): boolean;
18
- /**
19
- * Get the stored user ID from login, or null if not logged in.
3
+ * Get the stored user ID, or null if not set.
20
4
  */
21
5
  export declare function getUserId(): string | null;
22
6
  /**
23
- * Clear all stored tokens (logout).
24
- */
25
- export declare function clearTokens(): void;
26
- /**
27
- * Set an API key for authentication (future: replaces email/password login).
28
- */
29
- export declare function setApiKey(key: string): void;
30
- /**
31
- * Get the stored API key, or null if not set.
7
+ * Set the user ID directly (e.g. from config at init time).
32
8
  */
33
- export declare function getApiKey(): string | null;
9
+ export declare function setUserId(id: string): void;
34
10
  /**
35
- * Get the authorization header. Prefers API key if set, otherwise uses Bearer token.
36
- * Returns null if neither is available.
11
+ * Get the authorization header using the API key from config.
12
+ * Returns null if no API key is configured.
37
13
  */
38
14
  export declare function getAuthHeader(): AuthHeaders | null;
@@ -1,76 +1,25 @@
1
- let accessToken = null;
2
- let refreshToken = null;
3
- let tokenExpiryTime = null;
4
- let apiKey = null;
1
+ import config from "../../src/config/index.js";
5
2
  let userId = null;
6
3
  /**
7
- * Store tokens received from login or refresh.
8
- */
9
- export function setTokens(data) {
10
- accessToken = data.access_token;
11
- refreshToken = data.refresh_token;
12
- tokenExpiryTime = Date.now() + data.expires_in * 1000;
13
- if (data.user?.user_id != null) {
14
- userId = String(data.user.user_id);
15
- }
16
- }
17
- /**
18
- * Get the current access token, or null if not logged in.
19
- */
20
- export function getAccessToken() {
21
- return accessToken;
22
- }
23
- /**
24
- * Get the stored refresh token, or null if not logged in.
25
- */
26
- export function getRefreshToken() {
27
- return refreshToken;
28
- }
29
- /**
30
- * Check if the current access token is expired (with 60-second buffer).
31
- */
32
- export function isTokenExpired() {
33
- if (!tokenExpiryTime)
34
- return true;
35
- return Date.now() >= tokenExpiryTime - 60000;
36
- }
37
- /**
38
- * Get the stored user ID from login, or null if not logged in.
4
+ * Get the stored user ID, or null if not set.
39
5
  */
40
6
  export function getUserId() {
41
7
  return userId;
42
8
  }
43
9
  /**
44
- * Clear all stored tokens (logout).
45
- */
46
- export function clearTokens() {
47
- accessToken = null;
48
- refreshToken = null;
49
- tokenExpiryTime = null;
50
- userId = null;
51
- }
52
- /**
53
- * Set an API key for authentication (future: replaces email/password login).
10
+ * Set the user ID directly (e.g. from config at init time).
54
11
  */
55
- export function setApiKey(key) {
56
- apiKey = key;
12
+ export function setUserId(id) {
13
+ userId = id;
57
14
  }
58
15
  /**
59
- * Get the stored API key, or null if not set.
60
- */
61
- export function getApiKey() {
62
- return apiKey;
63
- }
64
- /**
65
- * Get the authorization header. Prefers API key if set, otherwise uses Bearer token.
66
- * Returns null if neither is available.
16
+ * Get the authorization header using the API key from config.
17
+ * Returns null if no API key is configured.
67
18
  */
68
19
  export function getAuthHeader() {
20
+ const apiKey = config.API_KEY;
69
21
  if (apiKey) {
70
- return { Authorization: `Bearer ${apiKey}` };
71
- }
72
- if (accessToken) {
73
- return { Authorization: `Bearer ${accessToken}` };
22
+ return { "X-API-Key": apiKey };
74
23
  }
75
24
  return null;
76
25
  }
@@ -1,20 +1,3 @@
1
- export interface LoginUser {
2
- user_id: number;
3
- max_limit_orders: number;
4
- max_market_orders: number;
5
- }
6
- export interface LoginResponse {
7
- access_token: string;
8
- refresh_token: string;
9
- expires_in: number;
10
- token_type: string;
11
- user: LoginUser;
12
- }
13
- export interface RefreshResponse {
14
- access_token: string;
15
- refresh_token: string;
16
- expires_in: number;
17
- }
18
1
  export interface Ticker {
19
2
  symbol: string;
20
3
  last_price: string;
@@ -161,12 +144,6 @@ export interface ApiError {
161
144
  code: string | null;
162
145
  message: string;
163
146
  }
164
- export interface TokenData {
165
- access_token: string;
166
- refresh_token: string;
167
- expires_in: number;
168
- user?: LoginUser;
169
- }
170
147
  export interface AuthHeaders {
171
- Authorization: string;
148
+ "X-API-Key": string;
172
149
  }
package/dist/api/types.js CHANGED
@@ -1,2 +1,2 @@
1
- // ── Auth ──
1
+ // ── Market Data ──
2
2
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@temple-digital-group/temple-canton-js",
3
- "version": "1.0.39-beta.6",
3
+ "version": "2.0.0-beta.2",
4
4
  "description": "JavaScript library for interacting with Temple Canton blockchain",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/api/index.ts CHANGED
@@ -1,20 +1,11 @@
1
1
  import axios, { type AxiosRequestConfig } from "axios";
2
2
  import config, { initializeConfig, setWalletAdapter } from "../../src/config/index.js";
3
3
  import {
4
- setTokens,
5
- getAccessToken,
6
- getRefreshToken,
7
- getApiKey,
8
- setApiKey as setApiKeyFromConfig,
9
- isTokenExpired,
10
- clearTokens,
11
4
  getAuthHeader,
5
+ setUserId,
12
6
  } from "./tokenStore.js";
13
7
  import type {
14
8
  ApiError,
15
- LoginUser,
16
- LoginResponse,
17
- RefreshResponse,
18
9
  Ticker,
19
10
  OrderBook,
20
11
  OrderBookOptions,
@@ -40,9 +31,6 @@ import type {
40
31
  // Re-export types and token utilities consumers may need
41
32
  export type {
42
33
  ApiError,
43
- LoginUser,
44
- LoginResponse,
45
- RefreshResponse,
46
34
  Ticker,
47
35
  OrderBook,
48
36
  OrderBookOptions,
@@ -63,35 +51,26 @@ export type {
63
51
  AmuletDisclosure,
64
52
  DisclosuresResponse,
65
53
  };
66
- export { setApiKey, getUserId } from "./tokenStore.js";
54
+ export { getUserId } from "./tokenStore.js";
67
55
  export { setWalletAdapter } from "../../src/config/index.js";
68
56
 
69
57
  // ── Initialization ──
70
58
 
71
59
  /**
72
- * Initialize the Temple SDK — sets config and optionally authenticates with the REST API.
73
- * Pass `API_EMAIL`/`API_PASSWORD` or `API_KEY` to authenticate eagerly at init time.
60
+ * Initialize the Temple SDK — sets config and authenticates with the REST API via API key.
74
61
  *
75
- * @returns The login response on success, or an ApiError on failure.
76
- * Returns `null` if no API credentials were provided (config-only init).
62
+ * @returns null (config-only init). Throws no errors.
77
63
  */
78
- export async function initialize(cfg: Record<string, unknown>): Promise<LoginResponse | ApiError | null> {
64
+ export async function initialize(cfg: Record<string, unknown>): Promise<null> {
79
65
  initializeConfig(cfg);
80
66
 
81
67
  if (cfg.WALLET_ADAPTER) {
82
68
  setWalletAdapter(cfg.WALLET_ADAPTER);
83
69
  }
84
70
 
85
- const apiKey = cfg.API_KEY as string | undefined;
86
- if (apiKey) {
87
- setApiKeyFromConfig(apiKey);
88
- return null;
89
- }
90
-
91
- const email = cfg.API_EMAIL as string | undefined;
92
- const password = cfg.API_PASSWORD as string | undefined;
93
- if (email && password) {
94
- return login(email, password);
71
+ const userIdValue = cfg.USER_ID as string | undefined;
72
+ if (userIdValue) {
73
+ setUserId(userIdValue);
95
74
  }
96
75
 
97
76
  return null;
@@ -99,9 +78,6 @@ export async function initialize(cfg: Record<string, unknown>): Promise<LoginRes
99
78
 
100
79
  // ── Internal helpers ──
101
80
 
102
- /** Pending auto-login promise for dedup. */
103
- let autoLoginPromise: Promise<LoginResponse | ApiError> | null = null;
104
-
105
81
  function handleApiError(error: unknown, context: string): ApiError {
106
82
  const err = error as { response?: { status?: number; data?: { message?: string; error?: string; code?: string } }; message?: string };
107
83
  const status = err.response?.status ?? null;
@@ -117,50 +93,13 @@ function handleApiError(error: unknown, context: string): ApiError {
117
93
  return { error: true, status, code, message };
118
94
  }
119
95
 
120
- /** Pending refresh promise for dedup. */
121
- let refreshPromise: Promise<RefreshResponse | ApiError> | null = null;
122
-
123
- async function ensureAuthenticated(): Promise<ApiError | null> {
124
- // API key takes priority — no login needed
125
- const configApiKey = (config as Record<string, unknown>).API_KEY as string | undefined;
126
- if (!getApiKey() && configApiKey) {
127
- setApiKeyFromConfig(configApiKey);
128
- }
129
- if (getApiKey()) return null;
130
-
131
- // Auto-login from config if no token exists
132
- if (!getAccessToken()) {
133
- const email = (config as Record<string, unknown>).API_EMAIL as string | undefined;
134
- const password = (config as Record<string, unknown>).API_PASSWORD as string | undefined;
135
- if (email && password) {
136
- if (!autoLoginPromise) {
137
- autoLoginPromise = login(email, password).finally(() => {
138
- autoLoginPromise = null;
139
- });
140
- }
141
- const result = await autoLoginPromise;
142
- if ("error" in result && result.error) return result as ApiError;
143
- } else {
144
- return { error: true, status: 401, code: "NOT_AUTHENTICATED", message: "Not logged in. Call login() or provide API_EMAIL/API_PASSWORD in config." };
145
- }
146
- }
147
-
148
- // Auto-refresh if expired
149
- if (isTokenExpired()) {
150
- if (!refreshPromise) {
151
- refreshPromise = refreshAccessToken().finally(() => {
152
- refreshPromise = null;
153
- });
154
- }
155
- const result = await refreshPromise;
156
- if ("error" in result && result.error) return result as ApiError;
157
- }
158
-
159
- return null;
96
+ function ensureAuthenticated(): ApiError | null {
97
+ if (config.API_KEY) return null;
98
+ return { error: true, status: 401, code: "NOT_AUTHENTICATED", message: "API key required. Pass API_KEY in initialize()." };
160
99
  }
161
100
 
162
101
  async function authenticatedGet<T>(path: string, params?: Record<string, string | number | undefined>): Promise<T | ApiError> {
163
- const authError = await ensureAuthenticated();
102
+ const authError = ensureAuthenticated();
164
103
  if (authError) return authError;
165
104
 
166
105
  const headers = {
@@ -188,7 +127,7 @@ async function authenticatedGet<T>(path: string, params?: Record<string, string
188
127
  }
189
128
 
190
129
  async function authenticatedPost<T>(path: string, body?: Record<string, unknown>): Promise<T | ApiError> {
191
- const authError = await ensureAuthenticated();
130
+ const authError = ensureAuthenticated();
192
131
  if (authError) return authError;
193
132
 
194
133
  const headers = {
@@ -204,60 +143,6 @@ async function authenticatedPost<T>(path: string, body?: Record<string, unknown>
204
143
  }
205
144
  }
206
145
 
207
- // ── Auth ──
208
-
209
- /**
210
- * Login to the Temple REST API with email and password.
211
- * Stores tokens automatically for subsequent API calls.
212
- * @param email - User email
213
- * @param password - User password
214
- */
215
- export async function login(email: string, password: string): Promise<LoginResponse | ApiError> {
216
- if (!email || !password) {
217
- return { error: true, status: null, code: "INVALID_PARAMS", message: "Email and password are required." };
218
- }
219
-
220
- try {
221
- const response = await axios.post<LoginResponse>(`${config.API_BASE_URL}/auth/login`, {
222
- email,
223
- password,
224
- });
225
- setTokens(response.data);
226
- return response.data;
227
- } catch (error) {
228
- return handleApiError(error, "login");
229
- }
230
- }
231
-
232
- /**
233
- * Refresh the access token using the stored or provided refresh token.
234
- * Updates the token store automatically on success.
235
- * @param refreshTokenOverride - Optional explicit refresh token (uses stored one if omitted)
236
- */
237
- export async function refreshAccessToken(refreshTokenOverride?: string): Promise<RefreshResponse | ApiError> {
238
- const token = refreshTokenOverride ?? getRefreshToken();
239
- if (!token) {
240
- return { error: true, status: null, code: "NO_REFRESH_TOKEN", message: "No refresh token available. Call login() first." };
241
- }
242
-
243
- try {
244
- const response = await axios.post<RefreshResponse>(`${config.API_BASE_URL}/auth/refresh`, {
245
- refresh_token: token,
246
- });
247
- setTokens(response.data);
248
- return response.data;
249
- } catch (error) {
250
- return handleApiError(error, "refreshAccessToken");
251
- }
252
- }
253
-
254
- /**
255
- * Logout: clear all stored REST API tokens.
256
- */
257
- export function logout(): void {
258
- clearTokens();
259
- }
260
-
261
146
  // ── Helpers ──
262
147
 
263
148
  /** Normalize CC → Amulet in symbol strings (e.g. "CC/SBC" → "Amulet/SBC", "CC" → "Amulet") */
@@ -378,7 +263,6 @@ export async function getDisclosures(partyId: string): Promise<DisclosuresRespon
378
263
 
379
264
  /**
380
265
  * Get the user's trading delegation status.
381
- * The user ID is extracted from the JWT token automatically.
382
266
  */
383
267
  export async function getDelegation(): Promise<DelegationResponse | ApiError> {
384
268
  return authenticatedGet("/api/trading/delegation");
@@ -1,87 +1,30 @@
1
- import type { TokenData, AuthHeaders } from "./types.js";
2
-
3
- let accessToken: string | null = null;
4
- let refreshToken: string | null = null;
5
- let tokenExpiryTime: number | null = null;
6
- let apiKey: string | null = null;
7
- let userId: string | null = null;
8
-
9
- /**
10
- * Store tokens received from login or refresh.
11
- */
12
- export function setTokens(data: TokenData): void {
13
- accessToken = data.access_token;
14
- refreshToken = data.refresh_token;
15
- tokenExpiryTime = Date.now() + data.expires_in * 1000;
16
- if (data.user?.user_id != null) {
17
- userId = String(data.user.user_id);
18
- }
19
- }
20
-
21
- /**
22
- * Get the current access token, or null if not logged in.
23
- */
24
- export function getAccessToken(): string | null {
25
- return accessToken;
26
- }
27
-
28
- /**
29
- * Get the stored refresh token, or null if not logged in.
30
- */
31
- export function getRefreshToken(): string | null {
32
- return refreshToken;
33
- }
34
-
35
- /**
36
- * Check if the current access token is expired (with 60-second buffer).
37
- */
38
- export function isTokenExpired(): boolean {
39
- if (!tokenExpiryTime) return true;
40
- return Date.now() >= tokenExpiryTime - 60_000;
41
- }
42
-
43
- /**
44
- * Get the stored user ID from login, or null if not logged in.
45
- */
46
- export function getUserId(): string | null {
47
- return userId;
48
- }
49
-
50
-
51
- /**
52
- * Clear all stored tokens (logout).
53
- */
54
- export function clearTokens(): void {
55
- accessToken = null;
56
- refreshToken = null;
57
- tokenExpiryTime = null;
58
- userId = null;
59
- }
60
-
61
- /**
62
- * Set an API key for authentication (future: replaces email/password login).
63
- */
64
- export function setApiKey(key: string): void {
65
- apiKey = key;
66
- }
67
-
68
- /**
69
- * Get the stored API key, or null if not set.
70
- */
71
- export function getApiKey(): string | null {
72
- return apiKey;
73
- }
74
-
75
- /**
76
- * Get the authorization header. Prefers API key if set, otherwise uses Bearer token.
77
- * Returns null if neither is available.
78
- */
79
- export function getAuthHeader(): AuthHeaders | null {
80
- if (apiKey) {
81
- return { Authorization: `Bearer ${apiKey}` };
82
- }
83
- if (accessToken) {
84
- return { Authorization: `Bearer ${accessToken}` };
85
- }
86
- return null;
87
- }
1
+ import config from "../../src/config/index.js";
2
+ import type { AuthHeaders } from "./types.js";
3
+
4
+ let userId: string | null = null;
5
+
6
+ /**
7
+ * Get the stored user ID, or null if not set.
8
+ */
9
+ export function getUserId(): string | null {
10
+ return userId;
11
+ }
12
+
13
+ /**
14
+ * Set the user ID directly (e.g. from config at init time).
15
+ */
16
+ export function setUserId(id: string): void {
17
+ userId = id;
18
+ }
19
+
20
+ /**
21
+ * Get the authorization header using the API key from config.
22
+ * Returns null if no API key is configured.
23
+ */
24
+ export function getAuthHeader(): AuthHeaders | null {
25
+ const apiKey = config.API_KEY;
26
+ if (apiKey) {
27
+ return { "X-API-Key": apiKey };
28
+ }
29
+ return null;
30
+ }
package/src/api/types.ts CHANGED
@@ -1,25 +1,3 @@
1
- // ── Auth ──
2
-
3
- export interface LoginUser {
4
- user_id: number;
5
- max_limit_orders: number;
6
- max_market_orders: number;
7
- }
8
-
9
- export interface LoginResponse {
10
- access_token: string;
11
- refresh_token: string;
12
- expires_in: number;
13
- token_type: string;
14
- user: LoginUser;
15
- }
16
-
17
- export interface RefreshResponse {
18
- access_token: string;
19
- refresh_token: string;
20
- expires_in: number;
21
- }
22
-
23
1
  // ── Market Data ──
24
2
 
25
3
  export interface Ticker {
@@ -209,15 +187,8 @@ export interface ApiError {
209
187
  message: string;
210
188
  }
211
189
 
212
- // ── Token Store ──
213
-
214
- export interface TokenData {
215
- access_token: string;
216
- refresh_token: string;
217
- expires_in: number;
218
- user?: LoginUser;
219
- }
190
+ // ── Auth ──
220
191
 
221
192
  export interface AuthHeaders {
222
- Authorization: string;
193
+ "X-API-Key": string;
223
194
  }
@@ -57,4 +57,5 @@ export namespace config {
57
57
  const VALIDATOR_REGISTRAR_PARTY_ID: any;
58
58
  const PACKAGE_NAME_SETTLEMENT_INTERFACE: any;
59
59
  const PACKAGE_NAME_SETTLEMENT_IMPL: any;
60
+ const API_KEY: any;
60
61
  }