@rougechain/sdk 0.1.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.
- package/README.md +334 -0
- package/dist/index.cjs +664 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +441 -0
- package/dist/index.d.ts +441 -0
- package/dist/index.js +653 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
import { ml_dsa65 } from '@noble/post-quantum/ml-dsa.js';
|
|
2
|
+
|
|
3
|
+
// src/signer.ts
|
|
4
|
+
|
|
5
|
+
// src/utils.ts
|
|
6
|
+
function hexToBytes(hex) {
|
|
7
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
8
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
9
|
+
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
10
|
+
}
|
|
11
|
+
return bytes;
|
|
12
|
+
}
|
|
13
|
+
function bytesToHex(bytes) {
|
|
14
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
15
|
+
}
|
|
16
|
+
function generateNonce() {
|
|
17
|
+
const bytes = crypto.getRandomValues(new Uint8Array(16));
|
|
18
|
+
return bytesToHex(bytes);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/signer.ts
|
|
22
|
+
var BURN_ADDRESS = "XRGE_BURN_0x000000000000000000000000000000000000000000000000000000000000DEAD";
|
|
23
|
+
function serializePayload(payload) {
|
|
24
|
+
const json = JSON.stringify(payload, Object.keys(payload).sort());
|
|
25
|
+
return new TextEncoder().encode(json);
|
|
26
|
+
}
|
|
27
|
+
function signTransaction(payload, privateKey, publicKey) {
|
|
28
|
+
const payloadBytes = serializePayload(payload);
|
|
29
|
+
const signature = ml_dsa65.sign(payloadBytes, hexToBytes(privateKey));
|
|
30
|
+
return {
|
|
31
|
+
payload,
|
|
32
|
+
signature: bytesToHex(signature),
|
|
33
|
+
public_key: publicKey
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function verifyTransaction(signedTx) {
|
|
37
|
+
try {
|
|
38
|
+
const payloadBytes = serializePayload(signedTx.payload);
|
|
39
|
+
return ml_dsa65.verify(
|
|
40
|
+
hexToBytes(signedTx.signature),
|
|
41
|
+
payloadBytes,
|
|
42
|
+
hexToBytes(signedTx.public_key)
|
|
43
|
+
);
|
|
44
|
+
} catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function isBurnAddress(address) {
|
|
49
|
+
return address === BURN_ADDRESS;
|
|
50
|
+
}
|
|
51
|
+
function buildAndSign(wallet, payload) {
|
|
52
|
+
const full = {
|
|
53
|
+
...payload,
|
|
54
|
+
from: wallet.publicKey,
|
|
55
|
+
timestamp: Date.now(),
|
|
56
|
+
nonce: generateNonce()
|
|
57
|
+
};
|
|
58
|
+
return signTransaction(full, wallet.privateKey, wallet.publicKey);
|
|
59
|
+
}
|
|
60
|
+
function createSignedTransfer(wallet, to, amount, fee = 1, token = "XRGE") {
|
|
61
|
+
return buildAndSign(wallet, { type: "transfer", to, amount, fee, token });
|
|
62
|
+
}
|
|
63
|
+
function createSignedTokenCreation(wallet, tokenName, tokenSymbol, initialSupply, fee = 10) {
|
|
64
|
+
return buildAndSign(wallet, {
|
|
65
|
+
type: "create_token",
|
|
66
|
+
token_name: tokenName,
|
|
67
|
+
token_symbol: tokenSymbol,
|
|
68
|
+
initial_supply: initialSupply,
|
|
69
|
+
fee
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function createSignedSwap(wallet, tokenIn, tokenOut, amountIn, minAmountOut) {
|
|
73
|
+
return buildAndSign(wallet, {
|
|
74
|
+
type: "swap",
|
|
75
|
+
token_in: tokenIn,
|
|
76
|
+
token_out: tokenOut,
|
|
77
|
+
amount_in: amountIn,
|
|
78
|
+
min_amount_out: minAmountOut
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function createSignedPoolCreation(wallet, tokenA, tokenB, amountA, amountB) {
|
|
82
|
+
return buildAndSign(wallet, {
|
|
83
|
+
type: "create_pool",
|
|
84
|
+
token_a: tokenA,
|
|
85
|
+
token_b: tokenB,
|
|
86
|
+
amount_a: amountA,
|
|
87
|
+
amount_b: amountB
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
function createSignedAddLiquidity(wallet, poolId, amountA, amountB) {
|
|
91
|
+
return buildAndSign(wallet, {
|
|
92
|
+
type: "add_liquidity",
|
|
93
|
+
pool_id: poolId,
|
|
94
|
+
amount_a: amountA,
|
|
95
|
+
amount_b: amountB
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function createSignedRemoveLiquidity(wallet, poolId, lpAmount) {
|
|
99
|
+
return buildAndSign(wallet, {
|
|
100
|
+
type: "remove_liquidity",
|
|
101
|
+
pool_id: poolId,
|
|
102
|
+
lp_amount: lpAmount
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
function createSignedStake(wallet, amount, fee = 1) {
|
|
106
|
+
return buildAndSign(wallet, { type: "stake", amount, fee });
|
|
107
|
+
}
|
|
108
|
+
function createSignedUnstake(wallet, amount, fee = 1) {
|
|
109
|
+
return buildAndSign(wallet, { type: "unstake", amount, fee });
|
|
110
|
+
}
|
|
111
|
+
function createSignedFaucetRequest(wallet) {
|
|
112
|
+
return buildAndSign(wallet, { type: "faucet" });
|
|
113
|
+
}
|
|
114
|
+
function createSignedBurn(wallet, amount, fee = 1, token = "XRGE") {
|
|
115
|
+
return buildAndSign(wallet, {
|
|
116
|
+
type: "transfer",
|
|
117
|
+
to: BURN_ADDRESS,
|
|
118
|
+
amount,
|
|
119
|
+
fee,
|
|
120
|
+
token
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function createSignedNftCreateCollection(wallet, symbol, name, opts = {}) {
|
|
124
|
+
return buildAndSign(wallet, {
|
|
125
|
+
type: "nft_create_collection",
|
|
126
|
+
symbol,
|
|
127
|
+
name,
|
|
128
|
+
fee: 50,
|
|
129
|
+
maxSupply: opts.maxSupply,
|
|
130
|
+
royaltyBps: opts.royaltyBps,
|
|
131
|
+
image: opts.image,
|
|
132
|
+
description: opts.description
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
function createSignedNftMint(wallet, collectionId, name, opts = {}) {
|
|
136
|
+
return buildAndSign(wallet, {
|
|
137
|
+
type: "nft_mint",
|
|
138
|
+
collectionId,
|
|
139
|
+
name,
|
|
140
|
+
fee: 5,
|
|
141
|
+
metadataUri: opts.metadataUri,
|
|
142
|
+
attributes: opts.attributes
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function createSignedNftBatchMint(wallet, collectionId, names, opts = {}) {
|
|
146
|
+
return buildAndSign(wallet, {
|
|
147
|
+
type: "nft_batch_mint",
|
|
148
|
+
collectionId,
|
|
149
|
+
names,
|
|
150
|
+
fee: 5 * names.length,
|
|
151
|
+
uris: opts.uris,
|
|
152
|
+
batchAttributes: opts.batchAttributes
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function createSignedNftTransfer(wallet, collectionId, tokenId, to, salePrice) {
|
|
156
|
+
return buildAndSign(wallet, {
|
|
157
|
+
type: "nft_transfer",
|
|
158
|
+
collectionId,
|
|
159
|
+
tokenId,
|
|
160
|
+
to,
|
|
161
|
+
fee: 1,
|
|
162
|
+
salePrice
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
function createSignedNftBurn(wallet, collectionId, tokenId) {
|
|
166
|
+
return buildAndSign(wallet, {
|
|
167
|
+
type: "nft_burn",
|
|
168
|
+
collectionId,
|
|
169
|
+
tokenId,
|
|
170
|
+
fee: 0.1
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function createSignedNftLock(wallet, collectionId, tokenId, locked) {
|
|
174
|
+
return buildAndSign(wallet, {
|
|
175
|
+
type: "nft_lock",
|
|
176
|
+
collectionId,
|
|
177
|
+
tokenId,
|
|
178
|
+
locked,
|
|
179
|
+
fee: 0.1
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
function createSignedNftFreezeCollection(wallet, collectionId, frozen) {
|
|
183
|
+
return buildAndSign(wallet, {
|
|
184
|
+
type: "nft_freeze_collection",
|
|
185
|
+
collectionId,
|
|
186
|
+
frozen,
|
|
187
|
+
fee: 0.1
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/client.ts
|
|
192
|
+
var RougeChain = class {
|
|
193
|
+
constructor(baseUrl, options = {}) {
|
|
194
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
195
|
+
this.fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
196
|
+
this.headers = { "Content-Type": "application/json" };
|
|
197
|
+
if (options.apiKey) {
|
|
198
|
+
this.headers["X-API-Key"] = options.apiKey;
|
|
199
|
+
}
|
|
200
|
+
this.nft = new NftClient(this);
|
|
201
|
+
this.dex = new DexClient(this);
|
|
202
|
+
this.bridge = new BridgeClient(this);
|
|
203
|
+
}
|
|
204
|
+
// ===== Internal helpers =====
|
|
205
|
+
/** @internal */
|
|
206
|
+
async get(path) {
|
|
207
|
+
const res = await this.fetchFn(`${this.baseUrl}${path}`, {
|
|
208
|
+
headers: this.headers
|
|
209
|
+
});
|
|
210
|
+
if (!res.ok) {
|
|
211
|
+
throw new Error(`GET ${path} failed: ${res.status} ${res.statusText}`);
|
|
212
|
+
}
|
|
213
|
+
return res.json();
|
|
214
|
+
}
|
|
215
|
+
/** @internal */
|
|
216
|
+
async post(path, body) {
|
|
217
|
+
const res = await this.fetchFn(`${this.baseUrl}${path}`, {
|
|
218
|
+
method: "POST",
|
|
219
|
+
headers: this.headers,
|
|
220
|
+
body: JSON.stringify(body)
|
|
221
|
+
});
|
|
222
|
+
if (!res.ok) {
|
|
223
|
+
const text = await res.text().catch(() => "");
|
|
224
|
+
throw new Error(
|
|
225
|
+
`POST ${path} failed: ${res.status} ${res.statusText} ${text}`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
return res.json();
|
|
229
|
+
}
|
|
230
|
+
/** @internal */
|
|
231
|
+
async submitTx(endpoint, signedTx) {
|
|
232
|
+
try {
|
|
233
|
+
const raw = await this.post(endpoint, signedTx);
|
|
234
|
+
const { success, error, ...rest } = raw;
|
|
235
|
+
return {
|
|
236
|
+
success,
|
|
237
|
+
error,
|
|
238
|
+
data: Object.keys(rest).length > 0 ? rest : void 0
|
|
239
|
+
};
|
|
240
|
+
} catch (e) {
|
|
241
|
+
return {
|
|
242
|
+
success: false,
|
|
243
|
+
error: e instanceof Error ? e.message : String(e)
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// ===== Stats & Health =====
|
|
248
|
+
async getStats() {
|
|
249
|
+
return this.get("/stats");
|
|
250
|
+
}
|
|
251
|
+
async getHealth() {
|
|
252
|
+
return this.get("/health");
|
|
253
|
+
}
|
|
254
|
+
// ===== Blocks =====
|
|
255
|
+
async getBlocks(opts = {}) {
|
|
256
|
+
const q = opts.limit ? `?limit=${opts.limit}` : "";
|
|
257
|
+
const data = await this.get(`/blocks${q}`);
|
|
258
|
+
return data.blocks;
|
|
259
|
+
}
|
|
260
|
+
async getBlocksSummary(range = "24h") {
|
|
261
|
+
return this.get(`/blocks/summary?range=${range}`);
|
|
262
|
+
}
|
|
263
|
+
// ===== Balance =====
|
|
264
|
+
async getBalance(publicKey) {
|
|
265
|
+
return this.get(`/balance/${publicKey}`);
|
|
266
|
+
}
|
|
267
|
+
async getTokenBalance(publicKey, token) {
|
|
268
|
+
const data = await this.get(
|
|
269
|
+
`/balance/${publicKey}/${token}`
|
|
270
|
+
);
|
|
271
|
+
return data.balance;
|
|
272
|
+
}
|
|
273
|
+
// ===== Transactions =====
|
|
274
|
+
async getTransactions(opts = {}) {
|
|
275
|
+
const params = new URLSearchParams();
|
|
276
|
+
if (opts.limit) params.set("limit", String(opts.limit));
|
|
277
|
+
if (opts.offset) params.set("offset", String(opts.offset));
|
|
278
|
+
const q = params.toString();
|
|
279
|
+
return this.get(`/txs${q ? `?${q}` : ""}`);
|
|
280
|
+
}
|
|
281
|
+
// ===== Tokens =====
|
|
282
|
+
async getTokens() {
|
|
283
|
+
const data = await this.get(
|
|
284
|
+
"/tokens"
|
|
285
|
+
);
|
|
286
|
+
return data.tokens;
|
|
287
|
+
}
|
|
288
|
+
async getTokenMetadata(symbol) {
|
|
289
|
+
return this.get(`/token/${symbol}/metadata`);
|
|
290
|
+
}
|
|
291
|
+
async getTokenHolders(symbol) {
|
|
292
|
+
const data = await this.get(
|
|
293
|
+
`/token/${symbol}/holders`
|
|
294
|
+
);
|
|
295
|
+
return data.holders;
|
|
296
|
+
}
|
|
297
|
+
async getTokenTransactions(symbol) {
|
|
298
|
+
return this.get(`/token/${symbol}/transactions`);
|
|
299
|
+
}
|
|
300
|
+
// ===== Validators =====
|
|
301
|
+
async getValidators() {
|
|
302
|
+
const data = await this.get("/validators");
|
|
303
|
+
return data.validators;
|
|
304
|
+
}
|
|
305
|
+
async getValidatorStats() {
|
|
306
|
+
return this.get("/validators/stats");
|
|
307
|
+
}
|
|
308
|
+
async getFinality() {
|
|
309
|
+
return this.get("/finality");
|
|
310
|
+
}
|
|
311
|
+
// ===== Peers =====
|
|
312
|
+
async getPeers() {
|
|
313
|
+
const data = await this.get("/peers");
|
|
314
|
+
return data.peers;
|
|
315
|
+
}
|
|
316
|
+
// ===== Burned =====
|
|
317
|
+
async getBurnedTokens() {
|
|
318
|
+
return this.get("/burned");
|
|
319
|
+
}
|
|
320
|
+
// ===== Write operations =====
|
|
321
|
+
async transfer(wallet, params) {
|
|
322
|
+
const tx = createSignedTransfer(
|
|
323
|
+
wallet,
|
|
324
|
+
params.to,
|
|
325
|
+
params.amount,
|
|
326
|
+
params.fee,
|
|
327
|
+
params.token
|
|
328
|
+
);
|
|
329
|
+
return this.submitTx("/v2/transfer", tx);
|
|
330
|
+
}
|
|
331
|
+
async createToken(wallet, params) {
|
|
332
|
+
const tx = createSignedTokenCreation(
|
|
333
|
+
wallet,
|
|
334
|
+
params.name,
|
|
335
|
+
params.symbol,
|
|
336
|
+
params.totalSupply,
|
|
337
|
+
params.fee
|
|
338
|
+
);
|
|
339
|
+
return this.submitTx("/v2/token/create", tx);
|
|
340
|
+
}
|
|
341
|
+
async stake(wallet, params) {
|
|
342
|
+
const tx = createSignedStake(wallet, params.amount, params.fee);
|
|
343
|
+
return this.submitTx("/v2/stake", tx);
|
|
344
|
+
}
|
|
345
|
+
async unstake(wallet, params) {
|
|
346
|
+
const tx = createSignedUnstake(wallet, params.amount, params.fee);
|
|
347
|
+
return this.submitTx("/v2/unstake", tx);
|
|
348
|
+
}
|
|
349
|
+
async faucet(wallet) {
|
|
350
|
+
const tx = createSignedFaucetRequest(wallet);
|
|
351
|
+
return this.submitTx("/v2/faucet", tx);
|
|
352
|
+
}
|
|
353
|
+
async burn(wallet, amount, fee = 1, token = "XRGE") {
|
|
354
|
+
const tx = createSignedBurn(wallet, amount, fee, token);
|
|
355
|
+
return this.submitTx("/v2/transfer", tx);
|
|
356
|
+
}
|
|
357
|
+
async updateTokenMetadata(wallet, params) {
|
|
358
|
+
try {
|
|
359
|
+
const data = await this.post("/token/metadata/update", {
|
|
360
|
+
token_symbol: params.symbol,
|
|
361
|
+
from_public_key: wallet.publicKey,
|
|
362
|
+
from_private_key: wallet.privateKey,
|
|
363
|
+
image: params.image,
|
|
364
|
+
description: params.description,
|
|
365
|
+
website: params.website,
|
|
366
|
+
twitter: params.twitter,
|
|
367
|
+
discord: params.discord
|
|
368
|
+
});
|
|
369
|
+
return data;
|
|
370
|
+
} catch (e) {
|
|
371
|
+
return {
|
|
372
|
+
success: false,
|
|
373
|
+
error: e instanceof Error ? e.message : String(e)
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
var NftClient = class {
|
|
379
|
+
constructor(rc) {
|
|
380
|
+
this.rc = rc;
|
|
381
|
+
}
|
|
382
|
+
// Queries
|
|
383
|
+
async getCollections() {
|
|
384
|
+
const data = await this.rc.get(
|
|
385
|
+
"/nft/collections"
|
|
386
|
+
);
|
|
387
|
+
return data.collections;
|
|
388
|
+
}
|
|
389
|
+
async getCollection(collectionId) {
|
|
390
|
+
return this.rc.get(
|
|
391
|
+
`/nft/collection/${encodeURIComponent(collectionId)}`
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
async getTokens(collectionId, opts = {}) {
|
|
395
|
+
const params = new URLSearchParams();
|
|
396
|
+
if (opts.limit !== void 0) params.set("limit", String(opts.limit));
|
|
397
|
+
if (opts.offset !== void 0) params.set("offset", String(opts.offset));
|
|
398
|
+
const q = params.toString();
|
|
399
|
+
return this.rc.get(
|
|
400
|
+
`/nft/collection/${encodeURIComponent(collectionId)}/tokens${q ? `?${q}` : ""}`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
async getToken(collectionId, tokenId) {
|
|
404
|
+
return this.rc.get(
|
|
405
|
+
`/nft/token/${encodeURIComponent(collectionId)}/${tokenId}`
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
async getByOwner(pubkey) {
|
|
409
|
+
const data = await this.rc.get(
|
|
410
|
+
`/nft/owner/${encodeURIComponent(pubkey)}`
|
|
411
|
+
);
|
|
412
|
+
return data.nfts;
|
|
413
|
+
}
|
|
414
|
+
// Write operations
|
|
415
|
+
async createCollection(wallet, params) {
|
|
416
|
+
const tx = createSignedNftCreateCollection(wallet, params.symbol, params.name, {
|
|
417
|
+
maxSupply: params.maxSupply,
|
|
418
|
+
royaltyBps: params.royaltyBps,
|
|
419
|
+
image: params.image,
|
|
420
|
+
description: params.description
|
|
421
|
+
});
|
|
422
|
+
return this.rc.submitTx("/v2/nft/collection/create", tx);
|
|
423
|
+
}
|
|
424
|
+
async mint(wallet, params) {
|
|
425
|
+
const tx = createSignedNftMint(wallet, params.collectionId, params.name, {
|
|
426
|
+
metadataUri: params.metadataUri,
|
|
427
|
+
attributes: params.attributes
|
|
428
|
+
});
|
|
429
|
+
return this.rc.submitTx("/v2/nft/mint", tx);
|
|
430
|
+
}
|
|
431
|
+
async batchMint(wallet, params) {
|
|
432
|
+
const tx = createSignedNftBatchMint(
|
|
433
|
+
wallet,
|
|
434
|
+
params.collectionId,
|
|
435
|
+
params.names,
|
|
436
|
+
{ uris: params.uris, batchAttributes: params.batchAttributes }
|
|
437
|
+
);
|
|
438
|
+
return this.rc.submitTx("/v2/nft/batch-mint", tx);
|
|
439
|
+
}
|
|
440
|
+
async transfer(wallet, params) {
|
|
441
|
+
const tx = createSignedNftTransfer(
|
|
442
|
+
wallet,
|
|
443
|
+
params.collectionId,
|
|
444
|
+
params.tokenId,
|
|
445
|
+
params.to,
|
|
446
|
+
params.salePrice
|
|
447
|
+
);
|
|
448
|
+
return this.rc.submitTx("/v2/nft/transfer", tx);
|
|
449
|
+
}
|
|
450
|
+
async burn(wallet, params) {
|
|
451
|
+
const tx = createSignedNftBurn(wallet, params.collectionId, params.tokenId);
|
|
452
|
+
return this.rc.submitTx("/v2/nft/burn", tx);
|
|
453
|
+
}
|
|
454
|
+
async lock(wallet, params) {
|
|
455
|
+
const tx = createSignedNftLock(
|
|
456
|
+
wallet,
|
|
457
|
+
params.collectionId,
|
|
458
|
+
params.tokenId,
|
|
459
|
+
params.locked
|
|
460
|
+
);
|
|
461
|
+
return this.rc.submitTx("/v2/nft/lock", tx);
|
|
462
|
+
}
|
|
463
|
+
async freezeCollection(wallet, params) {
|
|
464
|
+
const tx = createSignedNftFreezeCollection(
|
|
465
|
+
wallet,
|
|
466
|
+
params.collectionId,
|
|
467
|
+
params.frozen
|
|
468
|
+
);
|
|
469
|
+
return this.rc.submitTx("/v2/nft/freeze-collection", tx);
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
var DexClient = class {
|
|
473
|
+
constructor(rc) {
|
|
474
|
+
this.rc = rc;
|
|
475
|
+
}
|
|
476
|
+
// Queries
|
|
477
|
+
async getPools() {
|
|
478
|
+
const data = await this.rc.get("/pools");
|
|
479
|
+
return data.pools;
|
|
480
|
+
}
|
|
481
|
+
async getPool(poolId) {
|
|
482
|
+
return this.rc.get(`/pool/${poolId}`);
|
|
483
|
+
}
|
|
484
|
+
async getPoolEvents(poolId) {
|
|
485
|
+
const data = await this.rc.get(
|
|
486
|
+
`/pool/${poolId}/events`
|
|
487
|
+
);
|
|
488
|
+
return data.events;
|
|
489
|
+
}
|
|
490
|
+
async getPoolPrices(poolId) {
|
|
491
|
+
return this.rc.get(`/pool/${poolId}/prices`);
|
|
492
|
+
}
|
|
493
|
+
async getPoolStats(poolId) {
|
|
494
|
+
return this.rc.get(`/pool/${poolId}/stats`);
|
|
495
|
+
}
|
|
496
|
+
async quote(params) {
|
|
497
|
+
return this.rc.post("/swap/quote", {
|
|
498
|
+
pool_id: params.poolId,
|
|
499
|
+
token_in: params.tokenIn,
|
|
500
|
+
amount_in: params.amountIn
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
// Write operations
|
|
504
|
+
async swap(wallet, params) {
|
|
505
|
+
const tx = createSignedSwap(
|
|
506
|
+
wallet,
|
|
507
|
+
params.tokenIn,
|
|
508
|
+
params.tokenOut,
|
|
509
|
+
params.amountIn,
|
|
510
|
+
params.minAmountOut
|
|
511
|
+
);
|
|
512
|
+
return this.rc.submitTx("/v2/swap/execute", tx);
|
|
513
|
+
}
|
|
514
|
+
async createPool(wallet, params) {
|
|
515
|
+
const tx = createSignedPoolCreation(
|
|
516
|
+
wallet,
|
|
517
|
+
params.tokenA,
|
|
518
|
+
params.tokenB,
|
|
519
|
+
params.amountA,
|
|
520
|
+
params.amountB
|
|
521
|
+
);
|
|
522
|
+
return this.rc.submitTx("/v2/pool/create", tx);
|
|
523
|
+
}
|
|
524
|
+
async addLiquidity(wallet, params) {
|
|
525
|
+
const tx = createSignedAddLiquidity(
|
|
526
|
+
wallet,
|
|
527
|
+
params.poolId,
|
|
528
|
+
params.amountA,
|
|
529
|
+
params.amountB
|
|
530
|
+
);
|
|
531
|
+
return this.rc.submitTx("/v2/pool/add-liquidity", tx);
|
|
532
|
+
}
|
|
533
|
+
async removeLiquidity(wallet, params) {
|
|
534
|
+
const tx = createSignedRemoveLiquidity(wallet, params.poolId, params.lpAmount);
|
|
535
|
+
return this.rc.submitTx("/v2/pool/remove-liquidity", tx);
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
var BridgeClient = class {
|
|
539
|
+
constructor(rc) {
|
|
540
|
+
this.rc = rc;
|
|
541
|
+
}
|
|
542
|
+
async getConfig() {
|
|
543
|
+
try {
|
|
544
|
+
const data = await this.rc.get("/bridge/config");
|
|
545
|
+
return {
|
|
546
|
+
enabled: data.enabled === true,
|
|
547
|
+
custodyAddress: data.custodyAddress,
|
|
548
|
+
chainId: data.chainId ?? 84532
|
|
549
|
+
};
|
|
550
|
+
} catch {
|
|
551
|
+
return { enabled: false, chainId: 84532 };
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
async getWithdrawals() {
|
|
555
|
+
const data = await this.rc.get(
|
|
556
|
+
"/bridge/withdrawals"
|
|
557
|
+
);
|
|
558
|
+
return data.withdrawals;
|
|
559
|
+
}
|
|
560
|
+
async withdraw(wallet, params) {
|
|
561
|
+
try {
|
|
562
|
+
const evm = params.evmAddress.startsWith("0x") ? params.evmAddress : `0x${params.evmAddress}`;
|
|
563
|
+
const data = await this.rc.post(
|
|
564
|
+
"/bridge/withdraw",
|
|
565
|
+
{
|
|
566
|
+
fromPrivateKey: wallet.privateKey,
|
|
567
|
+
fromPublicKey: wallet.publicKey,
|
|
568
|
+
amountUnits: params.amount,
|
|
569
|
+
evmAddress: evm,
|
|
570
|
+
fee: params.fee
|
|
571
|
+
}
|
|
572
|
+
);
|
|
573
|
+
return {
|
|
574
|
+
success: data.success === true,
|
|
575
|
+
error: data.error,
|
|
576
|
+
data
|
|
577
|
+
};
|
|
578
|
+
} catch (e) {
|
|
579
|
+
return {
|
|
580
|
+
success: false,
|
|
581
|
+
error: e instanceof Error ? e.message : String(e)
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
async claim(params) {
|
|
586
|
+
try {
|
|
587
|
+
const data = await this.rc.post(
|
|
588
|
+
"/bridge/claim",
|
|
589
|
+
{
|
|
590
|
+
evmTxHash: params.evmTxHash.startsWith("0x") ? params.evmTxHash : `0x${params.evmTxHash}`,
|
|
591
|
+
evmAddress: params.evmAddress.startsWith("0x") ? params.evmAddress : `0x${params.evmAddress}`,
|
|
592
|
+
evmSignature: params.evmSignature,
|
|
593
|
+
recipientRougechainPubkey: params.recipientPubkey
|
|
594
|
+
}
|
|
595
|
+
);
|
|
596
|
+
return {
|
|
597
|
+
success: data.success === true,
|
|
598
|
+
error: data.error,
|
|
599
|
+
data
|
|
600
|
+
};
|
|
601
|
+
} catch (e) {
|
|
602
|
+
return {
|
|
603
|
+
success: false,
|
|
604
|
+
error: e instanceof Error ? e.message : String(e)
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
var Wallet = class _Wallet {
|
|
610
|
+
constructor(publicKey, privateKey) {
|
|
611
|
+
this.publicKey = publicKey;
|
|
612
|
+
this.privateKey = privateKey;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Generate a new ML-DSA-65 keypair.
|
|
616
|
+
* Uses crypto.getRandomValues for secure randomness.
|
|
617
|
+
*/
|
|
618
|
+
static generate() {
|
|
619
|
+
const keypair = ml_dsa65.keygen();
|
|
620
|
+
return new _Wallet(
|
|
621
|
+
bytesToHex(keypair.publicKey),
|
|
622
|
+
bytesToHex(keypair.secretKey)
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Restore a wallet from existing hex-encoded keys.
|
|
627
|
+
*/
|
|
628
|
+
static fromKeys(publicKey, privateKey) {
|
|
629
|
+
return new _Wallet(publicKey, privateKey);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Export keys as a plain object (for serialization/storage).
|
|
633
|
+
*/
|
|
634
|
+
toJSON() {
|
|
635
|
+
return { publicKey: this.publicKey, privateKey: this.privateKey };
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Verify that the keypair is valid by signing and verifying a test message.
|
|
639
|
+
*/
|
|
640
|
+
verify() {
|
|
641
|
+
try {
|
|
642
|
+
const msg = new TextEncoder().encode("rougechain-verify");
|
|
643
|
+
const sig = ml_dsa65.sign(msg, hexToBytes(this.privateKey));
|
|
644
|
+
return ml_dsa65.verify(sig, msg, hexToBytes(this.publicKey));
|
|
645
|
+
} catch {
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
|
|
651
|
+
export { BURN_ADDRESS, RougeChain, Wallet, bytesToHex, generateNonce, hexToBytes, isBurnAddress, serializePayload, signTransaction, verifyTransaction };
|
|
652
|
+
//# sourceMappingURL=index.js.map
|
|
653
|
+
//# sourceMappingURL=index.js.map
|