@sip-protocol/sdk 0.6.25 → 0.7.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 RECTOR Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/browser.js CHANGED
@@ -4036,6 +4036,9 @@ function generateStealthMetaAddress(chain, label) {
4036
4036
  "chain"
4037
4037
  );
4038
4038
  }
4039
+ if (isEd25519Chain(chain)) {
4040
+ return generateEd25519StealthMetaAddress(chain, label);
4041
+ }
4039
4042
  const spendingPrivateKey = (0, import_utils2.randomBytes)(32);
4040
4043
  const viewingPrivateKey = (0, import_utils2.randomBytes)(32);
4041
4044
  try {
@@ -4097,6 +4100,9 @@ function validateStealthMetaAddress(metaAddress, field = "recipientMetaAddress")
4097
4100
  }
4098
4101
  function generateStealthAddress(recipientMetaAddress) {
4099
4102
  validateStealthMetaAddress(recipientMetaAddress);
4103
+ if (isEd25519Chain(recipientMetaAddress.chain)) {
4104
+ return generateEd25519StealthAddress(recipientMetaAddress);
4105
+ }
4100
4106
  const ephemeralPrivateKey = (0, import_utils2.randomBytes)(32);
4101
4107
  try {
4102
4108
  const ephemeralPublicKey = import_secp256k1.secp256k1.getPublicKey(ephemeralPrivateKey, true);
@@ -5430,6 +5436,12 @@ async function createShieldedIntent(params, options) {
5430
5436
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
5431
5437
  return (0, import_utils6.hexToBytes)(cleanHex);
5432
5438
  };
5439
+ if (allowPlaceholders && typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
5440
+ throw new ValidationError(
5441
+ "allowPlaceholders cannot be used in production environment. Provide valid senderSecret and signatures for production use.",
5442
+ "options.allowPlaceholders"
5443
+ );
5444
+ }
5433
5445
  const effectiveSenderSecret = senderSecret ?? (0, import_utils6.randomBytes)(32);
5434
5446
  const rawIntentHashBytes = (0, import_sha2565.sha256)(new TextEncoder().encode(intentId));
5435
5447
  const intentHashHex = hash(intentId);
@@ -5651,8 +5663,8 @@ var OneClickClient = class {
5651
5663
  params.set("depositMemo", depositMemo);
5652
5664
  }
5653
5665
  const rawStatus = await this.get(`/v0/status?${params.toString()}`);
5654
- const settlementTxHash = rawStatus.settlementTxHash ?? rawStatus.destinationChainTxHashes?.[0]?.hash;
5655
- const depositTxHash = rawStatus.depositTxHash ?? rawStatus.originChainTxHashes?.[0]?.hash;
5666
+ const settlementTxHash = rawStatus.settlementTxHash ?? rawStatus.swapDetails?.destinationChainTxHashes?.[0]?.hash ?? rawStatus.destinationChainTxHashes?.[0]?.hash;
5667
+ const depositTxHash = rawStatus.depositTxHash ?? rawStatus.swapDetails?.originChainTxHashes?.[0]?.hash ?? rawStatus.originChainTxHashes?.[0]?.hash;
5656
5668
  return {
5657
5669
  ...rawStatus,
5658
5670
  settlementTxHash,
package/dist/browser.mjs CHANGED
@@ -263,7 +263,7 @@ import {
263
263
  walletRegistry,
264
264
  withSecureBuffer,
265
265
  withSecureBufferSync
266
- } from "./chunk-EMOAOF5P.mjs";
266
+ } from "./chunk-3OVABDRH.mjs";
267
267
  import {
268
268
  fulfillment_proof_default,
269
269
  funding_proof_default,
@@ -379,6 +379,9 @@ function generateStealthMetaAddress(chain, label) {
379
379
  "chain"
380
380
  );
381
381
  }
382
+ if (isEd25519Chain(chain)) {
383
+ return generateEd25519StealthMetaAddress(chain, label);
384
+ }
382
385
  const spendingPrivateKey = randomBytes2(32);
383
386
  const viewingPrivateKey = randomBytes2(32);
384
387
  try {
@@ -440,6 +443,9 @@ function validateStealthMetaAddress(metaAddress, field = "recipientMetaAddress")
440
443
  }
441
444
  function generateStealthAddress(recipientMetaAddress) {
442
445
  validateStealthMetaAddress(recipientMetaAddress);
446
+ if (isEd25519Chain(recipientMetaAddress.chain)) {
447
+ return generateEd25519StealthAddress(recipientMetaAddress);
448
+ }
443
449
  const ephemeralPrivateKey = randomBytes2(32);
444
450
  try {
445
451
  const ephemeralPublicKey = secp256k1.getPublicKey(ephemeralPrivateKey, true);
@@ -1773,6 +1779,12 @@ async function createShieldedIntent(params, options) {
1773
1779
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
1774
1780
  return hexToBytes4(cleanHex);
1775
1781
  };
1782
+ if (allowPlaceholders && typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
1783
+ throw new ValidationError(
1784
+ "allowPlaceholders cannot be used in production environment. Provide valid senderSecret and signatures for production use.",
1785
+ "options.allowPlaceholders"
1786
+ );
1787
+ }
1776
1788
  const effectiveSenderSecret = senderSecret ?? randomBytes6(32);
1777
1789
  const rawIntentHashBytes = sha2565(new TextEncoder().encode(intentId));
1778
1790
  const intentHashHex = hash(intentId);
@@ -1997,8 +2009,8 @@ var OneClickClient = class {
1997
2009
  params.set("depositMemo", depositMemo);
1998
2010
  }
1999
2011
  const rawStatus = await this.get(`/v0/status?${params.toString()}`);
2000
- const settlementTxHash = rawStatus.settlementTxHash ?? rawStatus.destinationChainTxHashes?.[0]?.hash;
2001
- const depositTxHash = rawStatus.depositTxHash ?? rawStatus.originChainTxHashes?.[0]?.hash;
2012
+ const settlementTxHash = rawStatus.settlementTxHash ?? rawStatus.swapDetails?.destinationChainTxHashes?.[0]?.hash ?? rawStatus.destinationChainTxHashes?.[0]?.hash;
2013
+ const depositTxHash = rawStatus.depositTxHash ?? rawStatus.swapDetails?.originChainTxHashes?.[0]?.hash ?? rawStatus.originChainTxHashes?.[0]?.hash;
2002
2014
  return {
2003
2015
  ...rawStatus,
2004
2016
  settlementTxHash,
package/dist/index.js CHANGED
@@ -4023,6 +4023,9 @@ function generateStealthMetaAddress(chain, label) {
4023
4023
  "chain"
4024
4024
  );
4025
4025
  }
4026
+ if (isEd25519Chain(chain)) {
4027
+ return generateEd25519StealthMetaAddress(chain, label);
4028
+ }
4026
4029
  const spendingPrivateKey = (0, import_utils2.randomBytes)(32);
4027
4030
  const viewingPrivateKey = (0, import_utils2.randomBytes)(32);
4028
4031
  try {
@@ -4084,6 +4087,9 @@ function validateStealthMetaAddress(metaAddress, field = "recipientMetaAddress")
4084
4087
  }
4085
4088
  function generateStealthAddress(recipientMetaAddress) {
4086
4089
  validateStealthMetaAddress(recipientMetaAddress);
4090
+ if (isEd25519Chain(recipientMetaAddress.chain)) {
4091
+ return generateEd25519StealthAddress(recipientMetaAddress);
4092
+ }
4087
4093
  const ephemeralPrivateKey = (0, import_utils2.randomBytes)(32);
4088
4094
  try {
4089
4095
  const ephemeralPublicKey = import_secp256k1.secp256k1.getPublicKey(ephemeralPrivateKey, true);
@@ -5417,6 +5423,12 @@ async function createShieldedIntent(params, options) {
5417
5423
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
5418
5424
  return (0, import_utils6.hexToBytes)(cleanHex);
5419
5425
  };
5426
+ if (allowPlaceholders && typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
5427
+ throw new ValidationError(
5428
+ "allowPlaceholders cannot be used in production environment. Provide valid senderSecret and signatures for production use.",
5429
+ "options.allowPlaceholders"
5430
+ );
5431
+ }
5420
5432
  const effectiveSenderSecret = senderSecret ?? (0, import_utils6.randomBytes)(32);
5421
5433
  const rawIntentHashBytes = (0, import_sha2565.sha256)(new TextEncoder().encode(intentId));
5422
5434
  const intentHashHex = hash(intentId);
@@ -5638,8 +5650,8 @@ var OneClickClient = class {
5638
5650
  params.set("depositMemo", depositMemo);
5639
5651
  }
5640
5652
  const rawStatus = await this.get(`/v0/status?${params.toString()}`);
5641
- const settlementTxHash = rawStatus.settlementTxHash ?? rawStatus.destinationChainTxHashes?.[0]?.hash;
5642
- const depositTxHash = rawStatus.depositTxHash ?? rawStatus.originChainTxHashes?.[0]?.hash;
5653
+ const settlementTxHash = rawStatus.settlementTxHash ?? rawStatus.swapDetails?.destinationChainTxHashes?.[0]?.hash ?? rawStatus.destinationChainTxHashes?.[0]?.hash;
5654
+ const depositTxHash = rawStatus.depositTxHash ?? rawStatus.swapDetails?.originChainTxHashes?.[0]?.hash ?? rawStatus.originChainTxHashes?.[0]?.hash;
5643
5655
  return {
5644
5656
  ...rawStatus,
5645
5657
  settlementTxHash,
package/dist/index.mjs CHANGED
@@ -253,7 +253,7 @@ import {
253
253
  walletRegistry,
254
254
  withSecureBuffer,
255
255
  withSecureBufferSync
256
- } from "./chunk-EMOAOF5P.mjs";
256
+ } from "./chunk-3OVABDRH.mjs";
257
257
  import {
258
258
  CryptoError,
259
259
  EncryptionNotImplementedError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sip-protocol/sdk",
3
- "version": "0.6.25",
3
+ "version": "0.7.0",
4
4
  "description": "Core SDK for Shielded Intents Protocol - Privacy layer for cross-chain transactions",
5
5
  "author": "SIP Protocol <hello@sip-protocol.org>",
6
6
  "homepage": "https://sip-protocol.org",
@@ -36,18 +36,6 @@
36
36
  "dist",
37
37
  "src"
38
38
  ],
39
- "scripts": {
40
- "build": "tsup src/index.ts src/browser.ts src/proofs/noir.ts --format cjs,esm --dts",
41
- "dev": "tsup src/index.ts src/browser.ts src/proofs/noir.ts --format cjs,esm --dts --watch",
42
- "lint": "eslint --ext .ts src/",
43
- "typecheck": "tsc --noEmit",
44
- "clean": "rm -rf dist",
45
- "test": "vitest",
46
- "test:coverage": "vitest run --coverage",
47
- "bench": "vitest bench --config vitest.bench.config.ts",
48
- "bench:json": "vitest bench --config vitest.bench.config.ts --outputJson benchmarks/results.json",
49
- "demo:auction": "tsx examples/auction-demo.ts"
50
- },
51
39
  "dependencies": {
52
40
  "@aztec/bb.js": "3.0.0-nightly.20251104",
53
41
  "@ethereumjs/rlp": "^10.1.0",
@@ -57,7 +45,7 @@
57
45
  "@noir-lang/noir_js": "1.0.0-beta.15",
58
46
  "@noir-lang/types": "1.0.0-beta.15",
59
47
  "@scure/base": "^2.0.0",
60
- "@sip-protocol/types": "^0.2.0"
48
+ "@sip-protocol/types": "0.2.1"
61
49
  },
62
50
  "devDependencies": {
63
51
  "@vitest/coverage-v8": "1.6.1",
@@ -74,5 +62,17 @@
74
62
  "stealth-addresses",
75
63
  "zcash"
76
64
  ],
77
- "license": "MIT"
78
- }
65
+ "license": "MIT",
66
+ "scripts": {
67
+ "build": "tsup src/index.ts src/browser.ts src/proofs/noir.ts --format cjs,esm --dts",
68
+ "dev": "tsup src/index.ts src/browser.ts src/proofs/noir.ts --format cjs,esm --dts --watch",
69
+ "lint": "eslint --ext .ts src/",
70
+ "typecheck": "tsc --noEmit",
71
+ "clean": "rm -rf dist",
72
+ "test": "vitest",
73
+ "test:coverage": "vitest run --coverage",
74
+ "bench": "vitest bench --config vitest.bench.config.ts",
75
+ "bench:json": "vitest bench --config vitest.bench.config.ts --outputJson benchmarks/results.json",
76
+ "demo:auction": "tsx examples/auction-demo.ts"
77
+ }
78
+ }
@@ -173,16 +173,27 @@ export class OneClickClient {
173
173
  params.set('depositMemo', depositMemo)
174
174
  }
175
175
 
176
- const rawStatus = await this.get<OneClickStatusResponse>(`/v0/status?${params.toString()}`)
176
+ // Type for raw API response with nested swapDetails
177
+ interface RawStatusResponse extends OneClickStatusResponse {
178
+ swapDetails?: {
179
+ destinationChainTxHashes?: { hash: string; explorerUrl: string }[]
180
+ originChainTxHashes?: { hash: string; explorerUrl: string }[]
181
+ nearTxHashes?: string[]
182
+ }
183
+ }
184
+
185
+ const rawStatus = await this.get<RawStatusResponse>(`/v0/status?${params.toString()}`)
177
186
 
178
- // Normalize response: extract settlement tx hash from destinationChainTxHashes if available
179
- // The 1Click API returns destinationChainTxHashes array with {hash, explorerUrl} objects
187
+ // Normalize response: extract settlement tx hash from swapDetails.destinationChainTxHashes
188
+ // The 1Click API returns tx hashes nested inside swapDetails object
180
189
  const settlementTxHash = rawStatus.settlementTxHash
181
- ?? rawStatus.destinationChainTxHashes?.[0]?.hash
190
+ ?? rawStatus.swapDetails?.destinationChainTxHashes?.[0]?.hash
191
+ ?? rawStatus.destinationChainTxHashes?.[0]?.hash // fallback for flat response
182
192
 
183
- // Extract deposit tx hash from originChainTxHashes if not already present
193
+ // Extract deposit tx hash from swapDetails.originChainTxHashes if not already present
184
194
  const depositTxHash = rawStatus.depositTxHash
185
- ?? rawStatus.originChainTxHashes?.[0]?.hash
195
+ ?? rawStatus.swapDetails?.originChainTxHashes?.[0]?.hash
196
+ ?? rawStatus.originChainTxHashes?.[0]?.hash // fallback for flat response
186
197
 
187
198
  return {
188
199
  ...rawStatus,
package/src/intent.ts CHANGED
@@ -554,6 +554,16 @@ export async function createShieldedIntent(
554
554
  return hexToBytes(cleanHex)
555
555
  }
556
556
 
557
+ // SECURITY: Prevent placeholder mode in production environments
558
+ // Placeholder signatures are NOT cryptographically valid and must never be used in production
559
+ if (allowPlaceholders && typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') {
560
+ throw new ValidationError(
561
+ 'allowPlaceholders cannot be used in production environment. ' +
562
+ 'Provide valid senderSecret and signatures for production use.',
563
+ 'options.allowPlaceholders'
564
+ )
565
+ }
566
+
557
567
  // Use provided signatures or generate them from senderSecret
558
568
  // IMPORTANT: senderSecret must be random even for placeholders, as secp256k1
559
569
  // rejects all-zero private keys. randomBytes generates cryptographically secure random values.
package/src/stealth.ts CHANGED
@@ -113,7 +113,12 @@ export function generateStealthMetaAddress(
113
113
  )
114
114
  }
115
115
 
116
- // Generate random private keys
116
+ // Dispatch to curve-specific implementation
117
+ if (isEd25519Chain(chain)) {
118
+ return generateEd25519StealthMetaAddress(chain, label)
119
+ }
120
+
121
+ // secp256k1 implementation for EVM chains
117
122
  const spendingPrivateKey = randomBytes(32)
118
123
  const viewingPrivateKey = randomBytes(32)
119
124
 
@@ -269,7 +274,12 @@ export function generateStealthAddress(
269
274
  // Validate input
270
275
  validateStealthMetaAddress(recipientMetaAddress)
271
276
 
272
- // Generate ephemeral keypair
277
+ // Dispatch to curve-specific implementation based on chain
278
+ if (isEd25519Chain(recipientMetaAddress.chain)) {
279
+ return generateEd25519StealthAddress(recipientMetaAddress)
280
+ }
281
+
282
+ // secp256k1 implementation for EVM chains
273
283
  const ephemeralPrivateKey = randomBytes(32)
274
284
 
275
285
  try {