@temple-digital-group/temple-canton-js 1.0.30
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/LICENSE +21 -0
- package/README.md +253 -0
- package/index.js +9 -0
- package/package.json +40 -0
- package/src/auth0/index.js +50 -0
- package/src/canton/index.js +3856 -0
- package/src/canton/instrumentCatalog.js +146 -0
- package/src/canton/request_schemas/cancel_orders_amulet.json +78 -0
- package/src/canton/request_schemas/cancel_orders_utility.json +69 -0
- package/src/canton/request_schemas/create_order_proposal_amulet.json +95 -0
- package/src/canton/request_schemas/create_order_proposal_utility.json +122 -0
- package/src/canton/request_schemas/create_utility_credential.json +31 -0
- package/src/canton/request_schemas/execute_transfer_factory.json +43 -0
- package/src/canton/request_schemas/get_allocation_factory.json +21 -0
- package/src/canton/request_schemas/get_amulet_holdings.json +22 -0
- package/src/canton/request_schemas/get_instrument_configurations.json +21 -0
- package/src/canton/request_schemas/get_locked_amulet_holdings.json +22 -0
- package/src/canton/request_schemas/get_order_proposals.json +22 -0
- package/src/canton/request_schemas/get_orders.json +22 -0
- package/src/canton/request_schemas/get_sender_credentials.json +22 -0
- package/src/canton/request_schemas/get_transfer_factory.json +29 -0
- package/src/canton/request_schemas/get_utility_holdings.json +22 -0
- package/src/canton/request_schemas/unlock_amulet.json +38 -0
- package/src/config/index.js +129 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Temple Digital Group
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# Temple Canton JS
|
|
2
|
+
|
|
3
|
+
JavaScript SDK for interacting with the Temple Canton blockchain exchange. Supports Amulet, USDCx, and CBTC tokens on the Canton network.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @temple-digital-group/temple-canton-js
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Configuration
|
|
12
|
+
|
|
13
|
+
There are three ways to use the SDK depending on your environment:
|
|
14
|
+
|
|
15
|
+
### 1. Browser with Custom Validator
|
|
16
|
+
|
|
17
|
+
For browser apps connecting to your own validator. Requires `initializeConfig()` with your validator URLs and a pre-authenticated JWT token.
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
import { initializeConfig } from '@temple-digital-group/temple-canton-js';
|
|
21
|
+
|
|
22
|
+
initializeConfig({
|
|
23
|
+
NETWORK: 'mainnet',
|
|
24
|
+
VALIDATOR_API_URL: 'https://your-validator-url',
|
|
25
|
+
VALIDATOR_SCAN_API_URL: 'https://your-scan-api-url',
|
|
26
|
+
TEMPLE_PARTY_ID: 'your-temple-party-id',
|
|
27
|
+
VALIDATOR_DSO_PARTY_ID: 'your-dso-party-id',
|
|
28
|
+
JWT_TOKEN: 'your-jwt-token',
|
|
29
|
+
VALIDATOR_USER_PARTY_ID: 'your-user-party-id'
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| Key | Required | Description |
|
|
34
|
+
|-----|----------|-------------|
|
|
35
|
+
| `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
|
|
36
|
+
| `VALIDATOR_API_URL` | Yes | Base URL of the Canton validator ledger API |
|
|
37
|
+
| `VALIDATOR_SCAN_API_URL` | Yes | Base URL of the Canton Scan API |
|
|
38
|
+
| `TEMPLE_PARTY_ID` | Yes | Temple's party ID on the network |
|
|
39
|
+
| `VALIDATOR_DSO_PARTY_ID` | Yes | The DSO (Decentralized Synchronizer Operator) party ID |
|
|
40
|
+
| `JWT_TOKEN` | Yes | Pre-authenticated JWT token for ledger API calls |
|
|
41
|
+
| `VALIDATOR_USER_PARTY_ID` | Yes | The user's party ID on the network |
|
|
42
|
+
|
|
43
|
+
### 2. Browser with Wallet Provider
|
|
44
|
+
|
|
45
|
+
For browser apps using a wallet (e.g., Loop Wallet). Requires `initializeConfig()` with base network config only. Use `returnCommand = true` to get the command back for the wallet to sign.
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
import { initializeConfig, createOrderProposal } from '@temple-digital-group/temple-canton-js';
|
|
49
|
+
|
|
50
|
+
initializeConfig({
|
|
51
|
+
NETWORK: 'mainnet',
|
|
52
|
+
TEMPLE_PARTY_ID: 'your-temple-party-id',
|
|
53
|
+
VALIDATOR_DSO_PARTY_ID: 'your-dso-party-id'
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// returnCommand=true returns the command for the wallet to sign
|
|
57
|
+
const command = await createOrderProposal(orderArgs, true, walletProvider);
|
|
58
|
+
const result = await walletProvider.signAndSubmit(command);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Key | Required | Description |
|
|
62
|
+
|-----|----------|-------------|
|
|
63
|
+
| `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
|
|
64
|
+
| `TEMPLE_PARTY_ID` | Yes | Temple's party ID on the network |
|
|
65
|
+
| `VALIDATOR_DSO_PARTY_ID` | Yes | The DSO (Decentralized Synchronizer Operator) party ID |
|
|
66
|
+
|
|
67
|
+
### 3. Node.js / Server-Side
|
|
68
|
+
|
|
69
|
+
For server-side applications. Uses environment variables directly — no `initializeConfig()` call needed. Create a `.env` file:
|
|
70
|
+
|
|
71
|
+
```env
|
|
72
|
+
NETWORK=mainnet
|
|
73
|
+
VALIDATOR_API_URL=https://your-validator-url
|
|
74
|
+
VALIDATOR_SCAN_API_URL=https://your-scan-api-url
|
|
75
|
+
TEMPLE_PARTY_ID=your-temple-party-id
|
|
76
|
+
VALIDATOR_DSO_PARTY_ID=your-dso-party-id
|
|
77
|
+
|
|
78
|
+
AUTH0_TOKEN_URL=https://your-auth0-domain.auth0.com/oauth/token
|
|
79
|
+
AUTH0_USER_ID=your-auth0-user-id
|
|
80
|
+
AUTH0_CLIENT_ID=your-client-id
|
|
81
|
+
AUTH0_CLIENT_SECRET=your-client-secret
|
|
82
|
+
AUTH0_AUDIENCE=https://your-audience
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
| Parameter | Required | Description |
|
|
86
|
+
|-----------|----------|-------------|
|
|
87
|
+
| `NETWORK` | Yes | `mainnet`, `testnet`, or `localhost` |
|
|
88
|
+
| `VALIDATOR_API_URL` | Yes | Base URL of the Canton validator ledger API |
|
|
89
|
+
| `VALIDATOR_SCAN_API_URL` | Yes | Base URL of the Canton Scan API |
|
|
90
|
+
| `TEMPLE_PARTY_ID` | Yes | Temple's party ID on the network |
|
|
91
|
+
| `VALIDATOR_DSO_PARTY_ID` | Yes | The DSO (Decentralized Synchronizer Operator) party ID |
|
|
92
|
+
| `AUTH0_TOKEN_URL` | Yes | Auth0 OAuth token endpoint |
|
|
93
|
+
| `AUTH0_CLIENT_ID` | Yes | Auth0 application client ID |
|
|
94
|
+
| `AUTH0_CLIENT_SECRET` | Yes | Auth0 application client secret |
|
|
95
|
+
| `AUTH0_AUDIENCE` | Yes | Auth0 API audience identifier |
|
|
96
|
+
| `AUTH0_USER_ID` | Yes | Auth0 user ID for the service account |
|
|
97
|
+
|
|
98
|
+
The SDK fetches and caches JWT tokens automatically via Auth0.
|
|
99
|
+
|
|
100
|
+
You can also call `initializeConfig()` in Node.js to override specific environment variables at runtime. For example, if a frontend passes a JWT token to your server:
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
import { initializeConfig, getUserBalances } from '@temple-digital-group/temple-canton-js';
|
|
104
|
+
|
|
105
|
+
// .env provides base config (NETWORK, VALIDATOR_API_URL, etc.)
|
|
106
|
+
// Override with a token received from the frontend
|
|
107
|
+
initializeConfig({ JWT_TOKEN: tokenFromFrontend });
|
|
108
|
+
|
|
109
|
+
const balances = await getUserBalances(partyId);
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Runtime config values take precedence over environment variables.
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
## Supported Instruments
|
|
116
|
+
|
|
117
|
+
| Asset | Type | Networks |
|
|
118
|
+
|---------|---------|-------------------|
|
|
119
|
+
| Amulet | Amulet | testnet, mainnet |
|
|
120
|
+
| USDCx | Utility | testnet, mainnet |
|
|
121
|
+
| CBTC | Utility | testnet, mainnet |
|
|
122
|
+
|
|
123
|
+
## Supported Trading Pairs
|
|
124
|
+
|
|
125
|
+
- `Amulet/USDCx`
|
|
126
|
+
- `CBTC/USDCx`
|
|
127
|
+
|
|
128
|
+
## Usage
|
|
129
|
+
|
|
130
|
+
### Get User Balances
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
import { getUserBalances } from '@temple-digital-group/temple-canton-js';
|
|
134
|
+
|
|
135
|
+
const balances = await getUserBalances(partyId);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Create an Order
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
import { createOrderProposal } from '@temple-digital-group/temple-canton-js';
|
|
142
|
+
|
|
143
|
+
const result = await createOrderProposal({
|
|
144
|
+
party: partyId,
|
|
145
|
+
symbol: 'Amulet/USDCx',
|
|
146
|
+
side: 'Buy',
|
|
147
|
+
quantity: '100',
|
|
148
|
+
pricePerUnit: '1.5',
|
|
149
|
+
expiration: new Date(Date.now() + 3600000).toISOString(),
|
|
150
|
+
userId: auth0UserId,
|
|
151
|
+
orderType: 'limit'
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Get Orders and Proposals
|
|
156
|
+
|
|
157
|
+
```javascript
|
|
158
|
+
import { getOrdersForParty, getOrderProposalsForParty } from '@temple-digital-group/temple-canton-js';
|
|
159
|
+
|
|
160
|
+
const orders = await getOrdersForParty(partyId);
|
|
161
|
+
const proposals = await getOrderProposalsForParty(partyId);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Merge Holdings
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
import { mergeAmuletHoldingsForParty, mergeUtilityHoldingsForParty } from '@temple-digital-group/temple-canton-js';
|
|
168
|
+
|
|
169
|
+
await mergeAmuletHoldingsForParty(partyId);
|
|
170
|
+
await mergeUtilityHoldingsForParty(partyId, 'USDCx');
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## API Reference
|
|
174
|
+
|
|
175
|
+
> Functions marked with **W** support a wallet provider parameter. All other functions require a custom validator (ledger access via `VALIDATOR_API_URL` and `JWT_TOKEN`).
|
|
176
|
+
|
|
177
|
+
### Configuration
|
|
178
|
+
|
|
179
|
+
| Function | Description |
|
|
180
|
+
|----------|-------------|
|
|
181
|
+
| `initializeConfig(config)` | Initialize the library with a runtime config object |
|
|
182
|
+
| `getConfigValue(key)` | Get a config value from runtime config or environment |
|
|
183
|
+
|
|
184
|
+
### Authentication
|
|
185
|
+
|
|
186
|
+
| Function | Description |
|
|
187
|
+
|----------|-------------|
|
|
188
|
+
| `getJWTToken()` | Get Auth0 JWT access token (cached with auto-refresh) |
|
|
189
|
+
|
|
190
|
+
### Instrument Catalog
|
|
191
|
+
|
|
192
|
+
These functions are synchronous and work in all environments (no ledger or provider needed).
|
|
193
|
+
|
|
194
|
+
| Function | Description |
|
|
195
|
+
|----------|-------------|
|
|
196
|
+
| `resolveInstrumentDefinition(assetId)` | Look up an instrument definition from the catalog |
|
|
197
|
+
| `getInstrumentRegistrar(assetId)` | Get the registrar party for a utility instrument |
|
|
198
|
+
| `getSupportedTradingPairs()` | Get the list of supported trading pairs |
|
|
199
|
+
| `getInstrumentCatalog()` | Get the full instrument catalog |
|
|
200
|
+
| `checkAmuletContext(baseAsset, quoteAsset, side)` | Check if an order requires Amulet context |
|
|
201
|
+
|
|
202
|
+
### Holdings
|
|
203
|
+
|
|
204
|
+
| Function | Provider | Description |
|
|
205
|
+
|----------|----------|-------------|
|
|
206
|
+
| `getAmuletHoldingsForParty(party)` | **W** | Get Amulet holdings |
|
|
207
|
+
| `getUtilityHoldingsForParty(party)` | **W** | Get utility token holdings |
|
|
208
|
+
| `getCandidateHoldingForOrderCreation(party, isAmulet, quantity, assetId)` | **W** | Find a holding suitable for an order |
|
|
209
|
+
| `getUserBalances(party)` | | Get all balances for a party, grouped by asset |
|
|
210
|
+
| `getLockedAmuletHoldingsForParty(party)` | | Get locked Amulet holdings |
|
|
211
|
+
|
|
212
|
+
### Orders
|
|
213
|
+
|
|
214
|
+
| Function | Provider | Description |
|
|
215
|
+
|----------|----------|-------------|
|
|
216
|
+
| `createOrderProposal(orderArguments)` | **W** | Create an order proposal |
|
|
217
|
+
| `getOrderProposalsForParty(party)` | | Get pending order proposals |
|
|
218
|
+
| `getOrdersForParty(party)` | | Get active orders |
|
|
219
|
+
|
|
220
|
+
### Holding Operations
|
|
221
|
+
|
|
222
|
+
| Function | Description |
|
|
223
|
+
|----------|-------------|
|
|
224
|
+
| `mergeAmuletHoldingsForParty(party)` | Merge Amulet holdings into one |
|
|
225
|
+
| `mergeUtilityHoldingsForParty(party, utilityAsset)` | Merge utility holdings into one |
|
|
226
|
+
| `splitAmuletHoldingForParty(party, outputQuantity)` | Split an Amulet holding |
|
|
227
|
+
| `unlockLockedAmulets(party)` | Unlock locked Amulet holdings |
|
|
228
|
+
|
|
229
|
+
### Ledger Queries
|
|
230
|
+
|
|
231
|
+
| Function | Description |
|
|
232
|
+
|----------|-------------|
|
|
233
|
+
| `getTransferFactory(investor, admin, amount, holdingIds)` | Get transfer factory from Scan API |
|
|
234
|
+
| `getAmuletDisclosures(party)` | Get Amulet disclosure contracts |
|
|
235
|
+
| `getAmuletRules(dso)` | Get AmuletRules contract |
|
|
236
|
+
| `getExternalAmuletRules(dso)` | Get ExternalPartyAmuletRules contract |
|
|
237
|
+
| `getFeaturedAppRight()` | Get FeaturedAppRight contract |
|
|
238
|
+
| `getOpenMiningRounds(dso)` | Get open mining rounds |
|
|
239
|
+
| `getCandidateMiningRoundContract(dso)` | Get a currently-open mining round |
|
|
240
|
+
| `getUtilityInstrumentConfigurations()` | Get utility instrument configurations |
|
|
241
|
+
| `getUtilityAllocationFactory()` | Get utility allocation factory |
|
|
242
|
+
| `getUtilitySenderCredentials(sender)` | Get sender credentials |
|
|
243
|
+
| `createUtilityCredential(holder, registrar)` | Create a utility credential |
|
|
244
|
+
|
|
245
|
+
### Deprecated
|
|
246
|
+
|
|
247
|
+
| Function | Description |
|
|
248
|
+
|----------|-------------|
|
|
249
|
+
| ~~`cancelOrders(party, orderContractIds, assetType)`~~ | Batch cancel orders (deprecated) |
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@temple-digital-group/temple-canton-js",
|
|
3
|
+
"version": "1.0.30",
|
|
4
|
+
"description": "JavaScript library for interacting with Temple Canton blockchain",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"index.js",
|
|
12
|
+
"src/"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/Temple-Digital-Group/temple-canton-js.git"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"author": "kakashigr <augegr@gmail.com>",
|
|
22
|
+
"keywords": [
|
|
23
|
+
"canton",
|
|
24
|
+
"blockchain",
|
|
25
|
+
"daml",
|
|
26
|
+
"splice",
|
|
27
|
+
"amulet",
|
|
28
|
+
"ledger",
|
|
29
|
+
"trading",
|
|
30
|
+
"temple"
|
|
31
|
+
],
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"scripts": {
|
|
34
|
+
"start": "node index.js"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"axios": "^1.13.1",
|
|
38
|
+
"dotenv": "^17.2.3"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +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
|
+
}
|