@adelos/sdk 0.1.5 → 0.1.7

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.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/index.ts
2
2
  import {
3
- Connection as Connection2,
4
- PublicKey as PublicKey4,
3
+ Connection,
4
+ PublicKey as PublicKey3,
5
5
  SystemProgram,
6
6
  Transaction,
7
7
  TransactionInstruction,
@@ -17,7 +17,8 @@ var ADELOS_CONFIG = {
17
17
  MEMO_PROGRAM_ID: new PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),
18
18
  REGISTRY_SEED: "registry",
19
19
  MEMO_PREFIX: "ADLSv1:",
20
- STEALTH_DOMAIN: "adelos:stealth:v1"
20
+ STEALTH_DOMAIN: "adelos:stealth:v1",
21
+ UNLOCK_MESSAGE: "Adelos Protocol: Unlock Privacy Identity\n\nThis will derive your unique privacy key for stealth addresses. This does not cost gas."
21
22
  };
22
23
  var PROGRAM_ID = ADELOS_CONFIG.PROGRAM_ID;
23
24
  var RPC_URL = ADELOS_CONFIG.RPC_URL;
@@ -62,244 +63,8 @@ function getDiscriminator(instructionName) {
62
63
  return disc;
63
64
  }
64
65
 
65
- // src/idl.ts
66
- var IDL = {
67
- "address": "7T1UxHJ6psKiQheKZXxANu6mhgsmgaX55eNKZZL5u4Rp",
68
- "metadata": {
69
- "name": "adelos_registry",
70
- "version": "0.1.0",
71
- "spec": "0.1.0",
72
- "description": "Privacy Registry for Adelos Protocol"
73
- },
74
- "instructions": [
75
- {
76
- "name": "close_registry",
77
- "discriminator": [
78
- 76,
79
- 32,
80
- 154,
81
- 180,
82
- 51,
83
- 159,
84
- 218,
85
- 102
86
- ],
87
- "accounts": [
88
- {
89
- "name": "owner",
90
- "writable": true,
91
- "signer": true,
92
- "relations": [
93
- "registry"
94
- ]
95
- },
96
- {
97
- "name": "registry",
98
- "writable": true,
99
- "pda": {
100
- "seeds": [
101
- {
102
- "kind": "const",
103
- "value": [
104
- 114,
105
- 101,
106
- 103,
107
- 105,
108
- 115,
109
- 116,
110
- 114,
111
- 121
112
- ]
113
- },
114
- {
115
- "kind": "account",
116
- "path": "owner"
117
- }
118
- ]
119
- }
120
- }
121
- ],
122
- "args": []
123
- },
124
- {
125
- "name": "register_identity",
126
- "discriminator": [
127
- 164,
128
- 118,
129
- 227,
130
- 177,
131
- 47,
132
- 176,
133
- 187,
134
- 248
135
- ],
136
- "accounts": [
137
- {
138
- "name": "owner",
139
- "writable": true,
140
- "signer": true
141
- },
142
- {
143
- "name": "registry",
144
- "writable": true,
145
- "pda": {
146
- "seeds": [
147
- {
148
- "kind": "const",
149
- "value": [
150
- 114,
151
- 101,
152
- 103,
153
- 105,
154
- 115,
155
- 116,
156
- 114,
157
- 121
158
- ]
159
- },
160
- {
161
- "kind": "account",
162
- "path": "owner"
163
- }
164
- ]
165
- }
166
- },
167
- {
168
- "name": "system_program",
169
- "address": "11111111111111111111111111111111"
170
- }
171
- ],
172
- "args": [
173
- {
174
- "name": "meta_pubkey",
175
- "type": {
176
- "array": [
177
- "u8",
178
- 32
179
- ]
180
- }
181
- }
182
- ]
183
- },
184
- {
185
- "name": "update_identity",
186
- "discriminator": [
187
- 130,
188
- 54,
189
- 88,
190
- 104,
191
- 222,
192
- 124,
193
- 238,
194
- 252
195
- ],
196
- "accounts": [
197
- {
198
- "name": "owner",
199
- "writable": true,
200
- "signer": true,
201
- "relations": [
202
- "registry"
203
- ]
204
- },
205
- {
206
- "name": "registry",
207
- "writable": true,
208
- "pda": {
209
- "seeds": [
210
- {
211
- "kind": "const",
212
- "value": [
213
- 114,
214
- 101,
215
- 103,
216
- 105,
217
- 115,
218
- 116,
219
- 114,
220
- 121
221
- ]
222
- },
223
- {
224
- "kind": "account",
225
- "path": "owner"
226
- }
227
- ]
228
- }
229
- },
230
- {
231
- "name": "system_program",
232
- "address": "11111111111111111111111111111111"
233
- }
234
- ],
235
- "args": [
236
- {
237
- "name": "new_meta_pubkey",
238
- "type": {
239
- "array": [
240
- "u8",
241
- 32
242
- ]
243
- }
244
- }
245
- ]
246
- }
247
- ],
248
- "accounts": [
249
- {
250
- "name": "RegistryAccount",
251
- "discriminator": [
252
- 113,
253
- 93,
254
- 106,
255
- 201,
256
- 100,
257
- 166,
258
- 146,
259
- 98
260
- ]
261
- }
262
- ],
263
- "errors": [
264
- {
265
- "code": 6e3,
266
- "name": "InvalidMetaPubkey",
267
- "msg": "Invalid meta_pubkey"
268
- },
269
- {
270
- "code": 6001,
271
- "name": "Unauthorized",
272
- "msg": "Unauthorized"
273
- }
274
- ],
275
- "types": [
276
- {
277
- "name": "RegistryAccount",
278
- "type": {
279
- "kind": "struct",
280
- "fields": [
281
- {
282
- "name": "owner",
283
- "type": "pubkey"
284
- },
285
- {
286
- "name": "meta_pubkey",
287
- "type": {
288
- "array": [
289
- "u8",
290
- 32
291
- ]
292
- }
293
- },
294
- {
295
- "name": "bump",
296
- "type": "u8"
297
- }
298
- ]
299
- }
300
- }
301
- ]
302
- };
66
+ // src/index.ts
67
+ import { sha256 as sha2562 } from "@noble/hashes/sha256";
303
68
 
304
69
  // src/crypto.ts
305
70
  import { sha256 } from "@noble/hashes/sha256";
@@ -311,25 +76,34 @@ ed.etc.sha512Sync = (...m) => {
311
76
  return h.digest();
312
77
  };
313
78
  var encoder = new TextEncoder();
79
+ var toScalar = (bytes) => {
80
+ const cleanBytes = bytes.length === 64 ? bytes.slice(0, 32) : bytes;
81
+ return ed.etc.mod(BigInt("0x" + bytesToHex(cleanBytes)), ed.CURVE.n);
82
+ };
314
83
  function generateEphemeralKeypair() {
315
84
  const secretKey = ed.utils.randomPrivateKey();
316
- return { secretKey, publicKey: ed.getPublicKey(secretKey) };
85
+ const scalar = toScalar(secretKey);
86
+ const publicKey = ed.ExtendedPoint.BASE.multiply(scalar).toRawBytes();
87
+ return { secretKey, publicKey };
88
+ }
89
+ function derivePublicKey(secretKey) {
90
+ const scalar = toScalar(secretKey);
91
+ return ed.ExtendedPoint.BASE.multiply(scalar).toRawBytes();
317
92
  }
318
93
  function computeSharedSecret(ephemeralSk, recipientMetaPk) {
319
94
  const point = ed.ExtendedPoint.fromHex(bytesToHex(recipientMetaPk));
320
- const scalar = ed.etc.mod(BigInt("0x" + bytesToHex(ephemeralSk)), ed.CURVE.n);
95
+ const scalar = toScalar(ephemeralSk);
321
96
  return sha256(point.multiply(scalar).toRawBytes());
322
97
  }
323
98
  function computeSharedSecretAsRecipient(metaSk, ephemeralPk) {
324
- const secretKey = metaSk.length === 64 ? metaSk.slice(0, 32) : metaSk;
325
99
  const point = ed.ExtendedPoint.fromHex(bytesToHex(ephemeralPk));
326
- const scalar = ed.etc.mod(BigInt("0x" + bytesToHex(secretKey)), ed.CURVE.n);
100
+ const scalar = toScalar(metaSk);
327
101
  return sha256(point.multiply(scalar).toRawBytes());
328
102
  }
329
103
  function deriveStealthPubkey(metaPk, sharedSecret) {
330
104
  const domain = encoder.encode(ADELOS_CONFIG.STEALTH_DOMAIN);
331
105
  const scalarBytes = sha256(new Uint8Array([...sharedSecret, ...domain]));
332
- const scalar = ed.etc.mod(BigInt("0x" + bytesToHex(scalarBytes)), ed.CURVE.n);
106
+ const scalar = toScalar(scalarBytes);
333
107
  const metaPoint = ed.ExtendedPoint.fromHex(bytesToHex(metaPk));
334
108
  const stealthPoint = metaPoint.add(ed.ExtendedPoint.BASE.multiply(scalar));
335
109
  return stealthPoint.toRawBytes();
@@ -337,8 +111,8 @@ function deriveStealthPubkey(metaPk, sharedSecret) {
337
111
  function recoverStealthSecretKey(metaSk, sharedSecret) {
338
112
  const domain = encoder.encode(ADELOS_CONFIG.STEALTH_DOMAIN);
339
113
  const scalarBytes = sha256(new Uint8Array([...sharedSecret, ...domain]));
340
- const scalar = ed.etc.mod(BigInt("0x" + bytesToHex(scalarBytes)), ed.CURVE.n);
341
- const metaScalar = ed.etc.mod(BigInt("0x" + bytesToHex(metaSk)), ed.CURVE.n);
114
+ const scalar = toScalar(scalarBytes);
115
+ const metaScalar = toScalar(metaSk);
342
116
  const stealthScalar = ed.etc.mod(metaScalar + scalar, ed.CURVE.n);
343
117
  const hex = stealthScalar.toString(16).padStart(64, "0");
344
118
  return hexToBytes(hex);
@@ -365,14 +139,10 @@ function generateStealthAddress(recipientMetaPk) {
365
139
  }
366
140
 
367
141
  // src/indexer.ts
368
- import { Connection } from "@solana/web3.js";
369
- var AdelosIndexer = class _AdelosIndexer {
370
- constructor(config) {
371
- this.connection = new Connection(config.rpcUrl, "confirmed");
372
- this.heliusApiKey = config.heliusApiKey;
373
- }
374
- static create(config) {
375
- return new _AdelosIndexer(config);
142
+ var AdelosIndexer = class {
143
+ // Sekarang langsung menerima objek Connection yang sudah jadi
144
+ constructor(connection) {
145
+ this.connection = connection;
376
146
  }
377
147
  /** Scan for stealth transfers to this recipient */
378
148
  async scanForStealthTransfers(metaSk, metaPk, limit = 100) {
@@ -400,7 +170,9 @@ var AdelosIndexer = class _AdelosIndexer {
400
170
  }
401
171
  return results;
402
172
  }
403
- /** Trial Decryption: Check if transaction is for this recipient */
173
+ /** * Trial Decryption: Mengecek apakah transaksi ini milik user.
174
+ * Dibuat 'public' agar bisa dites di file testing.
175
+ */
404
176
  attemptDecryption(tx, metaSk, metaPk) {
405
177
  const memo = this.extractMemo(tx);
406
178
  const ephemeralPk = parseStealthMemo(memo || "");
@@ -414,10 +186,10 @@ var AdelosIndexer = class _AdelosIndexer {
414
186
  if (idx === -1) return null;
415
187
  const preBalances = tx.meta?.preBalances || [];
416
188
  const postBalances = tx.meta?.postBalances || [];
417
- const change = (postBalances[idx] || 0) - (preBalances[idx] || 0);
189
+ const change = BigInt(postBalances[idx] || 0) - BigInt(preBalances[idx] || 0);
418
190
  return {
419
191
  stealthAddress: accounts[idx].pubkey,
420
- amount: BigInt(Math.max(change, 0))
192
+ amount: change > 0n ? change : 0n
421
193
  };
422
194
  }
423
195
  extractMemo(tx) {
@@ -427,54 +199,63 @@ var AdelosIndexer = class _AdelosIndexer {
427
199
  return ix?.parsed || null;
428
200
  }
429
201
  };
430
- function createIndexer(config) {
431
- return new AdelosIndexer(config);
202
+ function createIndexer(connection) {
203
+ return new AdelosIndexer(connection);
432
204
  }
433
205
 
434
206
  // src/index.ts
435
207
  var AdelosSDK = class {
436
208
  constructor(options = {}) {
437
- const rpcUrl = options.rpcUrl ?? ADELOS_CONFIG.RPC_URL;
438
- this.connection = new Connection2(rpcUrl, "confirmed");
209
+ this.connection = new Connection(options.rpcUrl ?? ADELOS_CONFIG.RPC_URL, "confirmed");
439
210
  this.programId = ADELOS_CONFIG.PROGRAM_ID;
440
211
  }
441
- // --- Registry Operations ---
442
- deriveRegistryAddress(owner) {
443
- return deriveRegistryPda(owner, this.programId);
444
- }
212
+ // --- 1. Identity & Registry ---
445
213
  async getRegistry(owner) {
446
- const [address] = this.deriveRegistryAddress(owner);
214
+ const [address] = deriveRegistryPda(owner, this.programId);
447
215
  const accountInfo = await this.connection.getAccountInfo(address);
448
- if (!accountInfo) {
449
- return { address, exists: false, account: null };
450
- }
216
+ if (!accountInfo) return { address, exists: false, account: null };
451
217
  const data = accountInfo.data.slice(8);
452
- const account = {
453
- owner: new PublicKey4(data.slice(0, 32)),
454
- metaPubkey: new Uint8Array(data.slice(32, 64)),
455
- bump: data[64]
218
+ return {
219
+ address,
220
+ exists: true,
221
+ account: {
222
+ owner: new PublicKey3(data.slice(0, 32)),
223
+ metaPubkey: new Uint8Array(data.slice(32, 64)),
224
+ bump: data[64]
225
+ }
456
226
  };
457
- return { address, exists: true, account };
458
227
  }
459
- async getMetaPubkey(owner) {
460
- const registry = await this.getRegistry(owner);
461
- return registry.exists ? registry.account.metaPubkey : null;
228
+ /** Menghasilkan metaSk tanpa simpan di LocalStorage (Deterministic) */
229
+ async unlockPrivacy(signMessage) {
230
+ const message = new TextEncoder().encode(ADELOS_CONFIG.UNLOCK_MESSAGE);
231
+ const signature = await signMessage(message);
232
+ return sha2562(signature);
462
233
  }
463
- async isRegistered(owner) {
464
- const registry = await this.getRegistry(owner);
465
- return registry.exists;
234
+ // --- 2. High-Level Transaction Builders ---
235
+ /** API Satu Pintu untuk kirim SOL secara privat */
236
+ async createStealthTransfer(sender, receiver, amountSOL, version = "v0") {
237
+ const registry = await this.getRegistry(receiver);
238
+ if (!registry.exists) throw new Error("Penerima belum terdaftar.");
239
+ const { stealthPubkey, memo } = await generateStealthAddress(registry.account.metaPubkey);
240
+ const instructions = [
241
+ SystemProgram.transfer({
242
+ fromPubkey: sender,
243
+ toPubkey: new PublicKey3(stealthPubkey),
244
+ lamports: BigInt(Math.round(amountSOL * 1e9))
245
+ }),
246
+ new TransactionInstruction({
247
+ keys: [{ pubkey: sender, isSigner: true, isWritable: false }],
248
+ programId: ADELOS_CONFIG.MEMO_PROGRAM_ID,
249
+ data: Buffer.from(memo, "utf-8")
250
+ })
251
+ ];
252
+ return this.buildTransaction(sender, instructions, version);
466
253
  }
467
- // --- Instruction Builders ---
468
- createRegisterInstruction(owner, metaPubkey) {
469
- if (!isValidMetaPubkey(metaPubkey)) {
470
- throw new Error("Invalid meta pubkey: must be 32 bytes and not all zeros");
471
- }
472
- const [registryPda] = this.deriveRegistryAddress(owner);
473
- const data = Buffer.concat([
474
- Buffer.from(getDiscriminator("register_identity")),
475
- Buffer.from(metaPubkey)
476
- ]);
477
- return new TransactionInstruction({
254
+ /** Membuat transaksi pendaftaran identitas */
255
+ async createRegisterTransaction(owner, metaPubkey, version = "v0") {
256
+ const [registryPda] = deriveRegistryPda(owner, this.programId);
257
+ const data = Buffer.concat([Buffer.from(getDiscriminator("register_identity")), Buffer.from(metaPubkey)]);
258
+ const ix = new TransactionInstruction({
478
259
  keys: [
479
260
  { pubkey: owner, isSigner: true, isWritable: true },
480
261
  { pubkey: registryPda, isSigner: false, isWritable: true },
@@ -483,39 +264,9 @@ var AdelosSDK = class {
483
264
  programId: this.programId,
484
265
  data
485
266
  });
267
+ return this.buildTransaction(owner, [ix], version);
486
268
  }
487
- createUpdateInstruction(owner, newMetaPubkey) {
488
- if (!isValidMetaPubkey(newMetaPubkey)) {
489
- throw new Error("Invalid meta pubkey: must be 32 bytes and not all zeros");
490
- }
491
- const [registryPda] = this.deriveRegistryAddress(owner);
492
- const data = Buffer.concat([
493
- Buffer.from(getDiscriminator("update_identity")),
494
- Buffer.from(newMetaPubkey)
495
- ]);
496
- return new TransactionInstruction({
497
- keys: [
498
- { pubkey: owner, isSigner: true, isWritable: true },
499
- { pubkey: registryPda, isSigner: false, isWritable: true },
500
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }
501
- ],
502
- programId: this.programId,
503
- data
504
- });
505
- }
506
- createCloseInstruction(owner) {
507
- const [registryPda] = this.deriveRegistryAddress(owner);
508
- const data = Buffer.from(getDiscriminator("close_registry"));
509
- return new TransactionInstruction({
510
- keys: [
511
- { pubkey: owner, isSigner: true, isWritable: true },
512
- { pubkey: registryPda, isSigner: false, isWritable: true }
513
- ],
514
- programId: this.programId,
515
- data
516
- });
517
- }
518
- // --- Transaction Builders ---
269
+ // --- 3. Core Engine (Internal Helpers) ---
519
270
  async buildTransaction(payer, instructions, version = "v0") {
520
271
  const { blockhash } = await this.connection.getLatestBlockhash();
521
272
  if (version === "legacy") {
@@ -531,21 +282,10 @@ var AdelosSDK = class {
531
282
  }).compileToV0Message();
532
283
  return new VersionedTransaction(message);
533
284
  }
534
- async createRegisterTransaction(owner, metaPubkey) {
535
- const ix = this.createRegisterInstruction(owner, metaPubkey);
536
- return this.buildTransaction(owner, [ix], "legacy");
537
- }
538
- async createRegisterTransactionV0(owner, metaPubkey) {
539
- const ix = this.createRegisterInstruction(owner, metaPubkey);
540
- return this.buildTransaction(owner, [ix], "v0");
541
- }
285
+ /** Satu fungsi kirim untuk semua jenis transaksi (Legacy/V0) */
542
286
  async sendAndConfirm(signedTx) {
543
- const sig = await this.connection.sendRawTransaction(signedTx.serialize());
544
- await this.connection.confirmTransaction(sig, "confirmed");
545
- return sig;
546
- }
547
- async sendAndConfirmV0(signedTx) {
548
- const sig = await this.connection.sendRawTransaction(signedTx.serialize());
287
+ const rawTx = signedTx instanceof Transaction ? signedTx.serialize() : signedTx.serialize();
288
+ const sig = await this.connection.sendRawTransaction(rawTx);
549
289
  await this.connection.confirmTransaction(sig, "confirmed");
550
290
  return sig;
551
291
  }
@@ -554,7 +294,6 @@ export {
554
294
  ADELOS_CONFIG,
555
295
  AdelosIndexer,
556
296
  AdelosSDK,
557
- IDL,
558
297
  MEMO_PREFIX,
559
298
  MEMO_PROGRAM_ID,
560
299
  PROGRAM_ID,
@@ -565,6 +304,7 @@ export {
565
304
  computeSharedSecret,
566
305
  computeSharedSecretAsRecipient,
567
306
  createIndexer,
307
+ derivePublicKey,
568
308
  deriveRegistryPda,
569
309
  deriveStealthPubkey,
570
310
  generateEphemeralKeypair,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adelos/sdk",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Adelos Protocol SDK - Privacy Stealth Transfers on Solana",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",