@temple-digital-group/temple-canton-js 2.0.0-beta.8 → 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 (42) hide show
  1. package/README.md +457 -447
  2. package/dist/api/index.js +3 -1
  3. package/dist/api/types.d.ts +1 -0
  4. package/dist/canton/deposits.js +4 -1
  5. package/dist/canton/withdrawals.js +19 -3
  6. package/index.js +15 -15
  7. package/package.json +49 -49
  8. package/src/api/config.d.ts +20 -20
  9. package/src/api/index.ts +322 -321
  10. package/src/api/tokenStore.ts +30 -30
  11. package/src/api/types.ts +196 -195
  12. package/src/auth0/index.d.ts +1 -1
  13. package/src/auth0/index.js +50 -50
  14. package/src/canton/deposits.ts +5 -1
  15. package/src/canton/helpers.ts +266 -266
  16. package/src/canton/index.d.ts +41 -41
  17. package/src/canton/index.js +3295 -3294
  18. package/src/canton/instrumentCatalog.d.ts +6 -6
  19. package/src/canton/instrumentCatalog.js +183 -183
  20. package/src/canton/request_schemas/cancel_orders_amulet.json +77 -77
  21. package/src/canton/request_schemas/cancel_orders_utility.json +68 -68
  22. package/src/canton/request_schemas/create_order_proposal_amulet.json +94 -94
  23. package/src/canton/request_schemas/create_order_proposal_utility.json +121 -121
  24. package/src/canton/request_schemas/create_utility_credential.json +31 -31
  25. package/src/canton/request_schemas/execute_transfer_factory.json +43 -43
  26. package/src/canton/request_schemas/get_allocation_factory.json +21 -21
  27. package/src/canton/request_schemas/get_amulet_holdings.json +21 -21
  28. package/src/canton/request_schemas/get_instrument_configurations.json +21 -21
  29. package/src/canton/request_schemas/get_locked_amulet_holdings.json +21 -21
  30. package/src/canton/request_schemas/get_order_proposals.json +21 -21
  31. package/src/canton/request_schemas/get_orders.json +21 -21
  32. package/src/canton/request_schemas/get_sender_credentials.json +22 -22
  33. package/src/canton/request_schemas/get_transfer_factory.json +28 -28
  34. package/src/canton/request_schemas/get_utility_holdings.json +21 -21
  35. package/src/canton/request_schemas/unlock_amulet.json +38 -38
  36. package/src/canton/walletAdapter.d.ts +7 -6
  37. package/src/canton/walletAdapter.js +112 -89
  38. package/src/canton/withdrawals.ts +511 -489
  39. package/src/config/index.d.ts +63 -63
  40. package/src/config/index.js +188 -188
  41. package/src/websocket/index.ts +341 -341
  42. package/src/websocket/ws.d.ts +24 -24
@@ -1,30 +1,30 @@
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
- }
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,195 +1,196 @@
1
- // ── Market Data ──
2
-
3
- export interface Ticker {
4
- symbol: string;
5
- last_price: string;
6
- bid_price: string;
7
- ask_price: string;
8
- high_24h: string;
9
- low_24h: string;
10
- volume_24h: string;
11
- change_24h: string;
12
- change_pct_24h: string;
13
- timestamp: string;
14
- }
15
-
16
- export interface OrderBookLevel {
17
- price: string;
18
- quantity: string;
19
- }
20
-
21
- export interface OrderBook {
22
- symbol: string;
23
- bids: OrderBookLevel[];
24
- asks: OrderBookLevel[];
25
- best_bid: string;
26
- best_ask: string;
27
- spread: string;
28
- timestamp: string;
29
- }
30
-
31
- export interface OrderBookOptions {
32
- levels?: number;
33
- precision?: 2 | 4;
34
- }
35
-
36
- export interface SymbolConfig {
37
- symbol: string;
38
- paused: boolean;
39
- max_decimals: number;
40
- minimum_quantity: string;
41
- }
42
-
43
- export interface OpenInterest {
44
- symbol: string;
45
- bid_interest: string;
46
- ask_interest: string;
47
- bid_order_count: number;
48
- ask_order_count: number;
49
- timestamp: string;
50
- }
51
-
52
- export interface Trade {
53
- trade_id: string;
54
- symbol: string;
55
- side: string;
56
- quantity: string;
57
- price: string;
58
- timestamp: string;
59
- }
60
-
61
- export interface RecentTradesOptions {
62
- limit?: number;
63
- }
64
-
65
- // ── Orders ──
66
-
67
- export interface ActiveOrder {
68
- order_id: string;
69
- symbol: string;
70
- side: string;
71
- quantity: string;
72
- price: string;
73
- status: string;
74
- created_at: string;
75
- updated_at: string;
76
- }
77
-
78
- export interface ActiveOrdersOptions {
79
- symbol?: string;
80
- limit?: number;
81
- }
82
-
83
- export interface CancelOrderResponse {
84
- success: boolean;
85
- order_id: string;
86
- already_queued: boolean;
87
- message: string;
88
- }
89
-
90
- export interface CancelAllOrdersOptions {
91
- symbol?: string;
92
- }
93
-
94
- export interface CancelAllOrdersResponse {
95
- success: boolean;
96
- canceled_count: number;
97
- already_queued_count: number;
98
- order_ids: string[];
99
- }
100
-
101
- // ── Delegation ──
102
-
103
- export interface Delegation {
104
- user_id: number;
105
- delegation_cid: string;
106
- created_at: string;
107
- updated_at: string;
108
- }
109
-
110
- export interface DelegationResponse {
111
- delegation: Delegation;
112
- }
113
-
114
- // ── Order Requests ──
115
-
116
- export interface CreateOrderRequestOpts {
117
- symbol: string;
118
- side: string;
119
- quantity: number;
120
- price: number;
121
- order_type?: string;
122
- expires_at?: string;
123
- }
124
-
125
-
126
- export interface CreateOrderRequestResponse {
127
- [key: string]: unknown;
128
- }
129
-
130
- // ── Withdrawals ──
131
-
132
- export interface WithdrawalRequest {
133
- asset_id: string;
134
- amount: string;
135
- }
136
-
137
- export interface WithdrawalResponse {
138
- [key: string]: unknown;
139
- }
140
-
141
- export interface WithdrawalStatusResponse {
142
- [key: string]: unknown;
143
- }
144
-
145
- // ── Trading Balances ──
146
-
147
- export interface TradingBalanceResponse {
148
- [key: string]: unknown;
149
- }
150
-
151
- // ── Disclosures ──
152
-
153
- export interface AmuletDisclosure {
154
- contractId: string;
155
- createdEventBlob: string;
156
- synchronizerId: string;
157
- templateId: string;
158
- }
159
-
160
- export interface ChoiceContextValue {
161
- tag: string;
162
- value: string;
163
- }
164
-
165
- export interface ChoiceContext {
166
- choiceContextData: {
167
- values: Record<string, ChoiceContextValue>;
168
- };
169
- disclosedContracts: AmuletDisclosure[];
170
- }
171
-
172
- export interface DisclosuresData {
173
- choiceContext: ChoiceContext;
174
- factoryId: string;
175
- transferKind: string;
176
- }
177
-
178
- export interface DisclosuresResponse {
179
- disclosures: DisclosuresData;
180
- }
181
-
182
- // ── Errors ──
183
-
184
- export interface ApiError {
185
- error: true;
186
- status: number | null;
187
- code: string | null;
188
- message: string;
189
- }
190
-
191
- // ── Auth ──
192
-
193
- export interface AuthHeaders {
194
- "X-API-Key": string;
195
- }
1
+ // ── Market Data ──
2
+
3
+ export interface Ticker {
4
+ symbol: string;
5
+ last_price: string;
6
+ bid_price: string;
7
+ ask_price: string;
8
+ high_24h: string;
9
+ low_24h: string;
10
+ volume_24h: string;
11
+ change_24h: string;
12
+ change_pct_24h: string;
13
+ timestamp: string;
14
+ }
15
+
16
+ export interface OrderBookLevel {
17
+ price: string;
18
+ quantity: string;
19
+ }
20
+
21
+ export interface OrderBook {
22
+ symbol: string;
23
+ bids: OrderBookLevel[];
24
+ asks: OrderBookLevel[];
25
+ best_bid: string;
26
+ best_ask: string;
27
+ spread: string;
28
+ timestamp: string;
29
+ }
30
+
31
+ export interface OrderBookOptions {
32
+ levels?: number;
33
+ precision?: 2 | 4;
34
+ }
35
+
36
+ export interface SymbolConfig {
37
+ symbol: string;
38
+ paused: boolean;
39
+ max_decimals: number;
40
+ minimum_quantity: string;
41
+ }
42
+
43
+ export interface OpenInterest {
44
+ symbol: string;
45
+ bid_interest: string;
46
+ ask_interest: string;
47
+ bid_order_count: number;
48
+ ask_order_count: number;
49
+ timestamp: string;
50
+ }
51
+
52
+ export interface Trade {
53
+ trade_id: string;
54
+ symbol: string;
55
+ side: string;
56
+ quantity: string;
57
+ price: string;
58
+ timestamp: string;
59
+ }
60
+
61
+ export interface RecentTradesOptions {
62
+ limit?: number;
63
+ }
64
+
65
+ // ── Orders ──
66
+
67
+ export interface ActiveOrder {
68
+ order_id: string;
69
+ symbol: string;
70
+ side: string;
71
+ quantity: string;
72
+ price: string;
73
+ status: string;
74
+ created_at: string;
75
+ updated_at: string;
76
+ }
77
+
78
+ export interface ActiveOrdersOptions {
79
+ symbol?: string;
80
+ limit?: number;
81
+ }
82
+
83
+ export interface CancelOrderResponse {
84
+ success: boolean;
85
+ order_id: string;
86
+ already_queued: boolean;
87
+ message: string;
88
+ }
89
+
90
+ export interface CancelAllOrdersOptions {
91
+ symbol?: string;
92
+ }
93
+
94
+ export interface CancelAllOrdersResponse {
95
+ success: boolean;
96
+ canceled_count: number;
97
+ already_queued_count: number;
98
+ order_ids: string[];
99
+ }
100
+
101
+ // ── Delegation ──
102
+
103
+ export interface Delegation {
104
+ user_id: number;
105
+ delegation_cid: string;
106
+ created_at: string;
107
+ updated_at: string;
108
+ }
109
+
110
+ export interface DelegationResponse {
111
+ delegation: Delegation;
112
+ }
113
+
114
+ // ── Order Requests ──
115
+
116
+ export interface CreateOrderRequestOpts {
117
+ symbol: string;
118
+ side: string;
119
+ quantity: number;
120
+ price: number;
121
+ order_type?: string;
122
+ order_subtype?: "post_only";
123
+ expires_at?: string;
124
+ }
125
+
126
+
127
+ export interface CreateOrderRequestResponse {
128
+ [key: string]: unknown;
129
+ }
130
+
131
+ // ── Withdrawals ──
132
+
133
+ export interface WithdrawalRequest {
134
+ asset_id: string;
135
+ amount: string;
136
+ }
137
+
138
+ export interface WithdrawalResponse {
139
+ [key: string]: unknown;
140
+ }
141
+
142
+ export interface WithdrawalStatusResponse {
143
+ [key: string]: unknown;
144
+ }
145
+
146
+ // ── Trading Balances ──
147
+
148
+ export interface TradingBalanceResponse {
149
+ [key: string]: unknown;
150
+ }
151
+
152
+ // ── Disclosures ──
153
+
154
+ export interface AmuletDisclosure {
155
+ contractId: string;
156
+ createdEventBlob: string;
157
+ synchronizerId: string;
158
+ templateId: string;
159
+ }
160
+
161
+ export interface ChoiceContextValue {
162
+ tag: string;
163
+ value: string;
164
+ }
165
+
166
+ export interface ChoiceContext {
167
+ choiceContextData: {
168
+ values: Record<string, ChoiceContextValue>;
169
+ };
170
+ disclosedContracts: AmuletDisclosure[];
171
+ }
172
+
173
+ export interface DisclosuresData {
174
+ choiceContext: ChoiceContext;
175
+ factoryId: string;
176
+ transferKind: string;
177
+ }
178
+
179
+ export interface DisclosuresResponse {
180
+ disclosures: DisclosuresData;
181
+ }
182
+
183
+ // ── Errors ──
184
+
185
+ export interface ApiError {
186
+ error: true;
187
+ status: number | null;
188
+ code: string | null;
189
+ message: string;
190
+ }
191
+
192
+ // ── Auth ──
193
+
194
+ export interface AuthHeaders {
195
+ "X-API-Key": string;
196
+ }
@@ -1 +1 @@
1
- export function getJWTToken(): Promise<string | null>;
1
+ export function getJWTToken(): Promise<string | null>;
@@ -1,50 +1,50 @@
1
- import config from "../config/index.js";
2
- import axios from "axios";
3
-
4
- let jwtToken = null;
5
- let tokenExpiryTime = null;
6
-
7
- /**
8
- * Get an Auth0 JWT access token with automatic caching and refresh.
9
- * Tokens are cached and reused until they expire (with a 60-second buffer).
10
- * Requires AUTH0_TOKEN_URL, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, and AUTH0_AUDIENCE to be configured.
11
- * @returns {Promise<string|null>} The JWT access token, or null on failure
12
- */
13
- export async function getJWTToken() {
14
- // Return cached token if not expired
15
- if (jwtToken != null && tokenExpiryTime != null) {
16
- // Check if expired (with 60 second buffer to avoid edge cases)
17
- const isExpired = Date.now() >= tokenExpiryTime - 60000;
18
- if (!isExpired) {
19
- return jwtToken.access_token;
20
- }
21
- }
22
- const encodedParams = new URLSearchParams();
23
- encodedParams.set("grant_type", config.AUTH0_GRANT_TYPE);
24
- encodedParams.set("client_id", config.AUTH0_CLIENT_ID);
25
- encodedParams.set("client_secret", config.AUTH0_CLIENT_SECRET);
26
- encodedParams.set("audience", config.AUTH0_AUDIENCE);
27
- encodedParams.set("scope", config.AUTH0_SCOPE);
28
-
29
- const options = {
30
- method: "POST",
31
- url: config.AUTH0_TOKEN_URL,
32
- headers: {
33
- "content-type": "application/x-www-form-urlencoded",
34
- },
35
- data: encodedParams,
36
- };
37
-
38
- try {
39
- const { data } = await axios.request(options);
40
- jwtToken = data;
41
- // Calculate expiry time: current time + expires_in (in seconds) * 1000 (to convert to milliseconds)
42
- tokenExpiryTime = Date.now() + data.expires_in * 1000;
43
- return jwtToken.access_token;
44
- } catch (error) {
45
- console.error(error);
46
- tokenExpiryTime = null;
47
- jwtToken = null;
48
- return null;
49
- }
50
- }
1
+ import config from "../config/index.js";
2
+ import axios from "axios";
3
+
4
+ let jwtToken = null;
5
+ let tokenExpiryTime = null;
6
+
7
+ /**
8
+ * Get an Auth0 JWT access token with automatic caching and refresh.
9
+ * Tokens are cached and reused until they expire (with a 60-second buffer).
10
+ * Requires AUTH0_TOKEN_URL, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, and AUTH0_AUDIENCE to be configured.
11
+ * @returns {Promise<string|null>} The JWT access token, or null on failure
12
+ */
13
+ export async function getJWTToken() {
14
+ // Return cached token if not expired
15
+ if (jwtToken != null && tokenExpiryTime != null) {
16
+ // Check if expired (with 60 second buffer to avoid edge cases)
17
+ const isExpired = Date.now() >= tokenExpiryTime - 60000;
18
+ if (!isExpired) {
19
+ return jwtToken.access_token;
20
+ }
21
+ }
22
+ const encodedParams = new URLSearchParams();
23
+ encodedParams.set("grant_type", config.AUTH0_GRANT_TYPE);
24
+ encodedParams.set("client_id", config.AUTH0_CLIENT_ID);
25
+ encodedParams.set("client_secret", config.AUTH0_CLIENT_SECRET);
26
+ encodedParams.set("audience", config.AUTH0_AUDIENCE);
27
+ encodedParams.set("scope", config.AUTH0_SCOPE);
28
+
29
+ const options = {
30
+ method: "POST",
31
+ url: config.AUTH0_TOKEN_URL,
32
+ headers: {
33
+ "content-type": "application/x-www-form-urlencoded",
34
+ },
35
+ data: encodedParams,
36
+ };
37
+
38
+ try {
39
+ const { data } = await axios.request(options);
40
+ jwtToken = data;
41
+ // Calculate expiry time: current time + expires_in (in seconds) * 1000 (to convert to milliseconds)
42
+ tokenExpiryTime = Date.now() + data.expires_in * 1000;
43
+ return jwtToken.access_token;
44
+ } catch (error) {
45
+ console.error(error);
46
+ tokenExpiryTime = null;
47
+ jwtToken = null;
48
+ return null;
49
+ }
50
+ }
@@ -2,7 +2,7 @@ import config from "../../src/config/index.js";
2
2
  import axios from "axios";
3
3
  import { getDisclosures } from "../api/index.js";
4
4
  import { getUserId } from "../api/tokenStore.js";
5
- import { getAdapterPartyId, getWalletAdapter, submitCommand } from "../../src/canton/walletAdapter.js";
5
+ import { getAdapterPartyId, getWalletAdapter, submitCommand, payDueGasIfAny } from "../../src/canton/walletAdapter.js";
6
6
  import { normalizeAssetId, instrumentCatalog } from "../../src/canton/instrumentCatalog.js";
7
7
  import {
8
8
  randomUUID,
@@ -183,6 +183,9 @@ export async function deposit(
183
183
  return { error: "deposit: could not resolve party ID from wallet adapter." };
184
184
  }
185
185
 
186
+ // Pay any outstanding network gas first so the balance check below is accurate.
187
+ await payDueGasIfAny();
188
+
186
189
  const assetId = normalizeAssetId(symbol);
187
190
  if (!instrumentCatalog[assetId]) {
188
191
  return { error: `deposit: unsupported symbol "${symbol}"` };
@@ -536,6 +539,7 @@ export async function depositFunds(
536
539
  // Auto-submit via wallet adapter if available
537
540
  if (getWalletAdapter()) {
538
541
  try {
542
+ await payDueGasIfAny();
539
543
  return (await submitCommand(command)) as Record<string, unknown>;
540
544
  } catch (error: unknown) {
541
545
  const msg = `depositFunds: wallet adapter submission failed: ${(error as Error).message}`;