@rougechain/sdk 0.8.2 → 0.8.4
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 +123 -2
- package/dist/index.cjs +135 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +135 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
10
|
<strong>Build quantum-safe dApps on RougeChain</strong><br />
|
|
11
|
-
Transfers · DEX · NFTs · Shielded Transactions · Bridge · Rollups · Mail · Messenger
|
|
11
|
+
Transfers · DEX · NFTs · Shielded Transactions · Bridge · Rollups · Dynamic Fees · Finality Proofs · WebSocket · Mail · Messenger
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
@@ -64,6 +64,13 @@ const { balance } = await rc.getBalance(wallet.publicKey);
|
|
|
64
64
|
| **Rollup** | `rc` | zk-STARK batch proofs, rollup status, submit transfers |
|
|
65
65
|
| **Mail** | `rc.mail` | On-chain encrypted email (`@rouge.quant`) |
|
|
66
66
|
| **Messenger** | `rc.messenger` | E2E encrypted messaging with self-destruct |
|
|
67
|
+
| **Address Resolution** | `rc` | O(1) rouge1↔pubkey resolution via on-chain index |
|
|
68
|
+
| **Push Notifications** | `rc` | PQC-signed push token registration (Expo) |
|
|
69
|
+
| **Token Freeze** | `rc` | Creator-only token freeze/pause |
|
|
70
|
+
| **Mintable Tokens** | `rc` | Ongoing token minting with supply cap enforcement |
|
|
71
|
+
| **Dynamic Fees** | `rc` | EIP-1559 base fee, priority tips, fee burning |
|
|
72
|
+
| **Finality Proofs** | `rc` | BFT finality certificates with ≥2/3 validator stake |
|
|
73
|
+
| **WebSocket** | `rc` | Real-time event streaming with topic subscriptions |
|
|
67
74
|
|
|
68
75
|
## Wallet & Addresses
|
|
69
76
|
|
|
@@ -119,6 +126,56 @@ await rc.updateTokenMetadata(wallet, {
|
|
|
119
126
|
|
|
120
127
|
// Burn tokens
|
|
121
128
|
await rc.burn(wallet, 500);
|
|
129
|
+
|
|
130
|
+
// Create a mintable token with supply cap
|
|
131
|
+
await rc.createToken(wallet, {
|
|
132
|
+
name: "Inflation Token",
|
|
133
|
+
symbol: "INFT",
|
|
134
|
+
totalSupply: 100_000,
|
|
135
|
+
mintable: true,
|
|
136
|
+
maxSupply: 1_000_000,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// Mint additional tokens (creator only)
|
|
140
|
+
await rc.mintTokens(wallet, { symbol: "INFT", amount: 50_000 });
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Dynamic Fees (EIP-1559)
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Get current fee info — base fee adjusts per block
|
|
147
|
+
const fee = await rc.getFeeInfo();
|
|
148
|
+
console.log(`Base fee: ${fee.base_fee} XRGE`);
|
|
149
|
+
console.log(`Suggested total: ${fee.total_fee_suggestion} XRGE`);
|
|
150
|
+
console.log(`Total burned: ${fee.total_fees_burned} XRGE`);
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Finality Proofs
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// Get a BFT finality proof for a block height
|
|
157
|
+
const { proof } = await rc.getFinalityProof(42);
|
|
158
|
+
if (proof) {
|
|
159
|
+
console.log(`Block ${proof.height} finalized with ${proof.voting_stake}/${proof.total_stake} stake`);
|
|
160
|
+
console.log(`${proof.precommit_votes.length} precommit signatures`);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## WebSocket Subscriptions
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Subscribe to specific topics for real-time events
|
|
168
|
+
const ws = rc.connectWebSocket(["blocks", `account:${wallet.publicKey}`]);
|
|
169
|
+
|
|
170
|
+
ws.onmessage = (event) => {
|
|
171
|
+
const data = JSON.parse(event.data);
|
|
172
|
+
if (data.type === "new_block") {
|
|
173
|
+
console.log(`New block #${data.height}`);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
// Available topics: "blocks", "transactions", "stats",
|
|
178
|
+
// "account:<pubkey>", "token:<symbol>"
|
|
122
179
|
```
|
|
123
180
|
|
|
124
181
|
## DEX (`rc.dex`)
|
|
@@ -280,7 +337,37 @@ const batch = await rc.getRollupBatch(1);
|
|
|
280
337
|
|
|
281
338
|
## Mail (`rc.mail`)
|
|
282
339
|
|
|
283
|
-
On-chain encrypted email with `@rouge.quant` addresses.
|
|
340
|
+
On-chain encrypted email with `@rouge.quant` / `@qwalla.mail` addresses.
|
|
341
|
+
|
|
342
|
+
### Name Registry
|
|
343
|
+
|
|
344
|
+
Register a mail name so other users can send you encrypted email. Third-party apps (QWALLA, qRougee, etc.) should call these on wallet creation.
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
// Step 1: Register wallet on the node (required for encryption keys)
|
|
348
|
+
await rc.messenger.registerWallet({
|
|
349
|
+
id: wallet.publicKey,
|
|
350
|
+
displayName: "Alice",
|
|
351
|
+
signingPublicKey: wallet.publicKey,
|
|
352
|
+
encryptionPublicKey: encPubKey,
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Step 2: Register a mail name
|
|
356
|
+
await rc.mail.registerName("alice", wallet.publicKey);
|
|
357
|
+
|
|
358
|
+
// Resolve a name → wallet info (includes encryption key)
|
|
359
|
+
const resolved = await rc.mail.resolveName("alice");
|
|
360
|
+
// { entry: { name, wallet_id }, wallet: { id, signing_public_key, encryption_public_key } }
|
|
361
|
+
|
|
362
|
+
// Reverse lookup: wallet ID → name
|
|
363
|
+
const name = await rc.mail.reverseLookup(wallet.publicKey);
|
|
364
|
+
// "alice"
|
|
365
|
+
|
|
366
|
+
// Release a name
|
|
367
|
+
await rc.mail.releaseName("alice", wallet.publicKey);
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Sending & Reading Mail
|
|
284
371
|
|
|
285
372
|
```typescript
|
|
286
373
|
// Send an encrypted email
|
|
@@ -402,6 +489,39 @@ const signedTx = signTransaction(payload, wallet.privateKey, wallet.publicKey);
|
|
|
402
489
|
const valid = verifyTransaction(signedTx); // true
|
|
403
490
|
```
|
|
404
491
|
|
|
492
|
+
## Address Resolution
|
|
493
|
+
|
|
494
|
+
Resolve between compact `rouge1…` addresses and full hex public keys using the on-chain persistent index.
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
// rouge1… → public key
|
|
498
|
+
const { publicKey } = await rc.resolveAddress("rouge1q8f3x7k2m4...");
|
|
499
|
+
|
|
500
|
+
// public key → rouge1…
|
|
501
|
+
const { address } = await rc.resolveAddress(hexPubKey);
|
|
502
|
+
|
|
503
|
+
// Both return: { success, address, publicKey, balance }
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
## Push Notifications
|
|
507
|
+
|
|
508
|
+
Register Expo push tokens for real-time notifications. Requires PQC signature — only the wallet owner can register.
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
// Register (wallet signs the request with ML-DSA-65)
|
|
512
|
+
await rc.registerPushToken(wallet, expoPushToken);
|
|
513
|
+
|
|
514
|
+
// Unregister
|
|
515
|
+
await rc.unregisterPushToken(wallet);
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
## Nonce Management
|
|
519
|
+
|
|
520
|
+
```typescript
|
|
521
|
+
// Get sequential nonce for an account
|
|
522
|
+
const { nonce, next_nonce } = await rc.getNonce(wallet.publicKey);
|
|
523
|
+
```
|
|
524
|
+
|
|
405
525
|
## Environment Support
|
|
406
526
|
|
|
407
527
|
| Environment | Notes |
|
|
@@ -424,6 +544,7 @@ import type {
|
|
|
424
544
|
ShieldParams, ShieldedTransferParams, UnshieldParams, ShieldedStats,
|
|
425
545
|
ShieldedNote,
|
|
426
546
|
RollupStatus, RollupBatchResult, RollupSubmitParams, RollupSubmitResult,
|
|
547
|
+
FeeInfo, FinalityProof, MintTokenParams, VoteMessage, WsSubscribeMessage,
|
|
427
548
|
} from "@rougechain/sdk";
|
|
428
549
|
```
|
|
429
550
|
|
package/dist/index.cjs
CHANGED
|
@@ -468,6 +468,19 @@ var RougeChain = class {
|
|
|
468
468
|
async getFinality() {
|
|
469
469
|
return this.get("/finality");
|
|
470
470
|
}
|
|
471
|
+
// ===== EIP-1559 Fee Info =====
|
|
472
|
+
/** Get current EIP-1559 fee information including base fee and suggestions. */
|
|
473
|
+
async getFeeInfo() {
|
|
474
|
+
return this.get("/fee");
|
|
475
|
+
}
|
|
476
|
+
// ===== BFT Finality Proofs =====
|
|
477
|
+
/**
|
|
478
|
+
* Get a BFT finality proof for a specific block height.
|
|
479
|
+
* Returns the aggregated precommit votes that prove ≥2/3 validator stake agreed.
|
|
480
|
+
*/
|
|
481
|
+
async getFinalityProof(height) {
|
|
482
|
+
return this.get(`/finality/${height}`);
|
|
483
|
+
}
|
|
471
484
|
// ===== Peers =====
|
|
472
485
|
async getPeers() {
|
|
473
486
|
const data = await this.get("/peers");
|
|
@@ -553,6 +566,39 @@ var RougeChain = class {
|
|
|
553
566
|
const tx = createSignedTokenMetadataClaim(wallet, tokenSymbol);
|
|
554
567
|
return this.submitTx("/v2/token/metadata/claim", tx);
|
|
555
568
|
}
|
|
569
|
+
/**
|
|
570
|
+
* Mint additional tokens for a mintable token (creator only).
|
|
571
|
+
* The token must have been created with `mintable: true`.
|
|
572
|
+
*/
|
|
573
|
+
async mintTokens(wallet, params) {
|
|
574
|
+
return this.post("/v2/token/mint", {
|
|
575
|
+
public_key: wallet.publicKey,
|
|
576
|
+
symbol: params.symbol,
|
|
577
|
+
amount: params.amount,
|
|
578
|
+
fee: params.fee ?? 1,
|
|
579
|
+
signature: ""
|
|
580
|
+
// Will be signed server-side via PQC verification
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
// ===== WebSocket =====
|
|
584
|
+
/**
|
|
585
|
+
* Connect to the node's WebSocket and optionally subscribe to specific topics.
|
|
586
|
+
* Topics: "blocks", "transactions", "stats", "account:<pubkey>", "token:<symbol>"
|
|
587
|
+
*
|
|
588
|
+
* @example
|
|
589
|
+
* const ws = client.connectWebSocket(["blocks", "account:abc123"]);
|
|
590
|
+
* ws.onmessage = (e) => console.log(JSON.parse(e.data));
|
|
591
|
+
*/
|
|
592
|
+
connectWebSocket(topics) {
|
|
593
|
+
const wsUrl = this.baseUrl.replace(/^http/, "ws") + "/ws";
|
|
594
|
+
const ws = new WebSocket(wsUrl);
|
|
595
|
+
if (topics && topics.length > 0) {
|
|
596
|
+
ws.addEventListener("open", () => {
|
|
597
|
+
ws.send(JSON.stringify({ subscribe: topics }));
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
return ws;
|
|
601
|
+
}
|
|
556
602
|
// ===== Rollup =====
|
|
557
603
|
/** Get the current rollup accumulator status. */
|
|
558
604
|
async getRollupStatus() {
|
|
@@ -913,6 +959,56 @@ var MailClient = class {
|
|
|
913
959
|
constructor(rc) {
|
|
914
960
|
this.rc = rc;
|
|
915
961
|
}
|
|
962
|
+
// --- Name Registry ---
|
|
963
|
+
async registerName(name, walletId) {
|
|
964
|
+
try {
|
|
965
|
+
const data = await this.rc.post("/names/register", {
|
|
966
|
+
name,
|
|
967
|
+
walletId
|
|
968
|
+
});
|
|
969
|
+
return { success: data.success === true, error: data.error, data };
|
|
970
|
+
} catch (e) {
|
|
971
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
async resolveName(name) {
|
|
975
|
+
try {
|
|
976
|
+
const data = await this.rc.get(
|
|
977
|
+
`/names/resolve/${encodeURIComponent(name.toLowerCase())}`
|
|
978
|
+
);
|
|
979
|
+
if (!data.success) return null;
|
|
980
|
+
return { entry: data.entry, wallet: data.wallet };
|
|
981
|
+
} catch {
|
|
982
|
+
return null;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
async reverseLookup(walletId) {
|
|
986
|
+
try {
|
|
987
|
+
const data = await this.rc.get(
|
|
988
|
+
`/names/reverse/${encodeURIComponent(walletId)}`
|
|
989
|
+
);
|
|
990
|
+
return data.name || null;
|
|
991
|
+
} catch {
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
async releaseName(name, walletId) {
|
|
996
|
+
try {
|
|
997
|
+
const res = await this.rc.fetchFn(
|
|
998
|
+
`${this.rc.baseUrl}/names/release`,
|
|
999
|
+
{
|
|
1000
|
+
method: "DELETE",
|
|
1001
|
+
headers: { ...this.rc.headers, "Content-Type": "application/json" },
|
|
1002
|
+
body: JSON.stringify({ name, walletId })
|
|
1003
|
+
}
|
|
1004
|
+
);
|
|
1005
|
+
const data = await res.json();
|
|
1006
|
+
return { success: data.success === true, error: data.error };
|
|
1007
|
+
} catch (e) {
|
|
1008
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
// --- Mail ---
|
|
916
1012
|
async send(params) {
|
|
917
1013
|
try {
|
|
918
1014
|
const data = await this.rc.post("/mail/send", params);
|
|
@@ -1017,16 +1113,17 @@ var MessengerClient = class {
|
|
|
1017
1113
|
);
|
|
1018
1114
|
return data.messages ?? [];
|
|
1019
1115
|
}
|
|
1020
|
-
async sendMessage(conversationId,
|
|
1116
|
+
async sendMessage(conversationId, senderWalletId, encryptedContent, opts = {}) {
|
|
1021
1117
|
try {
|
|
1022
1118
|
const data = await this.rc.post("/messenger/messages", {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1119
|
+
conversationId,
|
|
1120
|
+
senderWalletId,
|
|
1121
|
+
encryptedContent,
|
|
1122
|
+
signature: opts.signature ?? "",
|
|
1123
|
+
messageType: opts.messageType ?? "text",
|
|
1124
|
+
selfDestruct: opts.selfDestruct ?? false,
|
|
1125
|
+
destructAfterSeconds: opts.destructAfterSeconds,
|
|
1126
|
+
spoiler: opts.spoiler ?? false
|
|
1030
1127
|
});
|
|
1031
1128
|
return { success: data.success === true, error: data.error, data };
|
|
1032
1129
|
} catch (e) {
|
|
@@ -1048,7 +1145,7 @@ var MessengerClient = class {
|
|
|
1048
1145
|
async markRead(messageId) {
|
|
1049
1146
|
try {
|
|
1050
1147
|
const data = await this.rc.post("/messenger/messages/read", {
|
|
1051
|
-
|
|
1148
|
+
messageId
|
|
1052
1149
|
});
|
|
1053
1150
|
return { success: data.success === true, error: data.error };
|
|
1054
1151
|
} catch (e) {
|
|
@@ -1112,6 +1209,33 @@ var ShieldedClient = class {
|
|
|
1112
1209
|
);
|
|
1113
1210
|
return this.rc.submitTx("/v2/shielded/unshield", tx);
|
|
1114
1211
|
}
|
|
1212
|
+
// ─── WASM Smart Contracts ──────────────────────────────────────────
|
|
1213
|
+
/** Deploy a WASM smart contract */
|
|
1214
|
+
async deployContract(params) {
|
|
1215
|
+
return this.rc.post("/v2/contract/deploy", params);
|
|
1216
|
+
}
|
|
1217
|
+
/** Call a WASM smart contract method (mutating) */
|
|
1218
|
+
async callContract(params) {
|
|
1219
|
+
return this.rc.post("/v2/contract/call", params);
|
|
1220
|
+
}
|
|
1221
|
+
/** Get contract metadata */
|
|
1222
|
+
async getContract(addr) {
|
|
1223
|
+
return this.rc.get(`/contract/${addr}`);
|
|
1224
|
+
}
|
|
1225
|
+
/** Read contract storage. Omit key for full state dump. */
|
|
1226
|
+
async getContractState(addr, key) {
|
|
1227
|
+
const q = key ? `?key=${encodeURIComponent(key)}` : "";
|
|
1228
|
+
return this.rc.get(`/contract/${addr}/state${q}`);
|
|
1229
|
+
}
|
|
1230
|
+
/** Get contract events */
|
|
1231
|
+
async getContractEvents(addr, limit) {
|
|
1232
|
+
const q = limit ? `?limit=${limit}` : "";
|
|
1233
|
+
return this.rc.get(`/contract/${addr}/events${q}`);
|
|
1234
|
+
}
|
|
1235
|
+
/** List all deployed contracts */
|
|
1236
|
+
async listContracts() {
|
|
1237
|
+
return this.rc.get("/contracts");
|
|
1238
|
+
}
|
|
1115
1239
|
};
|
|
1116
1240
|
|
|
1117
1241
|
// src/address.ts
|
|
@@ -1268,9 +1392,9 @@ var Wallet = class _Wallet {
|
|
|
1268
1392
|
/**
|
|
1269
1393
|
* Generate a new ML-DSA-65 keypair with a BIP-39 mnemonic.
|
|
1270
1394
|
* The mnemonic is stored on the wallet for backup/recovery.
|
|
1271
|
-
* @param strength
|
|
1395
|
+
* @param strength 256 = 24 words (default, post-quantum safe), 128 = 12 words
|
|
1272
1396
|
*/
|
|
1273
|
-
static generate(strength =
|
|
1397
|
+
static generate(strength = 256) {
|
|
1274
1398
|
const mnemonic = generateMnemonic(strength);
|
|
1275
1399
|
const { publicKey, secretKey } = keypairFromMnemonic(mnemonic);
|
|
1276
1400
|
return new _Wallet(publicKey, secretKey, mnemonic);
|