@defuse-protocol/intents-sdk 0.51.0 → 0.52.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.
@@ -40,7 +40,8 @@ const caip2Mapping = {
40
40
  [require_caip2.Chains.Aptos]: "aptos:mainnet",
41
41
  [require_caip2.Chains.Cardano]: "cardano:mainnet",
42
42
  [require_caip2.Chains.Litecoin]: "ltc:mainnet",
43
- [require_caip2.Chains.Starknet]: "starknet:mainnet"
43
+ [require_caip2.Chains.Starknet]: "starknet:mainnet",
44
+ [require_caip2.Chains.Aleo]: "aleo:mainnet"
44
45
  };
45
46
  function toPoaNetwork(caip2) {
46
47
  if (caip2Mapping[caip2] == null) throw new Error(`Unsupported POA Bridge chain = ${caip2}`);
@@ -63,7 +64,8 @@ const tokenPrefixMapping = {
63
64
  aptos: require_caip2.Chains.Aptos,
64
65
  cardano: require_caip2.Chains.Cardano,
65
66
  ltc: require_caip2.Chains.Litecoin,
66
- starknet: require_caip2.Chains.Starknet
67
+ starknet: require_caip2.Chains.Starknet,
68
+ aleo: require_caip2.Chains.Aleo
67
69
  };
68
70
  function contractIdToCaip2(contractId) {
69
71
  for (const [prefix, caip2] of Object.entries(tokenPrefixMapping)) if (contractId.startsWith(`${prefix}.`) || contractId.startsWith(`${prefix}-`)) return caip2;
@@ -39,7 +39,8 @@ const caip2Mapping = {
39
39
  [Chains.Aptos]: "aptos:mainnet",
40
40
  [Chains.Cardano]: "cardano:mainnet",
41
41
  [Chains.Litecoin]: "ltc:mainnet",
42
- [Chains.Starknet]: "starknet:mainnet"
42
+ [Chains.Starknet]: "starknet:mainnet",
43
+ [Chains.Aleo]: "aleo:mainnet"
43
44
  };
44
45
  function toPoaNetwork(caip2) {
45
46
  if (caip2Mapping[caip2] == null) throw new Error(`Unsupported POA Bridge chain = ${caip2}`);
@@ -62,7 +63,8 @@ const tokenPrefixMapping = {
62
63
  aptos: Chains.Aptos,
63
64
  cardano: Chains.Cardano,
64
65
  ltc: Chains.Litecoin,
65
- starknet: Chains.Starknet
66
+ starknet: Chains.Starknet,
67
+ aleo: Chains.Aleo
66
68
  };
67
69
  function contractIdToCaip2(contractId) {
68
70
  for (const [prefix, caip2] of Object.entries(tokenPrefixMapping)) if (contractId.startsWith(`${prefix}.`) || contractId.startsWith(`${prefix}-`)) return caip2;
@@ -34,7 +34,8 @@ const Chains = {
34
34
  Cardano: "cip34:1-764824073",
35
35
  Starknet: "starknet:SN_MAIN",
36
36
  Plasma: "eip155:9745",
37
- Scroll: "eip155:534352"
37
+ Scroll: "eip155:534352",
38
+ Aleo: "aleo:0"
38
39
  };
39
40
  function getEIP155ChainId(chain) {
40
41
  (0, _defuse_protocol_internal_utils.assert)(chain.startsWith("eip155:"), "Chain is not an EIP-155 chain");
@@ -32,6 +32,7 @@ declare const Chains: {
32
32
  readonly Starknet: "starknet:SN_MAIN";
33
33
  readonly Plasma: "eip155:9745";
34
34
  readonly Scroll: "eip155:534352";
35
+ readonly Aleo: "aleo:0";
35
36
  };
36
37
  type Chain = (typeof Chains)[keyof typeof Chains];
37
38
  //#endregion
@@ -32,6 +32,7 @@ declare const Chains: {
32
32
  readonly Starknet: "starknet:SN_MAIN";
33
33
  readonly Plasma: "eip155:9745";
34
34
  readonly Scroll: "eip155:534352";
35
+ readonly Aleo: "aleo:0";
35
36
  };
36
37
  type Chain = (typeof Chains)[keyof typeof Chains];
37
38
  //#endregion
@@ -33,7 +33,8 @@ const Chains = {
33
33
  Cardano: "cip34:1-764824073",
34
34
  Starknet: "starknet:SN_MAIN",
35
35
  Plasma: "eip155:9745",
36
- Scroll: "eip155:534352"
36
+ Scroll: "eip155:534352",
37
+ Aleo: "aleo:0"
37
38
  };
38
39
  function getEIP155ChainId(chain) {
39
40
  assert(chain.startsWith("eip155:"), "Chain is not an EIP-155 chain");
@@ -46,6 +46,7 @@ function validateAddress(address, blockchain) {
46
46
  case require_caip2.Chains.Berachain:
47
47
  case require_caip2.Chains.Plasma:
48
48
  case require_caip2.Chains.Scroll: return validateEthAddress(address);
49
+ case require_caip2.Chains.Aleo: return validateAleoAddress(address);
49
50
  default: return false;
50
51
  }
51
52
  }
@@ -266,6 +267,154 @@ function validateLitecoinBech32Address(address) {
266
267
  }
267
268
  return false;
268
269
  }
270
+ /** Base field modulus (= scalar field order of BLS12-377). */
271
+ const P = 8444461749428370424248824938781546531375899335154063827935233455917409239041n;
272
+ /** Edwards curve coefficient d. Curve: -x² + y² = 1 + d·x²·y² (a = -1). */
273
+ const D = 3021n;
274
+ /** Prime-order subgroup order (= scalar field of Edwards BLS12-377, cofactor = 4). */
275
+ const SUBGROUP_ORDER = 2111115437357092606062206234695386632838870926408408195193685246394721360383n;
276
+ function modPow(base, exp, m) {
277
+ let result = 1n;
278
+ base = (base % m + m) % m;
279
+ while (exp > 0n) {
280
+ if (exp & 1n) result = result * base % m;
281
+ exp >>= 1n;
282
+ base = base * base % m;
283
+ }
284
+ return result;
285
+ }
286
+ /** Tonelli-Shanks square root in F_P. Returns null when n is a non-residue. */
287
+ function modSqrt(n) {
288
+ n = (n % P + P) % P;
289
+ if (n === 0n) return 0n;
290
+ if (modPow(n, (P - 1n) / 2n, P) !== 1n) return null;
291
+ let s = 0;
292
+ let q = P - 1n;
293
+ while ((q & 1n) === 0n) {
294
+ s++;
295
+ q >>= 1n;
296
+ }
297
+ let z = 2n;
298
+ while (modPow(z, (P - 1n) / 2n, P) !== P - 1n) z++;
299
+ let m = s;
300
+ let c = modPow(z, q, P);
301
+ let t = modPow(n, q, P);
302
+ let r = modPow(n, (q + 1n) / 2n, P);
303
+ for (;;) {
304
+ if (t === 1n) return r;
305
+ let i = 1;
306
+ let tmp = t * t % P;
307
+ while (tmp !== 1n) {
308
+ tmp = tmp * tmp % P;
309
+ i++;
310
+ }
311
+ let b = c;
312
+ for (let j = 0; j < m - i - 1; j++) b = b * b % P;
313
+ m = i;
314
+ c = b * b % P;
315
+ t = t * c % P;
316
+ r = r * b % P;
317
+ }
318
+ }
319
+ const EXT_ZERO = [
320
+ 0n,
321
+ 1n,
322
+ 0n,
323
+ 1n
324
+ ];
325
+ function extAdd(a, b) {
326
+ const [X1, Y1, T1, Z1] = a;
327
+ const [X2, Y2, T2, Z2] = b;
328
+ const A = X1 * X2 % P;
329
+ const B = Y1 * Y2 % P;
330
+ const C = T1 * D % P * T2 % P;
331
+ const Dd = Z1 * Z2 % P;
332
+ const E = ((X1 + Y1) % P * ((X2 + Y2) % P) % P - A - B + 2n * P) % P;
333
+ const F = ((Dd - C) % P + P) % P;
334
+ const G = (Dd + C) % P;
335
+ const H = (B + A) % P;
336
+ return [
337
+ E * F % P,
338
+ G * H % P,
339
+ E * H % P,
340
+ F * G % P
341
+ ];
342
+ }
343
+ function extDouble(a) {
344
+ const [X, Y, _T, Z] = a;
345
+ const A = X * X % P;
346
+ const B = Y * Y % P;
347
+ const C = 2n * (Z * Z % P) % P;
348
+ const Dd = (P - A) % P;
349
+ const E = ((X + Y) % P * ((X + Y) % P) % P - A - B + 2n * P) % P;
350
+ const G = (Dd + B) % P;
351
+ const F = ((G - C) % P + P) % P;
352
+ const H = ((Dd - B) % P + P) % P;
353
+ return [
354
+ E * F % P,
355
+ G * H % P,
356
+ E * H % P,
357
+ F * G % P
358
+ ];
359
+ }
360
+ function scalarMul(pt, scalar) {
361
+ let result = EXT_ZERO;
362
+ let base = pt;
363
+ let s = scalar;
364
+ while (s > 0n) {
365
+ if (s & 1n) result = extAdd(result, base);
366
+ base = extDouble(base);
367
+ s >>= 1n;
368
+ }
369
+ return result;
370
+ }
371
+ /** Check whether an extended point is the identity (0, 1). */
372
+ function isIdentity(pt) {
373
+ return pt[0] === 0n && pt[1] === pt[3];
374
+ }
375
+ /**
376
+ * Validates an Aleo address by decoding the bech32m payload, decompressing
377
+ * the Edwards BLS12-377 point, and verifying it lies in the prime-order
378
+ * subgroup — matching snarkVM's `Group::from_x_coordinate` exactly.
379
+ *
380
+ * Compressed format: x-coordinate (little-endian, 32 bytes) with y-sign
381
+ * flag in bit 7 of byte 31.
382
+ */
383
+ function validateAleoAddress(address) {
384
+ try {
385
+ const decoded = _scure_base.bech32m.decodeToBytes(address);
386
+ if (decoded.prefix !== "aleo") return false;
387
+ if (decoded.bytes.length !== 32) return false;
388
+ const bytes = new Uint8Array(decoded.bytes);
389
+ bytes[31] = bytes[31] & 127;
390
+ let x = 0n;
391
+ for (let i = 31; i >= 0; i--) x = x << 8n | BigInt(bytes[i]);
392
+ if (x >= P) return false;
393
+ const x2 = x * x % P;
394
+ const num = (1n + x2) % P;
395
+ const den = ((1n - D * x2 % P) % P + P) % P;
396
+ if (den === 0n) return false;
397
+ const y = modSqrt(num * modPow(den, P - 2n, P) % P);
398
+ if (y === null) return false;
399
+ const negY = y === 0n ? 0n : P - y;
400
+ const p1 = [
401
+ x,
402
+ y,
403
+ x * y % P,
404
+ 1n
405
+ ];
406
+ const p2 = [
407
+ x,
408
+ negY,
409
+ x * negY % P,
410
+ 1n
411
+ ];
412
+ for (const pt of [p1, p2]) if (isIdentity(scalarMul(pt, SUBGROUP_ORDER))) return true;
413
+ return false;
414
+ } catch {
415
+ return false;
416
+ }
417
+ }
269
418
 
270
419
  //#endregion
271
420
  exports.validateAddress = validateAddress;
@@ -45,6 +45,7 @@ function validateAddress(address, blockchain) {
45
45
  case Chains.Berachain:
46
46
  case Chains.Plasma:
47
47
  case Chains.Scroll: return validateEthAddress(address);
48
+ case Chains.Aleo: return validateAleoAddress(address);
48
49
  default: return false;
49
50
  }
50
51
  }
@@ -265,6 +266,154 @@ function validateLitecoinBech32Address(address) {
265
266
  }
266
267
  return false;
267
268
  }
269
+ /** Base field modulus (= scalar field order of BLS12-377). */
270
+ const P = 8444461749428370424248824938781546531375899335154063827935233455917409239041n;
271
+ /** Edwards curve coefficient d. Curve: -x² + y² = 1 + d·x²·y² (a = -1). */
272
+ const D = 3021n;
273
+ /** Prime-order subgroup order (= scalar field of Edwards BLS12-377, cofactor = 4). */
274
+ const SUBGROUP_ORDER = 2111115437357092606062206234695386632838870926408408195193685246394721360383n;
275
+ function modPow(base, exp, m) {
276
+ let result = 1n;
277
+ base = (base % m + m) % m;
278
+ while (exp > 0n) {
279
+ if (exp & 1n) result = result * base % m;
280
+ exp >>= 1n;
281
+ base = base * base % m;
282
+ }
283
+ return result;
284
+ }
285
+ /** Tonelli-Shanks square root in F_P. Returns null when n is a non-residue. */
286
+ function modSqrt(n) {
287
+ n = (n % P + P) % P;
288
+ if (n === 0n) return 0n;
289
+ if (modPow(n, (P - 1n) / 2n, P) !== 1n) return null;
290
+ let s = 0;
291
+ let q = P - 1n;
292
+ while ((q & 1n) === 0n) {
293
+ s++;
294
+ q >>= 1n;
295
+ }
296
+ let z = 2n;
297
+ while (modPow(z, (P - 1n) / 2n, P) !== P - 1n) z++;
298
+ let m = s;
299
+ let c = modPow(z, q, P);
300
+ let t = modPow(n, q, P);
301
+ let r = modPow(n, (q + 1n) / 2n, P);
302
+ for (;;) {
303
+ if (t === 1n) return r;
304
+ let i = 1;
305
+ let tmp = t * t % P;
306
+ while (tmp !== 1n) {
307
+ tmp = tmp * tmp % P;
308
+ i++;
309
+ }
310
+ let b = c;
311
+ for (let j = 0; j < m - i - 1; j++) b = b * b % P;
312
+ m = i;
313
+ c = b * b % P;
314
+ t = t * c % P;
315
+ r = r * b % P;
316
+ }
317
+ }
318
+ const EXT_ZERO = [
319
+ 0n,
320
+ 1n,
321
+ 0n,
322
+ 1n
323
+ ];
324
+ function extAdd(a, b) {
325
+ const [X1, Y1, T1, Z1] = a;
326
+ const [X2, Y2, T2, Z2] = b;
327
+ const A = X1 * X2 % P;
328
+ const B = Y1 * Y2 % P;
329
+ const C = T1 * D % P * T2 % P;
330
+ const Dd = Z1 * Z2 % P;
331
+ const E = ((X1 + Y1) % P * ((X2 + Y2) % P) % P - A - B + 2n * P) % P;
332
+ const F = ((Dd - C) % P + P) % P;
333
+ const G = (Dd + C) % P;
334
+ const H = (B + A) % P;
335
+ return [
336
+ E * F % P,
337
+ G * H % P,
338
+ E * H % P,
339
+ F * G % P
340
+ ];
341
+ }
342
+ function extDouble(a) {
343
+ const [X, Y, _T, Z] = a;
344
+ const A = X * X % P;
345
+ const B = Y * Y % P;
346
+ const C = 2n * (Z * Z % P) % P;
347
+ const Dd = (P - A) % P;
348
+ const E = ((X + Y) % P * ((X + Y) % P) % P - A - B + 2n * P) % P;
349
+ const G = (Dd + B) % P;
350
+ const F = ((G - C) % P + P) % P;
351
+ const H = ((Dd - B) % P + P) % P;
352
+ return [
353
+ E * F % P,
354
+ G * H % P,
355
+ E * H % P,
356
+ F * G % P
357
+ ];
358
+ }
359
+ function scalarMul(pt, scalar) {
360
+ let result = EXT_ZERO;
361
+ let base = pt;
362
+ let s = scalar;
363
+ while (s > 0n) {
364
+ if (s & 1n) result = extAdd(result, base);
365
+ base = extDouble(base);
366
+ s >>= 1n;
367
+ }
368
+ return result;
369
+ }
370
+ /** Check whether an extended point is the identity (0, 1). */
371
+ function isIdentity(pt) {
372
+ return pt[0] === 0n && pt[1] === pt[3];
373
+ }
374
+ /**
375
+ * Validates an Aleo address by decoding the bech32m payload, decompressing
376
+ * the Edwards BLS12-377 point, and verifying it lies in the prime-order
377
+ * subgroup — matching snarkVM's `Group::from_x_coordinate` exactly.
378
+ *
379
+ * Compressed format: x-coordinate (little-endian, 32 bytes) with y-sign
380
+ * flag in bit 7 of byte 31.
381
+ */
382
+ function validateAleoAddress(address) {
383
+ try {
384
+ const decoded = bech32m.decodeToBytes(address);
385
+ if (decoded.prefix !== "aleo") return false;
386
+ if (decoded.bytes.length !== 32) return false;
387
+ const bytes = new Uint8Array(decoded.bytes);
388
+ bytes[31] = bytes[31] & 127;
389
+ let x = 0n;
390
+ for (let i = 31; i >= 0; i--) x = x << 8n | BigInt(bytes[i]);
391
+ if (x >= P) return false;
392
+ const x2 = x * x % P;
393
+ const num = (1n + x2) % P;
394
+ const den = ((1n - D * x2 % P) % P + P) % P;
395
+ if (den === 0n) return false;
396
+ const y = modSqrt(num * modPow(den, P - 2n, P) % P);
397
+ if (y === null) return false;
398
+ const negY = y === 0n ? 0n : P - y;
399
+ const p1 = [
400
+ x,
401
+ y,
402
+ x * y % P,
403
+ 1n
404
+ ];
405
+ const p2 = [
406
+ x,
407
+ negY,
408
+ x * negY % P,
409
+ 1n
410
+ ];
411
+ for (const pt of [p1, p2]) if (isIdentity(scalarMul(pt, SUBGROUP_ORDER))) return true;
412
+ return false;
413
+ } catch {
414
+ return false;
415
+ }
416
+ }
268
417
 
269
418
  //#endregion
270
419
  export { validateAddress };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defuse-protocol/intents-sdk",
3
- "version": "0.51.0",
3
+ "version": "0.52.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -46,7 +46,7 @@
46
46
  "valibot": "^1.0.0",
47
47
  "viem": "^2.0.0",
48
48
  "@defuse-protocol/contract-types": "0.6.0",
49
- "@defuse-protocol/internal-utils": "0.26.0"
49
+ "@defuse-protocol/internal-utils": "0.27.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "tsdown": "0.19.0"