@xchainjs/xchain-radix 2.0.11 → 2.0.12
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/lib/gateway-api.d.ts +165 -0
- package/lib/index.esm.js +134 -58
- package/lib/index.js +134 -58
- package/lib/radix-client.d.ts +3 -4
- package/package.json +1 -2
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight Radix Gateway API client replacing the heavy
|
|
3
|
+
* @radixdlt/babylon-gateway-api-sdk (~2.7 MB).
|
|
4
|
+
*
|
|
5
|
+
* Only implements the endpoints actually used by xchain-radix.
|
|
6
|
+
*/
|
|
7
|
+
export type LedgerState = {
|
|
8
|
+
network: string;
|
|
9
|
+
state_version: number;
|
|
10
|
+
proposer_round_timestamp: string;
|
|
11
|
+
epoch: number;
|
|
12
|
+
round: number;
|
|
13
|
+
};
|
|
14
|
+
export type GatewayStatusResponse = {
|
|
15
|
+
ledger_state: LedgerState;
|
|
16
|
+
};
|
|
17
|
+
export type FungibleResourcesCollectionItem = {
|
|
18
|
+
aggregation_level: string;
|
|
19
|
+
resource_address: string;
|
|
20
|
+
amount: number | string;
|
|
21
|
+
last_updated_at_state_version: number;
|
|
22
|
+
};
|
|
23
|
+
export type NonFungibleResourcesCollectionItem = {
|
|
24
|
+
aggregation_level: string;
|
|
25
|
+
resource_address: string;
|
|
26
|
+
amount: number;
|
|
27
|
+
last_updated_at_state_version: number;
|
|
28
|
+
};
|
|
29
|
+
export type StateEntityDetailsVaultResponseItem = {
|
|
30
|
+
address: string;
|
|
31
|
+
details?: {
|
|
32
|
+
type: string;
|
|
33
|
+
divisibility?: number;
|
|
34
|
+
[key: string]: any;
|
|
35
|
+
};
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
};
|
|
38
|
+
export type StateEntityFungiblesPageRequest = {
|
|
39
|
+
address: string;
|
|
40
|
+
limit_per_page: number;
|
|
41
|
+
cursor?: string;
|
|
42
|
+
at_ledger_state?: {
|
|
43
|
+
state_version: number;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export type StateEntityFungiblesPageResponse = {
|
|
47
|
+
ledger_state: LedgerState;
|
|
48
|
+
total_count?: number;
|
|
49
|
+
items: FungibleResourcesCollectionItem[];
|
|
50
|
+
next_cursor?: string;
|
|
51
|
+
address?: string;
|
|
52
|
+
};
|
|
53
|
+
export type StateEntityNonFungiblesPageRequest = {
|
|
54
|
+
address: string;
|
|
55
|
+
limit_per_page: number;
|
|
56
|
+
cursor?: string;
|
|
57
|
+
at_ledger_state?: {
|
|
58
|
+
state_version: number;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export type StateEntityNonFungiblesPageResponse = {
|
|
62
|
+
ledger_state: LedgerState;
|
|
63
|
+
total_count?: number;
|
|
64
|
+
items: NonFungibleResourcesCollectionItem[];
|
|
65
|
+
next_cursor?: string;
|
|
66
|
+
address?: string;
|
|
67
|
+
};
|
|
68
|
+
export type GatewayPublicKey = {
|
|
69
|
+
key_type: string;
|
|
70
|
+
key_hex: string;
|
|
71
|
+
};
|
|
72
|
+
export type TransactionPreviewRequest = {
|
|
73
|
+
manifest: string;
|
|
74
|
+
blobs_hex: string[];
|
|
75
|
+
start_epoch_inclusive: number;
|
|
76
|
+
end_epoch_exclusive: number;
|
|
77
|
+
notary_public_key: GatewayPublicKey;
|
|
78
|
+
notary_is_signatory: boolean;
|
|
79
|
+
tip_percentage: number;
|
|
80
|
+
nonce: number;
|
|
81
|
+
signer_public_keys: GatewayPublicKey[];
|
|
82
|
+
flags: {
|
|
83
|
+
assume_all_signature_proofs: boolean;
|
|
84
|
+
skip_epoch_check: boolean;
|
|
85
|
+
use_free_credit: boolean;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
export type TransactionPreviewResponse = {
|
|
89
|
+
receipt: {
|
|
90
|
+
status: string;
|
|
91
|
+
fee_summary: {
|
|
92
|
+
execution_cost_units_consumed: number;
|
|
93
|
+
finalization_cost_units_consumed: number;
|
|
94
|
+
xrd_total_execution_cost: string;
|
|
95
|
+
xrd_total_finalization_cost: string;
|
|
96
|
+
xrd_total_royalty_cost: string;
|
|
97
|
+
xrd_total_storage_cost: string;
|
|
98
|
+
xrd_total_tipping_cost: string;
|
|
99
|
+
};
|
|
100
|
+
[key: string]: any;
|
|
101
|
+
};
|
|
102
|
+
[key: string]: any;
|
|
103
|
+
};
|
|
104
|
+
export type TransactionSubmitResponse = {
|
|
105
|
+
duplicate: boolean;
|
|
106
|
+
};
|
|
107
|
+
export type CommittedTransactionInfo = {
|
|
108
|
+
transaction_status: string;
|
|
109
|
+
state_version: number;
|
|
110
|
+
epoch: number;
|
|
111
|
+
round: number;
|
|
112
|
+
round_timestamp: string;
|
|
113
|
+
payload_hash: string;
|
|
114
|
+
intent_hash: string;
|
|
115
|
+
fee_paid: string;
|
|
116
|
+
confirmed_at?: Date;
|
|
117
|
+
raw_hex?: string;
|
|
118
|
+
receipt?: {
|
|
119
|
+
status: string;
|
|
120
|
+
};
|
|
121
|
+
manifest_classes?: string[];
|
|
122
|
+
};
|
|
123
|
+
export type TransactionCommittedDetailsResponse = {
|
|
124
|
+
ledger_state?: LedgerState;
|
|
125
|
+
transaction: CommittedTransactionInfo;
|
|
126
|
+
};
|
|
127
|
+
export type StreamTransactionsRequest = {
|
|
128
|
+
affected_global_entities_filter?: string[];
|
|
129
|
+
limit_per_page?: number;
|
|
130
|
+
from_ledger_state?: {
|
|
131
|
+
state_version: number;
|
|
132
|
+
};
|
|
133
|
+
manifest_resources_filter?: string[];
|
|
134
|
+
opt_ins?: {
|
|
135
|
+
raw_hex?: boolean;
|
|
136
|
+
};
|
|
137
|
+
cursor?: string;
|
|
138
|
+
};
|
|
139
|
+
export type StreamTransactionsResponse = {
|
|
140
|
+
items: CommittedTransactionInfo[];
|
|
141
|
+
next_cursor?: string;
|
|
142
|
+
};
|
|
143
|
+
export type TransactionStatusResponse = {
|
|
144
|
+
status: string;
|
|
145
|
+
intent_hash: string;
|
|
146
|
+
};
|
|
147
|
+
export declare class RadixGatewayApi {
|
|
148
|
+
private baseUrl;
|
|
149
|
+
constructor(networkId: number);
|
|
150
|
+
private post;
|
|
151
|
+
getStatus(): Promise<GatewayStatusResponse>;
|
|
152
|
+
getEntityDetailsVaultAggregated(addresses: string[]): Promise<StateEntityDetailsVaultResponseItem[]>;
|
|
153
|
+
getEntityFungiblesPage(request: StateEntityFungiblesPageRequest): Promise<StateEntityFungiblesPageResponse>;
|
|
154
|
+
getEntityNonFungiblesPage(request: StateEntityNonFungiblesPageRequest): Promise<StateEntityNonFungiblesPageResponse>;
|
|
155
|
+
previewTransaction(request: TransactionPreviewRequest): Promise<TransactionPreviewResponse>;
|
|
156
|
+
submitTransaction(notarizedTransactionHex: string): Promise<TransactionSubmitResponse>;
|
|
157
|
+
getTransactionDetails(request: {
|
|
158
|
+
intent_hash: string;
|
|
159
|
+
opt_ins?: {
|
|
160
|
+
raw_hex?: boolean;
|
|
161
|
+
};
|
|
162
|
+
}): Promise<TransactionCommittedDetailsResponse>;
|
|
163
|
+
getStreamTransactions(request: StreamTransactionsRequest): Promise<StreamTransactionsResponse>;
|
|
164
|
+
getTransactionStatus(intentHash: string): Promise<TransactionStatusResponse>;
|
|
165
|
+
}
|
package/lib/index.esm.js
CHANGED
|
@@ -5,7 +5,6 @@ import { AssetType, assetToBase, assetAmount, eqAsset, baseAmount } from '@xchai
|
|
|
5
5
|
import { bech32m } from '@scure/base';
|
|
6
6
|
import { HDKey } from '@scure/bip32';
|
|
7
7
|
import slip10 from 'micro-key-producer/slip10.js';
|
|
8
|
-
import { GatewayApiClient } from '@radixdlt/babylon-gateway-api-sdk';
|
|
9
8
|
|
|
10
9
|
/******************************************************************************
|
|
11
10
|
Copyright (c) Microsoft Corporation.
|
|
@@ -84,6 +83,102 @@ const feesEstimationPublicKeys = {
|
|
|
84
83
|
},
|
|
85
84
|
};
|
|
86
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Lightweight Radix Gateway API client replacing the heavy
|
|
88
|
+
* @radixdlt/babylon-gateway-api-sdk (~2.7 MB).
|
|
89
|
+
*
|
|
90
|
+
* Only implements the endpoints actually used by xchain-radix.
|
|
91
|
+
*/
|
|
92
|
+
// #endregion Types
|
|
93
|
+
// #region API Client
|
|
94
|
+
const NETWORK_URLS = {
|
|
95
|
+
1: 'https://mainnet.radixdlt.com',
|
|
96
|
+
2: 'https://stokenet.radixdlt.com',
|
|
97
|
+
};
|
|
98
|
+
class RadixGatewayApi {
|
|
99
|
+
constructor(networkId) {
|
|
100
|
+
const url = NETWORK_URLS[networkId];
|
|
101
|
+
if (!url)
|
|
102
|
+
throw new Error(`Unsupported Radix network ID: ${networkId}`);
|
|
103
|
+
this.baseUrl = url;
|
|
104
|
+
}
|
|
105
|
+
post(path, body) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
const response = yield fetch(`${this.baseUrl}${path}`, {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
headers: { 'Content-Type': 'application/json' },
|
|
110
|
+
body: JSON.stringify(body),
|
|
111
|
+
});
|
|
112
|
+
if (!response.ok) {
|
|
113
|
+
throw new Error(`Radix Gateway API error: ${response.status} ${response.statusText}`);
|
|
114
|
+
}
|
|
115
|
+
return response.json();
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
getStatus() {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
return this.post('/status/gateway-status', {});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
getEntityDetailsVaultAggregated(addresses) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
const response = yield this.post('/state/entity/details', {
|
|
126
|
+
addresses,
|
|
127
|
+
aggregation_level: 'Vault',
|
|
128
|
+
});
|
|
129
|
+
return response.items;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
getEntityFungiblesPage(request) {
|
|
133
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
+
return this.post('/state/entity/page/fungibles/', request);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
getEntityNonFungiblesPage(request) {
|
|
138
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
return this.post('/state/entity/page/non-fungibles/', request);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
previewTransaction(request) {
|
|
143
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
144
|
+
return this.post('/transaction/preview', request);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
submitTransaction(notarizedTransactionHex) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
return this.post('/transaction/submit', {
|
|
150
|
+
notarized_transaction_hex: notarizedTransactionHex,
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
getTransactionDetails(request) {
|
|
155
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
156
|
+
const response = yield this.post('/transaction/committed-details', request);
|
|
157
|
+
if (response.transaction.confirmed_at) {
|
|
158
|
+
response.transaction.confirmed_at = new Date(response.transaction.confirmed_at);
|
|
159
|
+
}
|
|
160
|
+
return response;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
getStreamTransactions(request) {
|
|
164
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
165
|
+
const response = yield this.post('/stream/transactions', request);
|
|
166
|
+
for (const item of response.items) {
|
|
167
|
+
if (item.confirmed_at) {
|
|
168
|
+
item.confirmed_at = new Date(item.confirmed_at);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return response;
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
getTransactionStatus(intentHash) {
|
|
175
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
176
|
+
return this.post('/transaction/status', { intent_hash: intentHash });
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// #endregion API Client
|
|
181
|
+
|
|
87
182
|
/**
|
|
88
183
|
* The main client for the Radix network which is then wrapped by the {Client} adapting it to have
|
|
89
184
|
* a {BaseXChainClient} interface.
|
|
@@ -91,29 +186,29 @@ const feesEstimationPublicKeys = {
|
|
|
91
186
|
class RadixSpecificClient {
|
|
92
187
|
constructor(networkId) {
|
|
93
188
|
this.innerNetwork = networkId;
|
|
94
|
-
this.
|
|
189
|
+
this.innerGateway = new RadixGatewayApi(networkId);
|
|
95
190
|
}
|
|
96
191
|
// #region Getters & Setters
|
|
97
192
|
set networkId(networkId) {
|
|
98
193
|
this.innerNetwork = networkId;
|
|
99
|
-
this.
|
|
194
|
+
this.innerGateway = new RadixGatewayApi(networkId);
|
|
100
195
|
}
|
|
101
196
|
get networkId() {
|
|
102
197
|
return this.innerNetwork;
|
|
103
198
|
}
|
|
104
|
-
get
|
|
105
|
-
return this.
|
|
199
|
+
get gateway() {
|
|
200
|
+
return this.innerGateway;
|
|
106
201
|
}
|
|
107
202
|
// #endregion
|
|
108
203
|
// #region Public Methods
|
|
109
204
|
currentEpoch() {
|
|
110
205
|
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
-
return this.
|
|
206
|
+
return this.innerGateway.getStatus().then((status) => status.ledger_state.epoch);
|
|
112
207
|
});
|
|
113
208
|
}
|
|
114
209
|
currentStateVersion() {
|
|
115
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
116
|
-
return this.
|
|
211
|
+
return this.innerGateway.getStatus().then((status) => status.ledger_state.state_version);
|
|
117
212
|
});
|
|
118
213
|
}
|
|
119
214
|
fetchBalances(address) {
|
|
@@ -141,12 +236,13 @@ class RadixSpecificClient {
|
|
|
141
236
|
}
|
|
142
237
|
for (const batch of resourceBatches) {
|
|
143
238
|
const addresses = batch.map((item) => item.resource_address);
|
|
144
|
-
const response = yield this.
|
|
239
|
+
const response = yield this.gateway.getEntityDetailsVaultAggregated(addresses);
|
|
145
240
|
const divisibilities = new Map();
|
|
146
241
|
response.forEach((result) => {
|
|
242
|
+
var _a;
|
|
147
243
|
if (result.details !== undefined) {
|
|
148
244
|
if (result.details.type === 'FungibleResource') {
|
|
149
|
-
divisibilities.set(result.address, result.details.divisibility);
|
|
245
|
+
divisibilities.set(result.address, (_a = result.details.divisibility) !== null && _a !== void 0 ? _a : 0);
|
|
150
246
|
}
|
|
151
247
|
}
|
|
152
248
|
});
|
|
@@ -190,9 +286,7 @@ class RadixSpecificClient {
|
|
|
190
286
|
state_version: stateVersion,
|
|
191
287
|
},
|
|
192
288
|
};
|
|
193
|
-
const stateEntityNonFungiblesPageResponse = yield this.
|
|
194
|
-
stateEntityNonFungiblesPageRequest: stateEntityNonFungiblesPageRequest,
|
|
195
|
-
});
|
|
289
|
+
const stateEntityNonFungiblesPageResponse = yield this.gateway.getEntityNonFungiblesPage(stateEntityNonFungiblesPageRequest);
|
|
196
290
|
nonFungibleResources = nonFungibleResources.concat(stateEntityNonFungiblesPageResponse.items);
|
|
197
291
|
if (stateEntityNonFungiblesPageResponse.next_cursor) {
|
|
198
292
|
nextCursor = stateEntityNonFungiblesPageResponse.next_cursor;
|
|
@@ -219,9 +313,7 @@ class RadixSpecificClient {
|
|
|
219
313
|
state_version: stateVersion,
|
|
220
314
|
},
|
|
221
315
|
};
|
|
222
|
-
const stateEntityFungiblesPageResponse = yield this.
|
|
223
|
-
stateEntityFungiblesPageRequest: stateEntityFungiblesPageRequest,
|
|
224
|
-
});
|
|
316
|
+
const stateEntityFungiblesPageResponse = yield this.gateway.getEntityFungiblesPage(stateEntityFungiblesPageRequest);
|
|
225
317
|
fungibleResources = fungibleResources.concat(stateEntityFungiblesPageResponse.items);
|
|
226
318
|
if (stateEntityFungiblesPageResponse.next_cursor) {
|
|
227
319
|
nextCursor = stateEntityFungiblesPageResponse.next_cursor;
|
|
@@ -286,21 +378,12 @@ class RadixSpecificClient {
|
|
|
286
378
|
return __awaiter(this, void 0, void 0, function* () {
|
|
287
379
|
const intentHash = yield RadixEngineToolkit.NotarizedTransaction.intentHash(notarizedTransaction);
|
|
288
380
|
const transactionHex = yield RadixEngineToolkit.NotarizedTransaction.compile(notarizedTransaction).then(Convert.Uint8Array.toHexString);
|
|
289
|
-
const response = yield this.
|
|
290
|
-
transactionSubmitRequest: { notarized_transaction_hex: transactionHex },
|
|
291
|
-
});
|
|
381
|
+
const response = yield this.innerGateway.submitTransaction(transactionHex);
|
|
292
382
|
return [response, intentHash];
|
|
293
383
|
});
|
|
294
384
|
}
|
|
295
385
|
// #endregion Public Methods
|
|
296
386
|
// #region Private Methods
|
|
297
|
-
static createGatewayClient(network) {
|
|
298
|
-
const applicationName = 'xchainjs';
|
|
299
|
-
return GatewayApiClient.initialize({
|
|
300
|
-
networkId: network,
|
|
301
|
-
applicationName,
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
387
|
static createSimpleTransferManifest(from, to, resourceAddress, amount, amountToLockForFees) {
|
|
305
388
|
return new ManifestBuilder()
|
|
306
389
|
.callMethod(from, 'lock_fee', [decimal(amountToLockForFees)])
|
|
@@ -341,25 +424,23 @@ class RadixSpecificClient {
|
|
|
341
424
|
return __awaiter(this, void 0, void 0, function* () {
|
|
342
425
|
// Translate the RET models to the gateway models for preview.
|
|
343
426
|
const request = {
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
use_free_credit: false,
|
|
359
|
-
},
|
|
427
|
+
manifest: yield RadixEngineToolkit.Instructions.convert(intent.manifest.instructions, this.networkId, 'String').then((instructions) => instructions.value),
|
|
428
|
+
blobs_hex: [],
|
|
429
|
+
start_epoch_inclusive: intent.header.startEpochInclusive,
|
|
430
|
+
end_epoch_exclusive: intent.header.endEpochExclusive,
|
|
431
|
+
notary_public_key: RadixSpecificClient.retPublicKeyToGatewayPublicKey(intent.header.notaryPublicKey),
|
|
432
|
+
notary_is_signatory: intent.header.notaryIsSignatory,
|
|
433
|
+
tip_percentage: intent.header.tipPercentage,
|
|
434
|
+
nonce: intent.header.nonce,
|
|
435
|
+
signer_public_keys: [RadixSpecificClient.retPublicKeyToGatewayPublicKey(intent.header.notaryPublicKey)],
|
|
436
|
+
// TODO: Add message
|
|
437
|
+
flags: {
|
|
438
|
+
assume_all_signature_proofs: false,
|
|
439
|
+
skip_epoch_check: false,
|
|
440
|
+
use_free_credit: false,
|
|
360
441
|
},
|
|
361
442
|
};
|
|
362
|
-
return this.
|
|
443
|
+
return this.innerGateway.previewTransaction(request);
|
|
363
444
|
});
|
|
364
445
|
}
|
|
365
446
|
static retPublicKeyToGatewayPublicKey(publicKey) {
|
|
@@ -623,19 +704,17 @@ class Client extends BaseXChainClient {
|
|
|
623
704
|
let committedTransactions = [];
|
|
624
705
|
const txList = { txs: [], total: 0 };
|
|
625
706
|
while (hasNextPage) {
|
|
626
|
-
const response = yield this.radixSpecificClient.
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
raw_hex: true,
|
|
636
|
-
},
|
|
637
|
-
cursor: nextCursor,
|
|
707
|
+
const response = yield this.radixSpecificClient.gateway.getStreamTransactions({
|
|
708
|
+
affected_global_entities_filter: [address],
|
|
709
|
+
limit_per_page: limit && limit > 100 ? 100 : limit,
|
|
710
|
+
from_ledger_state: {
|
|
711
|
+
state_version: offset,
|
|
712
|
+
},
|
|
713
|
+
manifest_resources_filter: asset ? [asset] : undefined,
|
|
714
|
+
opt_ins: {
|
|
715
|
+
raw_hex: true,
|
|
638
716
|
},
|
|
717
|
+
cursor: nextCursor,
|
|
639
718
|
});
|
|
640
719
|
committedTransactions = committedTransactions.concat(response.items);
|
|
641
720
|
if (response.next_cursor) {
|
|
@@ -672,14 +751,11 @@ class Client extends BaseXChainClient {
|
|
|
672
751
|
getTransactionData(txId) {
|
|
673
752
|
return __awaiter(this, void 0, void 0, function* () {
|
|
674
753
|
try {
|
|
675
|
-
const
|
|
754
|
+
const transactionCommittedDetailsResponse = yield this.radixSpecificClient.gateway.getTransactionDetails({
|
|
676
755
|
intent_hash: txId,
|
|
677
756
|
opt_ins: {
|
|
678
757
|
raw_hex: true,
|
|
679
758
|
},
|
|
680
|
-
};
|
|
681
|
-
const transactionCommittedDetailsResponse = yield this.radixSpecificClient.gatewayClient.transaction.innerClient.transactionCommittedDetails({
|
|
682
|
-
transactionCommittedDetailsRequest: transactionCommittedDetailsRequest,
|
|
683
759
|
});
|
|
684
760
|
if (transactionCommittedDetailsResponse.transaction.raw_hex !== undefined &&
|
|
685
761
|
transactionCommittedDetailsResponse.transaction.confirmed_at !== null &&
|
package/lib/index.js
CHANGED
|
@@ -7,7 +7,6 @@ var xchainUtil = require('@xchainjs/xchain-util');
|
|
|
7
7
|
var base = require('@scure/base');
|
|
8
8
|
var bip32 = require('@scure/bip32');
|
|
9
9
|
var slip10 = require('micro-key-producer/slip10.js');
|
|
10
|
-
var babylonGatewayApiSdk = require('@radixdlt/babylon-gateway-api-sdk');
|
|
11
10
|
|
|
12
11
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
12
|
|
|
@@ -90,6 +89,102 @@ const feesEstimationPublicKeys = {
|
|
|
90
89
|
},
|
|
91
90
|
};
|
|
92
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Lightweight Radix Gateway API client replacing the heavy
|
|
94
|
+
* @radixdlt/babylon-gateway-api-sdk (~2.7 MB).
|
|
95
|
+
*
|
|
96
|
+
* Only implements the endpoints actually used by xchain-radix.
|
|
97
|
+
*/
|
|
98
|
+
// #endregion Types
|
|
99
|
+
// #region API Client
|
|
100
|
+
const NETWORK_URLS = {
|
|
101
|
+
1: 'https://mainnet.radixdlt.com',
|
|
102
|
+
2: 'https://stokenet.radixdlt.com',
|
|
103
|
+
};
|
|
104
|
+
class RadixGatewayApi {
|
|
105
|
+
constructor(networkId) {
|
|
106
|
+
const url = NETWORK_URLS[networkId];
|
|
107
|
+
if (!url)
|
|
108
|
+
throw new Error(`Unsupported Radix network ID: ${networkId}`);
|
|
109
|
+
this.baseUrl = url;
|
|
110
|
+
}
|
|
111
|
+
post(path, body) {
|
|
112
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
+
const response = yield fetch(`${this.baseUrl}${path}`, {
|
|
114
|
+
method: 'POST',
|
|
115
|
+
headers: { 'Content-Type': 'application/json' },
|
|
116
|
+
body: JSON.stringify(body),
|
|
117
|
+
});
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
throw new Error(`Radix Gateway API error: ${response.status} ${response.statusText}`);
|
|
120
|
+
}
|
|
121
|
+
return response.json();
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
getStatus() {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
return this.post('/status/gateway-status', {});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
getEntityDetailsVaultAggregated(addresses) {
|
|
130
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
+
const response = yield this.post('/state/entity/details', {
|
|
132
|
+
addresses,
|
|
133
|
+
aggregation_level: 'Vault',
|
|
134
|
+
});
|
|
135
|
+
return response.items;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
getEntityFungiblesPage(request) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
return this.post('/state/entity/page/fungibles/', request);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
getEntityNonFungiblesPage(request) {
|
|
144
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
+
return this.post('/state/entity/page/non-fungibles/', request);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
previewTransaction(request) {
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
return this.post('/transaction/preview', request);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
submitTransaction(notarizedTransactionHex) {
|
|
154
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
155
|
+
return this.post('/transaction/submit', {
|
|
156
|
+
notarized_transaction_hex: notarizedTransactionHex,
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
getTransactionDetails(request) {
|
|
161
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
162
|
+
const response = yield this.post('/transaction/committed-details', request);
|
|
163
|
+
if (response.transaction.confirmed_at) {
|
|
164
|
+
response.transaction.confirmed_at = new Date(response.transaction.confirmed_at);
|
|
165
|
+
}
|
|
166
|
+
return response;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
getStreamTransactions(request) {
|
|
170
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
171
|
+
const response = yield this.post('/stream/transactions', request);
|
|
172
|
+
for (const item of response.items) {
|
|
173
|
+
if (item.confirmed_at) {
|
|
174
|
+
item.confirmed_at = new Date(item.confirmed_at);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return response;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
getTransactionStatus(intentHash) {
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
return this.post('/transaction/status', { intent_hash: intentHash });
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// #endregion API Client
|
|
187
|
+
|
|
93
188
|
/**
|
|
94
189
|
* The main client for the Radix network which is then wrapped by the {Client} adapting it to have
|
|
95
190
|
* a {BaseXChainClient} interface.
|
|
@@ -97,29 +192,29 @@ const feesEstimationPublicKeys = {
|
|
|
97
192
|
class RadixSpecificClient {
|
|
98
193
|
constructor(networkId) {
|
|
99
194
|
this.innerNetwork = networkId;
|
|
100
|
-
this.
|
|
195
|
+
this.innerGateway = new RadixGatewayApi(networkId);
|
|
101
196
|
}
|
|
102
197
|
// #region Getters & Setters
|
|
103
198
|
set networkId(networkId) {
|
|
104
199
|
this.innerNetwork = networkId;
|
|
105
|
-
this.
|
|
200
|
+
this.innerGateway = new RadixGatewayApi(networkId);
|
|
106
201
|
}
|
|
107
202
|
get networkId() {
|
|
108
203
|
return this.innerNetwork;
|
|
109
204
|
}
|
|
110
|
-
get
|
|
111
|
-
return this.
|
|
205
|
+
get gateway() {
|
|
206
|
+
return this.innerGateway;
|
|
112
207
|
}
|
|
113
208
|
// #endregion
|
|
114
209
|
// #region Public Methods
|
|
115
210
|
currentEpoch() {
|
|
116
211
|
return __awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
return this.
|
|
212
|
+
return this.innerGateway.getStatus().then((status) => status.ledger_state.epoch);
|
|
118
213
|
});
|
|
119
214
|
}
|
|
120
215
|
currentStateVersion() {
|
|
121
216
|
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
-
return this.
|
|
217
|
+
return this.innerGateway.getStatus().then((status) => status.ledger_state.state_version);
|
|
123
218
|
});
|
|
124
219
|
}
|
|
125
220
|
fetchBalances(address) {
|
|
@@ -147,12 +242,13 @@ class RadixSpecificClient {
|
|
|
147
242
|
}
|
|
148
243
|
for (const batch of resourceBatches) {
|
|
149
244
|
const addresses = batch.map((item) => item.resource_address);
|
|
150
|
-
const response = yield this.
|
|
245
|
+
const response = yield this.gateway.getEntityDetailsVaultAggregated(addresses);
|
|
151
246
|
const divisibilities = new Map();
|
|
152
247
|
response.forEach((result) => {
|
|
248
|
+
var _a;
|
|
153
249
|
if (result.details !== undefined) {
|
|
154
250
|
if (result.details.type === 'FungibleResource') {
|
|
155
|
-
divisibilities.set(result.address, result.details.divisibility);
|
|
251
|
+
divisibilities.set(result.address, (_a = result.details.divisibility) !== null && _a !== void 0 ? _a : 0);
|
|
156
252
|
}
|
|
157
253
|
}
|
|
158
254
|
});
|
|
@@ -196,9 +292,7 @@ class RadixSpecificClient {
|
|
|
196
292
|
state_version: stateVersion,
|
|
197
293
|
},
|
|
198
294
|
};
|
|
199
|
-
const stateEntityNonFungiblesPageResponse = yield this.
|
|
200
|
-
stateEntityNonFungiblesPageRequest: stateEntityNonFungiblesPageRequest,
|
|
201
|
-
});
|
|
295
|
+
const stateEntityNonFungiblesPageResponse = yield this.gateway.getEntityNonFungiblesPage(stateEntityNonFungiblesPageRequest);
|
|
202
296
|
nonFungibleResources = nonFungibleResources.concat(stateEntityNonFungiblesPageResponse.items);
|
|
203
297
|
if (stateEntityNonFungiblesPageResponse.next_cursor) {
|
|
204
298
|
nextCursor = stateEntityNonFungiblesPageResponse.next_cursor;
|
|
@@ -225,9 +319,7 @@ class RadixSpecificClient {
|
|
|
225
319
|
state_version: stateVersion,
|
|
226
320
|
},
|
|
227
321
|
};
|
|
228
|
-
const stateEntityFungiblesPageResponse = yield this.
|
|
229
|
-
stateEntityFungiblesPageRequest: stateEntityFungiblesPageRequest,
|
|
230
|
-
});
|
|
322
|
+
const stateEntityFungiblesPageResponse = yield this.gateway.getEntityFungiblesPage(stateEntityFungiblesPageRequest);
|
|
231
323
|
fungibleResources = fungibleResources.concat(stateEntityFungiblesPageResponse.items);
|
|
232
324
|
if (stateEntityFungiblesPageResponse.next_cursor) {
|
|
233
325
|
nextCursor = stateEntityFungiblesPageResponse.next_cursor;
|
|
@@ -292,21 +384,12 @@ class RadixSpecificClient {
|
|
|
292
384
|
return __awaiter(this, void 0, void 0, function* () {
|
|
293
385
|
const intentHash = yield radixEngineToolkit.RadixEngineToolkit.NotarizedTransaction.intentHash(notarizedTransaction);
|
|
294
386
|
const transactionHex = yield radixEngineToolkit.RadixEngineToolkit.NotarizedTransaction.compile(notarizedTransaction).then(radixEngineToolkit.Convert.Uint8Array.toHexString);
|
|
295
|
-
const response = yield this.
|
|
296
|
-
transactionSubmitRequest: { notarized_transaction_hex: transactionHex },
|
|
297
|
-
});
|
|
387
|
+
const response = yield this.innerGateway.submitTransaction(transactionHex);
|
|
298
388
|
return [response, intentHash];
|
|
299
389
|
});
|
|
300
390
|
}
|
|
301
391
|
// #endregion Public Methods
|
|
302
392
|
// #region Private Methods
|
|
303
|
-
static createGatewayClient(network) {
|
|
304
|
-
const applicationName = 'xchainjs';
|
|
305
|
-
return babylonGatewayApiSdk.GatewayApiClient.initialize({
|
|
306
|
-
networkId: network,
|
|
307
|
-
applicationName,
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
393
|
static createSimpleTransferManifest(from, to, resourceAddress, amount, amountToLockForFees) {
|
|
311
394
|
return new radixEngineToolkit.ManifestBuilder()
|
|
312
395
|
.callMethod(from, 'lock_fee', [radixEngineToolkit.decimal(amountToLockForFees)])
|
|
@@ -347,25 +430,23 @@ class RadixSpecificClient {
|
|
|
347
430
|
return __awaiter(this, void 0, void 0, function* () {
|
|
348
431
|
// Translate the RET models to the gateway models for preview.
|
|
349
432
|
const request = {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
use_free_credit: false,
|
|
365
|
-
},
|
|
433
|
+
manifest: yield radixEngineToolkit.RadixEngineToolkit.Instructions.convert(intent.manifest.instructions, this.networkId, 'String').then((instructions) => instructions.value),
|
|
434
|
+
blobs_hex: [],
|
|
435
|
+
start_epoch_inclusive: intent.header.startEpochInclusive,
|
|
436
|
+
end_epoch_exclusive: intent.header.endEpochExclusive,
|
|
437
|
+
notary_public_key: RadixSpecificClient.retPublicKeyToGatewayPublicKey(intent.header.notaryPublicKey),
|
|
438
|
+
notary_is_signatory: intent.header.notaryIsSignatory,
|
|
439
|
+
tip_percentage: intent.header.tipPercentage,
|
|
440
|
+
nonce: intent.header.nonce,
|
|
441
|
+
signer_public_keys: [RadixSpecificClient.retPublicKeyToGatewayPublicKey(intent.header.notaryPublicKey)],
|
|
442
|
+
// TODO: Add message
|
|
443
|
+
flags: {
|
|
444
|
+
assume_all_signature_proofs: false,
|
|
445
|
+
skip_epoch_check: false,
|
|
446
|
+
use_free_credit: false,
|
|
366
447
|
},
|
|
367
448
|
};
|
|
368
|
-
return this.
|
|
449
|
+
return this.innerGateway.previewTransaction(request);
|
|
369
450
|
});
|
|
370
451
|
}
|
|
371
452
|
static retPublicKeyToGatewayPublicKey(publicKey) {
|
|
@@ -629,19 +710,17 @@ class Client extends xchainClient.BaseXChainClient {
|
|
|
629
710
|
let committedTransactions = [];
|
|
630
711
|
const txList = { txs: [], total: 0 };
|
|
631
712
|
while (hasNextPage) {
|
|
632
|
-
const response = yield this.radixSpecificClient.
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
raw_hex: true,
|
|
642
|
-
},
|
|
643
|
-
cursor: nextCursor,
|
|
713
|
+
const response = yield this.radixSpecificClient.gateway.getStreamTransactions({
|
|
714
|
+
affected_global_entities_filter: [address],
|
|
715
|
+
limit_per_page: limit && limit > 100 ? 100 : limit,
|
|
716
|
+
from_ledger_state: {
|
|
717
|
+
state_version: offset,
|
|
718
|
+
},
|
|
719
|
+
manifest_resources_filter: asset ? [asset] : undefined,
|
|
720
|
+
opt_ins: {
|
|
721
|
+
raw_hex: true,
|
|
644
722
|
},
|
|
723
|
+
cursor: nextCursor,
|
|
645
724
|
});
|
|
646
725
|
committedTransactions = committedTransactions.concat(response.items);
|
|
647
726
|
if (response.next_cursor) {
|
|
@@ -678,14 +757,11 @@ class Client extends xchainClient.BaseXChainClient {
|
|
|
678
757
|
getTransactionData(txId) {
|
|
679
758
|
return __awaiter(this, void 0, void 0, function* () {
|
|
680
759
|
try {
|
|
681
|
-
const
|
|
760
|
+
const transactionCommittedDetailsResponse = yield this.radixSpecificClient.gateway.getTransactionDetails({
|
|
682
761
|
intent_hash: txId,
|
|
683
762
|
opt_ins: {
|
|
684
763
|
raw_hex: true,
|
|
685
764
|
},
|
|
686
|
-
};
|
|
687
|
-
const transactionCommittedDetailsResponse = yield this.radixSpecificClient.gatewayClient.transaction.innerClient.transactionCommittedDetails({
|
|
688
|
-
transactionCommittedDetailsRequest: transactionCommittedDetailsRequest,
|
|
689
765
|
});
|
|
690
766
|
if (transactionCommittedDetailsResponse.transaction.raw_hex !== undefined &&
|
|
691
767
|
transactionCommittedDetailsResponse.transaction.confirmed_at !== null &&
|
package/lib/radix-client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RadixGatewayApi, TransactionSubmitResponse } from './gateway-api';
|
|
2
2
|
import { Intent, NotarizedTransaction, PublicKey, TransactionHash } from '@radixdlt/radix-engine-toolkit';
|
|
3
3
|
import { Balance, MethodToCall } from './types/radix';
|
|
4
4
|
/**
|
|
@@ -7,11 +7,11 @@ import { Balance, MethodToCall } from './types/radix';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare class RadixSpecificClient {
|
|
9
9
|
private innerNetwork;
|
|
10
|
-
private
|
|
10
|
+
private innerGateway;
|
|
11
11
|
constructor(networkId: number);
|
|
12
12
|
set networkId(networkId: number);
|
|
13
13
|
get networkId(): number;
|
|
14
|
-
get
|
|
14
|
+
get gateway(): RadixGatewayApi;
|
|
15
15
|
currentEpoch(): Promise<number>;
|
|
16
16
|
currentStateVersion(): Promise<number>;
|
|
17
17
|
fetchBalances(address: string): Promise<Balance[]>;
|
|
@@ -24,7 +24,6 @@ export declare class RadixSpecificClient {
|
|
|
24
24
|
fees: number;
|
|
25
25
|
}>;
|
|
26
26
|
submitTransaction(notarizedTransaction: NotarizedTransaction): Promise<[TransactionSubmitResponse, TransactionHash]>;
|
|
27
|
-
private static createGatewayClient;
|
|
28
27
|
private static createSimpleTransferManifest;
|
|
29
28
|
private static createCustomTransferManifest;
|
|
30
29
|
private constructIntent;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xchainjs/xchain-radix",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.12",
|
|
4
4
|
"description": "Custom Radix client and utilities used by XChainJS clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"XRD",
|
|
@@ -38,7 +38,6 @@
|
|
|
38
38
|
"directory": "release/package"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@radixdlt/babylon-gateway-api-sdk": "^1.4.1",
|
|
42
41
|
"@radixdlt/radix-engine-toolkit": "^1.0.3",
|
|
43
42
|
"@scure/base": "^1.2.6",
|
|
44
43
|
"@scure/bip32": "^1.7.0",
|