@rougechain/sdk 0.4.1 → 0.6.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 +40 -6
- package/dist/index.cjs +152 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +765 -0
- package/dist/index.d.ts +765 -0
- package/dist/index.js +149 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
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 · Mail · Messenger
|
|
11
|
+
Transfers · DEX · NFTs · Shielded Transactions · Bridge · Rollups · Mail · Messenger
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
15
|
<a href="https://www.npmjs.com/package/@rougechain/sdk"><img src="https://img.shields.io/npm/v/@rougechain/sdk?color=00d2be&label=npm" alt="npm version" /></a>
|
|
16
16
|
<a href="https://www.npmjs.com/package/@rougechain/sdk"><img src="https://img.shields.io/npm/dm/@rougechain/sdk?color=00d2be" alt="npm downloads" /></a>
|
|
17
|
-
<a href="https://github.com/cyberdreadx/
|
|
17
|
+
<a href="https://github.com/cyberdreadx/rougechain-node/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license" /></a>
|
|
18
18
|
<a href="https://docs.rougechain.io"><img src="https://img.shields.io/badge/docs-rougechain-00d2be" alt="docs" /></a>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
@@ -59,18 +59,23 @@ const { balance } = await rc.getBalance(wallet.publicKey);
|
|
|
59
59
|
| **DEX** | `rc.dex` | AMM pools, swaps with slippage protection, liquidity |
|
|
60
60
|
| **NFTs** | `rc.nft` | RC-721 collections, mint, batch mint, royalties, freeze |
|
|
61
61
|
| **Shielded** | `rc.shielded` | Private transfers with zk-STARK proofs, shield/unshield XRGE |
|
|
62
|
-
| **Bridge** | `rc.bridge` | ETH ↔ qETH, USDC ↔ qUSDC, XRGE bridge (Base Sepolia)
|
|
62
|
+
| **Bridge** | `rc.bridge` | ETH ↔ qETH, USDC ↔ qUSDC, XRGE bridge (Base Mainnet/Sepolia) |
|
|
63
|
+
| **Rollup** | `rc` | zk-STARK batch proofs, rollup status, submit transfers |
|
|
63
64
|
| **Mail** | `rc.mail` | On-chain encrypted email (`@rouge.quant`) |
|
|
64
65
|
| **Messenger** | `rc.messenger` | E2E encrypted messaging with self-destruct |
|
|
65
66
|
|
|
66
|
-
## Wallet
|
|
67
|
+
## Wallet & Addresses
|
|
67
68
|
|
|
68
69
|
```typescript
|
|
69
|
-
import { Wallet } from "@rougechain/sdk";
|
|
70
|
+
import { Wallet, pubkeyToAddress, isRougeAddress, formatAddress } from "@rougechain/sdk";
|
|
70
71
|
|
|
71
72
|
// Generate a new post-quantum keypair
|
|
72
73
|
const wallet = Wallet.generate();
|
|
73
74
|
|
|
75
|
+
// Get the compact rouge1... address (~63 chars vs 3904-char hex pubkey)
|
|
76
|
+
const address = await wallet.address();
|
|
77
|
+
// "rouge1q8f3x7k2m4n9p..."
|
|
78
|
+
|
|
74
79
|
// Restore from saved keys
|
|
75
80
|
const restored = Wallet.fromKeys(publicKey, privateKey);
|
|
76
81
|
|
|
@@ -79,6 +84,11 @@ const keys = wallet.toJSON(); // { publicKey, privateKey }
|
|
|
79
84
|
|
|
80
85
|
// Verify keypair integrity
|
|
81
86
|
wallet.verify(); // true
|
|
87
|
+
|
|
88
|
+
// Address utilities
|
|
89
|
+
const addr = await pubkeyToAddress(someHexPubKey);
|
|
90
|
+
const display = formatAddress(addr); // "rouge1q8f3x7...k9m2"
|
|
91
|
+
isRougeAddress("rouge1q8f3x7k2m4..."); // true
|
|
82
92
|
```
|
|
83
93
|
|
|
84
94
|
## Transfers & Tokens
|
|
@@ -244,6 +254,29 @@ await rc.bridge.withdrawXrge(wallet, {
|
|
|
244
254
|
});
|
|
245
255
|
```
|
|
246
256
|
|
|
257
|
+
## Rollup (zk-STARK Batch Proofs)
|
|
258
|
+
|
|
259
|
+
Submit transfers to the rollup accumulator for batched STARK proving. Transfers are collected into batches of up to 32 and proven with a single zk-STARK proof.
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// Check rollup status
|
|
263
|
+
const status = await rc.getRollupStatus();
|
|
264
|
+
// { pending_transfers, completed_batches, current_state_root, ... }
|
|
265
|
+
|
|
266
|
+
// Submit a transfer to the rollup batch
|
|
267
|
+
const result = await rc.submitRollupTransfer({
|
|
268
|
+
sender: wallet.publicKey,
|
|
269
|
+
receiver: recipientPubKey,
|
|
270
|
+
amount: 100,
|
|
271
|
+
fee: 1,
|
|
272
|
+
});
|
|
273
|
+
// result.queued = true (waiting for batch) or result.batch_completed = true
|
|
274
|
+
|
|
275
|
+
// Get a completed batch result
|
|
276
|
+
const batch = await rc.getRollupBatch(1);
|
|
277
|
+
// { batch_id, transfer_count, proof_size_bytes, proof_time_ms, verified, ... }
|
|
278
|
+
```
|
|
279
|
+
|
|
247
280
|
## Mail (`rc.mail`)
|
|
248
281
|
|
|
249
282
|
On-chain encrypted email with `@rouge.quant` addresses.
|
|
@@ -389,6 +422,7 @@ import type {
|
|
|
389
422
|
PriceSnapshot, PoolEvent, PoolStats, SwapQuote,
|
|
390
423
|
ShieldParams, ShieldedTransferParams, UnshieldParams, ShieldedStats,
|
|
391
424
|
ShieldedNote,
|
|
425
|
+
RollupStatus, RollupBatchResult, RollupSubmitParams, RollupSubmitResult,
|
|
392
426
|
} from "@rougechain/sdk";
|
|
393
427
|
```
|
|
394
428
|
|
|
@@ -403,7 +437,7 @@ import type {
|
|
|
403
437
|
- [Website](https://rougechain.io)
|
|
404
438
|
- [Documentation](https://docs.rougechain.io)
|
|
405
439
|
- [Chrome Extension](https://chromewebstore.google.com/detail/rougechain-wallet/ilkbgjgphhaolfdjkfefdfiifipmhakj)
|
|
406
|
-
- [GitHub](https://github.com/cyberdreadx/
|
|
440
|
+
- [GitHub](https://github.com/cyberdreadx/rougechain-node)
|
|
407
441
|
|
|
408
442
|
## License
|
|
409
443
|
|
package/dist/index.cjs
CHANGED
|
@@ -496,6 +496,23 @@ var RougeChain = class {
|
|
|
496
496
|
const tx = createSignedTokenMetadataClaim(wallet, tokenSymbol);
|
|
497
497
|
return this.submitTx("/v2/token/metadata/claim", tx);
|
|
498
498
|
}
|
|
499
|
+
// ===== Rollup =====
|
|
500
|
+
/** Get the current rollup accumulator status. */
|
|
501
|
+
async getRollupStatus() {
|
|
502
|
+
const data = await this.get("/v2/rollup/status");
|
|
503
|
+
return data.rollup;
|
|
504
|
+
}
|
|
505
|
+
/** Submit a transfer into the rollup batch accumulator. */
|
|
506
|
+
async submitRollupTransfer(params) {
|
|
507
|
+
return this.post("/v2/rollup/submit", params);
|
|
508
|
+
}
|
|
509
|
+
/** Get the result of a completed rollup batch by ID. */
|
|
510
|
+
async getRollupBatch(batchId) {
|
|
511
|
+
const data = await this.get(
|
|
512
|
+
`/v2/rollup/batch/${batchId}`
|
|
513
|
+
);
|
|
514
|
+
return data.batch;
|
|
515
|
+
}
|
|
499
516
|
};
|
|
500
517
|
var NftClient = class {
|
|
501
518
|
constructor(rc) {
|
|
@@ -1039,6 +1056,130 @@ var ShieldedClient = class {
|
|
|
1039
1056
|
return this.rc.submitTx("/v2/shielded/unshield", tx);
|
|
1040
1057
|
}
|
|
1041
1058
|
};
|
|
1059
|
+
|
|
1060
|
+
// src/address.ts
|
|
1061
|
+
var CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
|
|
1062
|
+
var BECH32M_CONST = 734539939;
|
|
1063
|
+
var HRP = "rouge";
|
|
1064
|
+
function hrpExpand(hrp) {
|
|
1065
|
+
const ret = [];
|
|
1066
|
+
for (let i = 0; i < hrp.length; i++) ret.push(hrp.charCodeAt(i) >> 5);
|
|
1067
|
+
ret.push(0);
|
|
1068
|
+
for (let i = 0; i < hrp.length; i++) ret.push(hrp.charCodeAt(i) & 31);
|
|
1069
|
+
return ret;
|
|
1070
|
+
}
|
|
1071
|
+
function polymod(values) {
|
|
1072
|
+
const GEN = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
1073
|
+
let chk = 1;
|
|
1074
|
+
for (const v of values) {
|
|
1075
|
+
const b = chk >> 25;
|
|
1076
|
+
chk = (chk & 33554431) << 5 ^ v;
|
|
1077
|
+
for (let i = 0; i < 5; i++) {
|
|
1078
|
+
if (b >> i & 1) chk ^= GEN[i];
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return chk;
|
|
1082
|
+
}
|
|
1083
|
+
function createChecksum(hrp, data) {
|
|
1084
|
+
const values = hrpExpand(hrp).concat(data).concat([0, 0, 0, 0, 0, 0]);
|
|
1085
|
+
const pm = polymod(values) ^ BECH32M_CONST;
|
|
1086
|
+
const ret = [];
|
|
1087
|
+
for (let i = 0; i < 6; i++) ret.push(pm >> 5 * (5 - i) & 31);
|
|
1088
|
+
return ret;
|
|
1089
|
+
}
|
|
1090
|
+
function verifyChecksum(hrp, data) {
|
|
1091
|
+
return polymod(hrpExpand(hrp).concat(data)) === BECH32M_CONST;
|
|
1092
|
+
}
|
|
1093
|
+
function convertBits(data, fromBits, toBits, pad) {
|
|
1094
|
+
let acc = 0;
|
|
1095
|
+
let bits = 0;
|
|
1096
|
+
const ret = [];
|
|
1097
|
+
const maxv = (1 << toBits) - 1;
|
|
1098
|
+
for (const value of data) {
|
|
1099
|
+
acc = acc << fromBits | value;
|
|
1100
|
+
bits += fromBits;
|
|
1101
|
+
while (bits >= toBits) {
|
|
1102
|
+
bits -= toBits;
|
|
1103
|
+
ret.push(acc >> bits & maxv);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
{
|
|
1107
|
+
if (bits > 0) ret.push(acc << toBits - bits & maxv);
|
|
1108
|
+
}
|
|
1109
|
+
return ret;
|
|
1110
|
+
}
|
|
1111
|
+
function bech32mEncode(hrp, data) {
|
|
1112
|
+
const data5bit = convertBits(data, 8, 5);
|
|
1113
|
+
const checksum = createChecksum(hrp, data5bit);
|
|
1114
|
+
const combined = data5bit.concat(checksum);
|
|
1115
|
+
let result = hrp + "1";
|
|
1116
|
+
for (const d of combined) result += CHARSET[d];
|
|
1117
|
+
return result;
|
|
1118
|
+
}
|
|
1119
|
+
function bech32mDecode(str) {
|
|
1120
|
+
const lower = str.toLowerCase();
|
|
1121
|
+
const pos = lower.lastIndexOf("1");
|
|
1122
|
+
if (pos < 1 || pos + 7 > lower.length) throw new Error("Invalid bech32m string");
|
|
1123
|
+
const hrp = lower.slice(0, pos);
|
|
1124
|
+
const data5bit = [];
|
|
1125
|
+
for (let i = pos + 1; i < lower.length; i++) {
|
|
1126
|
+
const d = CHARSET.indexOf(lower[i]);
|
|
1127
|
+
if (d === -1) throw new Error(`Invalid character: ${lower[i]}`);
|
|
1128
|
+
data5bit.push(d);
|
|
1129
|
+
}
|
|
1130
|
+
if (!verifyChecksum(hrp, data5bit)) throw new Error("Invalid bech32m checksum");
|
|
1131
|
+
const payload = data5bit.slice(0, data5bit.length - 6);
|
|
1132
|
+
const ret = [];
|
|
1133
|
+
let acc = 0, bits = 0;
|
|
1134
|
+
for (const value of payload) {
|
|
1135
|
+
acc = acc << 5 | value;
|
|
1136
|
+
bits += 5;
|
|
1137
|
+
while (bits >= 8) {
|
|
1138
|
+
bits -= 8;
|
|
1139
|
+
ret.push(acc >> bits & 255);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
return { hrp, data: new Uint8Array(ret) };
|
|
1143
|
+
}
|
|
1144
|
+
function hexToBytes2(hex) {
|
|
1145
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
1146
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
1147
|
+
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
|
|
1148
|
+
}
|
|
1149
|
+
return bytes;
|
|
1150
|
+
}
|
|
1151
|
+
function bytesToHex2(bytes) {
|
|
1152
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1153
|
+
}
|
|
1154
|
+
async function sha2562(data) {
|
|
1155
|
+
const buf = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
1156
|
+
const hash = await crypto.subtle.digest("SHA-256", buf);
|
|
1157
|
+
return new Uint8Array(hash);
|
|
1158
|
+
}
|
|
1159
|
+
async function pubkeyToAddress(publicKeyHex) {
|
|
1160
|
+
const pkBytes = hexToBytes2(publicKeyHex);
|
|
1161
|
+
const hash = await sha2562(pkBytes);
|
|
1162
|
+
return bech32mEncode(HRP, hash);
|
|
1163
|
+
}
|
|
1164
|
+
function addressToHash(address) {
|
|
1165
|
+
const { data } = bech32mDecode(address);
|
|
1166
|
+
return bytesToHex2(data);
|
|
1167
|
+
}
|
|
1168
|
+
function isRougeAddress(input) {
|
|
1169
|
+
if (!input.toLowerCase().startsWith("rouge1") || input.length < 10) return false;
|
|
1170
|
+
try {
|
|
1171
|
+
bech32mDecode(input);
|
|
1172
|
+
return true;
|
|
1173
|
+
} catch {
|
|
1174
|
+
return false;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
function formatAddress(address, prefixLen = 12, suffixLen = 4) {
|
|
1178
|
+
if (address.length <= prefixLen + suffixLen + 3) return address;
|
|
1179
|
+
return `${address.slice(0, prefixLen)}...${address.slice(-suffixLen)}`;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
// src/wallet.ts
|
|
1042
1183
|
var Wallet = class _Wallet {
|
|
1043
1184
|
constructor(publicKey, privateKey) {
|
|
1044
1185
|
this.publicKey = publicKey;
|
|
@@ -1067,6 +1208,13 @@ var Wallet = class _Wallet {
|
|
|
1067
1208
|
toJSON() {
|
|
1068
1209
|
return { publicKey: this.publicKey, privateKey: this.privateKey };
|
|
1069
1210
|
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Derive the compact Bech32m address from the public key.
|
|
1213
|
+
* Returns a ~63-character `rouge1...` string.
|
|
1214
|
+
*/
|
|
1215
|
+
async address() {
|
|
1216
|
+
return pubkeyToAddress(this.publicKey);
|
|
1217
|
+
}
|
|
1070
1218
|
/**
|
|
1071
1219
|
* Verify that the keypair is valid by signing and verifying a test message.
|
|
1072
1220
|
*/
|
|
@@ -1084,6 +1232,7 @@ var Wallet = class _Wallet {
|
|
|
1084
1232
|
exports.BURN_ADDRESS = BURN_ADDRESS;
|
|
1085
1233
|
exports.RougeChain = RougeChain;
|
|
1086
1234
|
exports.Wallet = Wallet;
|
|
1235
|
+
exports.addressToHash = addressToHash;
|
|
1087
1236
|
exports.bytesToHex = bytesToHex;
|
|
1088
1237
|
exports.computeCommitment = computeCommitment;
|
|
1089
1238
|
exports.computeNullifier = computeNullifier;
|
|
@@ -1094,10 +1243,13 @@ exports.createSignedShieldedTransfer = createSignedShieldedTransfer;
|
|
|
1094
1243
|
exports.createSignedTokenMetadataClaim = createSignedTokenMetadataClaim;
|
|
1095
1244
|
exports.createSignedTokenMetadataUpdate = createSignedTokenMetadataUpdate;
|
|
1096
1245
|
exports.createSignedUnshield = createSignedUnshield;
|
|
1246
|
+
exports.formatAddress = formatAddress;
|
|
1097
1247
|
exports.generateNonce = generateNonce;
|
|
1098
1248
|
exports.generateRandomness = generateRandomness;
|
|
1099
1249
|
exports.hexToBytes = hexToBytes;
|
|
1100
1250
|
exports.isBurnAddress = isBurnAddress;
|
|
1251
|
+
exports.isRougeAddress = isRougeAddress;
|
|
1252
|
+
exports.pubkeyToAddress = pubkeyToAddress;
|
|
1101
1253
|
exports.serializePayload = serializePayload;
|
|
1102
1254
|
exports.signTransaction = signTransaction;
|
|
1103
1255
|
exports.verifyTransaction = verifyTransaction;
|