@adelos/sdk 0.1.11 → 0.1.13

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/dist/index.d.mts CHANGED
@@ -115,6 +115,12 @@ declare function generateStealthAddress(recipientMetaPk: Uint8Array): {
115
115
  sharedSecret: Uint8Array<ArrayBufferLike>;
116
116
  memo: string;
117
117
  };
118
+ /**
119
+ * Sign a message using a raw private SCALAR (not seed).
120
+ * Required because derived stealth keys are scalars, not seeds.
121
+ * Uses a random nonce for R, valid for Ed25519.
122
+ */
123
+ declare function signWithScalar(message: Uint8Array, scalarBytes: Uint8Array): Promise<Uint8Array>;
118
124
 
119
125
  /**
120
126
  * Adelos Indexer - Privacy-Preserving Transaction Scanner
@@ -180,4 +186,4 @@ declare class AdelosSDK {
180
186
  sendAndConfirm(signedTx: Transaction | VersionedTransaction): Promise<string>;
181
187
  }
182
188
 
183
- export { ADELOS_CONFIG, AdelosIndexer, type AdelosOptions, AdelosSDK, MEMO_PREFIX, MEMO_PROGRAM_ID, PROGRAM_ID, REGISTRY_SEED, RPC_URL, type RegistryAccount, type RegistryInfo, STEALTH_DOMAIN, type SolanaCluster, type StealthTransaction, type WithdrawableTransaction, bytesToHex, computeSharedSecret, computeSharedSecretAsRecipient, createIndexer, derivePublicKey, deriveRegistryPda, deriveStealthPubkey, generateEphemeralKeypair, generateStealthAddress, generateStealthMemo, getDiscriminator, hexToBytes, isValidMetaPubkey, parseStealthMemo, recoverStealthSecretKey };
189
+ export { ADELOS_CONFIG, AdelosIndexer, type AdelosOptions, AdelosSDK, MEMO_PREFIX, MEMO_PROGRAM_ID, PROGRAM_ID, REGISTRY_SEED, RPC_URL, type RegistryAccount, type RegistryInfo, STEALTH_DOMAIN, type SolanaCluster, type StealthTransaction, type WithdrawableTransaction, bytesToHex, computeSharedSecret, computeSharedSecretAsRecipient, createIndexer, derivePublicKey, deriveRegistryPda, deriveStealthPubkey, generateEphemeralKeypair, generateStealthAddress, generateStealthMemo, getDiscriminator, hexToBytes, isValidMetaPubkey, parseStealthMemo, recoverStealthSecretKey, signWithScalar };
package/dist/index.d.ts CHANGED
@@ -115,6 +115,12 @@ declare function generateStealthAddress(recipientMetaPk: Uint8Array): {
115
115
  sharedSecret: Uint8Array<ArrayBufferLike>;
116
116
  memo: string;
117
117
  };
118
+ /**
119
+ * Sign a message using a raw private SCALAR (not seed).
120
+ * Required because derived stealth keys are scalars, not seeds.
121
+ * Uses a random nonce for R, valid for Ed25519.
122
+ */
123
+ declare function signWithScalar(message: Uint8Array, scalarBytes: Uint8Array): Promise<Uint8Array>;
118
124
 
119
125
  /**
120
126
  * Adelos Indexer - Privacy-Preserving Transaction Scanner
@@ -180,4 +186,4 @@ declare class AdelosSDK {
180
186
  sendAndConfirm(signedTx: Transaction | VersionedTransaction): Promise<string>;
181
187
  }
182
188
 
183
- export { ADELOS_CONFIG, AdelosIndexer, type AdelosOptions, AdelosSDK, MEMO_PREFIX, MEMO_PROGRAM_ID, PROGRAM_ID, REGISTRY_SEED, RPC_URL, type RegistryAccount, type RegistryInfo, STEALTH_DOMAIN, type SolanaCluster, type StealthTransaction, type WithdrawableTransaction, bytesToHex, computeSharedSecret, computeSharedSecretAsRecipient, createIndexer, derivePublicKey, deriveRegistryPda, deriveStealthPubkey, generateEphemeralKeypair, generateStealthAddress, generateStealthMemo, getDiscriminator, hexToBytes, isValidMetaPubkey, parseStealthMemo, recoverStealthSecretKey };
189
+ export { ADELOS_CONFIG, AdelosIndexer, type AdelosOptions, AdelosSDK, MEMO_PREFIX, MEMO_PROGRAM_ID, PROGRAM_ID, REGISTRY_SEED, RPC_URL, type RegistryAccount, type RegistryInfo, STEALTH_DOMAIN, type SolanaCluster, type StealthTransaction, type WithdrawableTransaction, bytesToHex, computeSharedSecret, computeSharedSecretAsRecipient, createIndexer, derivePublicKey, deriveRegistryPda, deriveStealthPubkey, generateEphemeralKeypair, generateStealthAddress, generateStealthMemo, getDiscriminator, hexToBytes, isValidMetaPubkey, parseStealthMemo, recoverStealthSecretKey, signWithScalar };
package/dist/index.js CHANGED
@@ -53,7 +53,8 @@ __export(index_exports, {
53
53
  hexToBytes: () => hexToBytes,
54
54
  isValidMetaPubkey: () => isValidMetaPubkey,
55
55
  parseStealthMemo: () => parseStealthMemo,
56
- recoverStealthSecretKey: () => recoverStealthSecretKey
56
+ recoverStealthSecretKey: () => recoverStealthSecretKey,
57
+ signWithScalar: () => signWithScalar
57
58
  });
58
59
  module.exports = __toCommonJS(index_exports);
59
60
  var import_web33 = require("@solana/web3.js");
@@ -127,7 +128,8 @@ ed.etc.sha512Sync = (...m) => {
127
128
  var encoder = new TextEncoder();
128
129
  var toScalar = (bytes) => {
129
130
  const cleanBytes = bytes.length === 64 ? bytes.slice(0, 32) : bytes;
130
- return ed.etc.mod(BigInt("0x" + bytesToHex(cleanBytes)), ed.CURVE.n);
131
+ const reversed = Uint8Array.from(cleanBytes).reverse();
132
+ return ed.etc.mod(BigInt("0x" + bytesToHex(reversed)), ed.CURVE.n);
131
133
  };
132
134
  function generateEphemeralKeypair() {
133
135
  const secretKey = ed.utils.randomPrivateKey();
@@ -186,6 +188,29 @@ function generateStealthAddress(recipientMetaPk) {
186
188
  const memo = generateStealthMemo(ephemeralKeypair.publicKey);
187
189
  return { stealthPubkey, ephemeralKeypair, sharedSecret, memo };
188
190
  }
191
+ async function signWithScalar(message, scalarBytes) {
192
+ const scalar = toScalar(scalarBytes);
193
+ const pubPoint = ed.ExtendedPoint.BASE.multiply(scalar);
194
+ const pubBytes = pubPoint.toRawBytes();
195
+ const rBytes = ed.utils.randomPrivateKey();
196
+ const rScalar = toScalar(rBytes);
197
+ const R = ed.ExtendedPoint.BASE.multiply(rScalar);
198
+ const RBytes = R.toRawBytes();
199
+ const content = new Uint8Array(RBytes.length + pubBytes.length + message.length);
200
+ content.set(RBytes);
201
+ content.set(pubBytes, RBytes.length);
202
+ content.set(message, RBytes.length + pubBytes.length);
203
+ const hram = (0, import_sha512.sha512)(content);
204
+ const hramReversed = Uint8Array.from(hram).reverse();
205
+ const k = ed.etc.mod(BigInt("0x" + bytesToHex(hramReversed)), ed.CURVE.n);
206
+ const S = ed.etc.mod(rScalar + k * scalar, ed.CURVE.n);
207
+ const sHexPadded = S.toString(16).padStart(64, "0");
208
+ const SBytes = hexToBytes(sHexPadded).reverse();
209
+ const signature = new Uint8Array(64);
210
+ signature.set(RBytes);
211
+ signature.set(SBytes, 32);
212
+ return signature;
213
+ }
189
214
 
190
215
  // src/logger.ts
191
216
  var debugMode = false;
@@ -396,11 +421,6 @@ var AdelosSDK = class {
396
421
  * @param amountLamports - Amount to withdraw in lamports (use BigInt)
397
422
  */
398
423
  async createWithdrawTransaction(stealthSecretKey, stealthAddress, destination, amountLamports) {
399
- const { Keypair } = await import("@solana/web3.js");
400
- const stealthKeypair = Keypair.fromSeed(stealthSecretKey);
401
- if (!stealthKeypair.publicKey.equals(stealthAddress)) {
402
- throw new Error("Stealth secret key does not match stealth address");
403
- }
404
424
  const ix = import_web33.SystemProgram.transfer({
405
425
  fromPubkey: stealthAddress,
406
426
  toPubkey: destination,
@@ -414,7 +434,9 @@ var AdelosSDK = class {
414
434
  instructions: [ix]
415
435
  }).compileToV0Message();
416
436
  const tx = new import_web33.VersionedTransaction(message);
417
- tx.sign([stealthKeypair]);
437
+ const serializedMessage = message.serialize();
438
+ const signature = await signWithScalar(serializedMessage, stealthSecretKey);
439
+ tx.addSignature(stealthAddress, Buffer.from(signature));
418
440
  const sig = await this.connection.sendRawTransaction(tx.serialize());
419
441
  await this.connection.confirmTransaction(sig, "confirmed");
420
442
  return { transaction: tx, signature: sig };
@@ -468,5 +490,6 @@ var AdelosSDK = class {
468
490
  hexToBytes,
469
491
  isValidMetaPubkey,
470
492
  parseStealthMemo,
471
- recoverStealthSecretKey
493
+ recoverStealthSecretKey,
494
+ signWithScalar
472
495
  });
package/dist/index.mjs CHANGED
@@ -78,7 +78,8 @@ ed.etc.sha512Sync = (...m) => {
78
78
  var encoder = new TextEncoder();
79
79
  var toScalar = (bytes) => {
80
80
  const cleanBytes = bytes.length === 64 ? bytes.slice(0, 32) : bytes;
81
- return ed.etc.mod(BigInt("0x" + bytesToHex(cleanBytes)), ed.CURVE.n);
81
+ const reversed = Uint8Array.from(cleanBytes).reverse();
82
+ return ed.etc.mod(BigInt("0x" + bytesToHex(reversed)), ed.CURVE.n);
82
83
  };
83
84
  function generateEphemeralKeypair() {
84
85
  const secretKey = ed.utils.randomPrivateKey();
@@ -137,6 +138,29 @@ function generateStealthAddress(recipientMetaPk) {
137
138
  const memo = generateStealthMemo(ephemeralKeypair.publicKey);
138
139
  return { stealthPubkey, ephemeralKeypair, sharedSecret, memo };
139
140
  }
141
+ async function signWithScalar(message, scalarBytes) {
142
+ const scalar = toScalar(scalarBytes);
143
+ const pubPoint = ed.ExtendedPoint.BASE.multiply(scalar);
144
+ const pubBytes = pubPoint.toRawBytes();
145
+ const rBytes = ed.utils.randomPrivateKey();
146
+ const rScalar = toScalar(rBytes);
147
+ const R = ed.ExtendedPoint.BASE.multiply(rScalar);
148
+ const RBytes = R.toRawBytes();
149
+ const content = new Uint8Array(RBytes.length + pubBytes.length + message.length);
150
+ content.set(RBytes);
151
+ content.set(pubBytes, RBytes.length);
152
+ content.set(message, RBytes.length + pubBytes.length);
153
+ const hram = sha512(content);
154
+ const hramReversed = Uint8Array.from(hram).reverse();
155
+ const k = ed.etc.mod(BigInt("0x" + bytesToHex(hramReversed)), ed.CURVE.n);
156
+ const S = ed.etc.mod(rScalar + k * scalar, ed.CURVE.n);
157
+ const sHexPadded = S.toString(16).padStart(64, "0");
158
+ const SBytes = hexToBytes(sHexPadded).reverse();
159
+ const signature = new Uint8Array(64);
160
+ signature.set(RBytes);
161
+ signature.set(SBytes, 32);
162
+ return signature;
163
+ }
140
164
 
141
165
  // src/logger.ts
142
166
  var debugMode = false;
@@ -347,11 +371,6 @@ var AdelosSDK = class {
347
371
  * @param amountLamports - Amount to withdraw in lamports (use BigInt)
348
372
  */
349
373
  async createWithdrawTransaction(stealthSecretKey, stealthAddress, destination, amountLamports) {
350
- const { Keypair } = await import("@solana/web3.js");
351
- const stealthKeypair = Keypair.fromSeed(stealthSecretKey);
352
- if (!stealthKeypair.publicKey.equals(stealthAddress)) {
353
- throw new Error("Stealth secret key does not match stealth address");
354
- }
355
374
  const ix = SystemProgram.transfer({
356
375
  fromPubkey: stealthAddress,
357
376
  toPubkey: destination,
@@ -365,7 +384,9 @@ var AdelosSDK = class {
365
384
  instructions: [ix]
366
385
  }).compileToV0Message();
367
386
  const tx = new VersionedTransaction(message);
368
- tx.sign([stealthKeypair]);
387
+ const serializedMessage = message.serialize();
388
+ const signature = await signWithScalar(serializedMessage, stealthSecretKey);
389
+ tx.addSignature(stealthAddress, Buffer.from(signature));
369
390
  const sig = await this.connection.sendRawTransaction(tx.serialize());
370
391
  await this.connection.confirmTransaction(sig, "confirmed");
371
392
  return { transaction: tx, signature: sig };
@@ -418,5 +439,6 @@ export {
418
439
  hexToBytes,
419
440
  isValidMetaPubkey,
420
441
  parseStealthMemo,
421
- recoverStealthSecretKey
442
+ recoverStealthSecretKey,
443
+ signWithScalar
422
444
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adelos/sdk",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Adelos Protocol SDK - Privacy Stealth Transfers on Solana",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",