@rougechain/sdk 0.3.7 → 0.4.1

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 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 · Bridge · Mail · Messenger
11
+ Transfers · DEX · NFTs · Shielded Transactions · Bridge · Mail · Messenger
12
12
  </p>
13
13
 
14
14
  <p align="center">
@@ -58,7 +58,8 @@ const { balance } = await rc.getBalance(wallet.publicKey);
58
58
  | **Staking** | `rc` | Stake/unstake XRGE for validation |
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
- | **Bridge** | `rc.bridge` | ETH qETH, USDC ↔ qUSDC, XRGE bridge (Base Sepolia) |
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) |\r
62
63
  | **Mail** | `rc.mail` | On-chain encrypted email (`@rouge.quant`) |
63
64
  | **Messenger** | `rc.messenger` | E2E encrypted messaging with self-destruct |
64
65
 
@@ -306,6 +307,45 @@ const messages = await rc.messenger.getMessages(conversationId);
306
307
  await rc.messenger.deleteMessage(messageId);
307
308
  ```
308
309
 
310
+ ## Shielded Transactions (`rc.shielded`)
311
+
312
+ Private value transfers using zk-STARK proofs. Shield XRGE into private notes, transfer privately, and unshield back to public balance.
313
+
314
+ ```typescript
315
+ import { createShieldedNote, computeCommitment, computeNullifier } from "@rougechain/sdk";
316
+
317
+ // Shield 100 XRGE into a private note
318
+ const { note } = await rc.shielded.shield(wallet, { amount: 100 });
319
+ // ⚠️ Save `note` securely — losing it means losing the funds!
320
+ // note = { commitment, nullifier, value, randomness, ownerPubKey }
321
+
322
+ // Check pool stats
323
+ const stats = await rc.shielded.getStats();
324
+ // { commitment_count, nullifier_count, active_notes }
325
+
326
+ // Check if a nullifier has been spent
327
+ const { spent } = await rc.shielded.isNullifierSpent(note.nullifier);
328
+
329
+ // Private transfer (requires STARK proof from Rust prover)
330
+ await rc.shielded.transfer(wallet, {
331
+ nullifiers: [note.nullifier],
332
+ outputCommitments: [recipientCommitment],
333
+ proof: starkProofHex,
334
+ });
335
+
336
+ // Unshield back to public balance
337
+ await rc.shielded.unshield(wallet, {
338
+ nullifiers: [note.nullifier],
339
+ amount: 100,
340
+ proof: starkProofHex,
341
+ });
342
+
343
+ // Client-side crypto primitives
344
+ const randomness = generateRandomness();
345
+ const commitment = computeCommitment(100, wallet.publicKey, randomness);
346
+ const nullifier = computeNullifier(randomness, commitment);
347
+ ```
348
+
309
349
  ## Low-Level Signing
310
350
 
311
351
  For advanced use cases:
@@ -347,6 +387,8 @@ import type {
347
387
  NftToken, LiquidityPool, BalanceResponse, Validator,
348
388
  BridgeConfig, MailMessage, MessengerMessage, WalletKeys,
349
389
  PriceSnapshot, PoolEvent, PoolStats, SwapQuote,
390
+ ShieldParams, ShieldedTransferParams, UnshieldParams, ShieldedStats,
391
+ ShieldedNote,
350
392
  } from "@rougechain/sdk";
351
393
  ```
352
394
 
@@ -360,7 +402,7 @@ import type {
360
402
 
361
403
  - [Website](https://rougechain.io)
362
404
  - [Documentation](https://docs.rougechain.io)
363
- - [Chrome Extension](https://chromewebstore.google.com/detail/rougechain-wallet)
405
+ - [Chrome Extension](https://chromewebstore.google.com/detail/rougechain-wallet/ilkbgjgphhaolfdjkfefdfiifipmhakj)
364
406
  - [GitHub](https://github.com/cyberdreadx/quantum-vault)
365
407
 
366
408
  ## License
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var mlDsa_js = require('@noble/post-quantum/ml-dsa.js');
4
+ var sha2 = require('@noble/hashes/sha2');
4
5
 
5
6
  // src/signer.ts
6
7
 
@@ -228,6 +229,88 @@ function createSignedNftFreezeCollection(wallet, collectionId, frozen) {
228
229
  fee: 0.1
229
230
  });
230
231
  }
232
+ function createSignedShield(wallet, amount, commitment) {
233
+ return buildAndSign(wallet, {
234
+ type: "shield",
235
+ amount,
236
+ commitment
237
+ });
238
+ }
239
+ function createSignedShieldedTransfer(wallet, nullifiers, outputCommitments, proof, shieldedFee) {
240
+ return buildAndSign(wallet, {
241
+ type: "shielded_transfer",
242
+ nullifiers,
243
+ output_commitments: outputCommitments,
244
+ proof,
245
+ fee: shieldedFee ?? 0
246
+ });
247
+ }
248
+ function createSignedUnshield(wallet, nullifiers, amount, proof) {
249
+ return buildAndSign(wallet, {
250
+ type: "unshield",
251
+ nullifiers,
252
+ amount,
253
+ proof
254
+ });
255
+ }
256
+ var COMMITMENT_DOMAIN = new TextEncoder().encode("ROUGECHAIN_COMMITMENT_V1");
257
+ var NULLIFIER_DOMAIN = new TextEncoder().encode("ROUGECHAIN_NULLIFIER_V1");
258
+ function generateRandomness() {
259
+ const buf = new Uint8Array(32);
260
+ crypto.getRandomValues(buf);
261
+ return bytesToHex(buf);
262
+ }
263
+ function u64ToBytes(value) {
264
+ const buf = new Uint8Array(8);
265
+ const view = new DataView(buf.buffer);
266
+ view.setBigUint64(0, BigInt(value), false);
267
+ return buf;
268
+ }
269
+ function hexToU8(hex) {
270
+ const clean = hex.startsWith("0x") ? hex.slice(2) : hex;
271
+ const bytes = new Uint8Array(clean.length / 2);
272
+ for (let i = 0; i < bytes.length; i++) {
273
+ bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
274
+ }
275
+ return bytes;
276
+ }
277
+ function computeCommitment(value, ownerPubKey, randomness) {
278
+ const valueBytes = u64ToBytes(value);
279
+ const pubkeyBytes = hexToU8(ownerPubKey);
280
+ const randBytes = hexToU8(randomness);
281
+ const input = new Uint8Array(
282
+ COMMITMENT_DOMAIN.length + valueBytes.length + pubkeyBytes.length + randBytes.length
283
+ );
284
+ let offset = 0;
285
+ input.set(COMMITMENT_DOMAIN, offset);
286
+ offset += COMMITMENT_DOMAIN.length;
287
+ input.set(valueBytes, offset);
288
+ offset += valueBytes.length;
289
+ input.set(pubkeyBytes, offset);
290
+ offset += pubkeyBytes.length;
291
+ input.set(randBytes, offset);
292
+ return bytesToHex(sha2.sha256(input));
293
+ }
294
+ function computeNullifier(randomness, commitment) {
295
+ const randBytes = hexToU8(randomness);
296
+ const commitBytes = hexToU8(commitment);
297
+ const input = new Uint8Array(
298
+ NULLIFIER_DOMAIN.length + randBytes.length + commitBytes.length
299
+ );
300
+ let offset = 0;
301
+ input.set(NULLIFIER_DOMAIN, offset);
302
+ offset += NULLIFIER_DOMAIN.length;
303
+ input.set(randBytes, offset);
304
+ offset += randBytes.length;
305
+ input.set(commitBytes, offset);
306
+ return bytesToHex(sha2.sha256(input));
307
+ }
308
+ function createShieldedNote(value, ownerPubKey) {
309
+ const randomness = generateRandomness();
310
+ const commitment = computeCommitment(value, ownerPubKey, randomness);
311
+ const nullifier = computeNullifier(randomness, commitment);
312
+ return { commitment, nullifier, value, randomness, ownerPubKey };
313
+ }
231
314
 
232
315
  // src/client.ts
233
316
  var RougeChain = class {
@@ -243,6 +326,7 @@ var RougeChain = class {
243
326
  this.bridge = new BridgeClient(this);
244
327
  this.mail = new MailClient(this);
245
328
  this.messenger = new MessengerClient(this);
329
+ this.shielded = new ShieldedClient(this);
246
330
  }
247
331
  // ===== Internal helpers =====
248
332
  /** @internal */
@@ -898,6 +982,63 @@ var MessengerClient = class {
898
982
  }
899
983
  }
900
984
  };
985
+ var ShieldedClient = class {
986
+ constructor(rc) {
987
+ this.rc = rc;
988
+ }
989
+ // Queries
990
+ async getStats() {
991
+ return this.rc.get("/shielded/stats");
992
+ }
993
+ async isNullifierSpent(nullifierHex) {
994
+ return this.rc.get(
995
+ `/shielded/nullifier/${encodeURIComponent(nullifierHex)}`
996
+ );
997
+ }
998
+ // Write operations
999
+ /**
1000
+ * Shield public XRGE into a private note.
1001
+ * Creates the commitment client-side, submits to the chain.
1002
+ *
1003
+ * @returns The ShieldedNote (keep this locally — it's the only way to spend the note)
1004
+ */
1005
+ async shield(wallet, params) {
1006
+ const note = createShieldedNote(params.amount, wallet.publicKey);
1007
+ const tx = createSignedShield(wallet, params.amount, note.commitment);
1008
+ const result = await this.rc.submitTx("/v2/shielded/shield", tx);
1009
+ if (result.success) {
1010
+ return { ...result, note };
1011
+ }
1012
+ return result;
1013
+ }
1014
+ /**
1015
+ * Transfer between shielded notes (private → private).
1016
+ * Requires a pre-generated STARK proof.
1017
+ */
1018
+ async transfer(wallet, params) {
1019
+ const tx = createSignedShieldedTransfer(
1020
+ wallet,
1021
+ params.nullifiers,
1022
+ params.outputCommitments,
1023
+ params.proof,
1024
+ params.shieldedFee
1025
+ );
1026
+ return this.rc.submitTx("/v2/shielded/transfer", tx);
1027
+ }
1028
+ /**
1029
+ * Unshield a private note back to public XRGE.
1030
+ * Requires a STARK proof of note ownership.
1031
+ */
1032
+ async unshield(wallet, params) {
1033
+ const tx = createSignedUnshield(
1034
+ wallet,
1035
+ params.nullifiers,
1036
+ params.amount,
1037
+ params.proof
1038
+ );
1039
+ return this.rc.submitTx("/v2/shielded/unshield", tx);
1040
+ }
1041
+ };
901
1042
  var Wallet = class _Wallet {
902
1043
  constructor(publicKey, privateKey) {
903
1044
  this.publicKey = publicKey;
@@ -944,10 +1085,17 @@ exports.BURN_ADDRESS = BURN_ADDRESS;
944
1085
  exports.RougeChain = RougeChain;
945
1086
  exports.Wallet = Wallet;
946
1087
  exports.bytesToHex = bytesToHex;
1088
+ exports.computeCommitment = computeCommitment;
1089
+ exports.computeNullifier = computeNullifier;
1090
+ exports.createShieldedNote = createShieldedNote;
947
1091
  exports.createSignedBridgeWithdraw = createSignedBridgeWithdraw;
1092
+ exports.createSignedShield = createSignedShield;
1093
+ exports.createSignedShieldedTransfer = createSignedShieldedTransfer;
948
1094
  exports.createSignedTokenMetadataClaim = createSignedTokenMetadataClaim;
949
1095
  exports.createSignedTokenMetadataUpdate = createSignedTokenMetadataUpdate;
1096
+ exports.createSignedUnshield = createSignedUnshield;
950
1097
  exports.generateNonce = generateNonce;
1098
+ exports.generateRandomness = generateRandomness;
951
1099
  exports.hexToBytes = hexToBytes;
952
1100
  exports.isBurnAddress = isBurnAddress;
953
1101
  exports.serializePayload = serializePayload;