@hsuite/smart-engines-sdk 3.6.0 → 3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.6.1 — 2026-06-15
4
+
5
+ ### Fixed
6
+
7
+ - **`SmartGatewayClient.getReadiness()` no longer throws when the gateway is not ready.** The gateway's `/api/v3/ready` now returns **HTTP 503** (was 200) when not ready — honest readiness so load balancers / k8s probes can drain a degraded origin. `getReadiness()` now unwraps that 503: the gateway's global exception filter wraps the body as `{statusCode,error,message,context:{status:'not_ready',...}}` (payload under `context`; a non-filtered server's flat top-level body is also accepted), and the method still **resolves** to a `GatewayReadinessResponse` (`{status:'ready'|'not_ready'}`) in both the ready (200) and not-ready (503) cases. Return shape unchanged; genuine errors (non-readiness 503s, 5xx, network) still throw. (#1114)
8
+
3
9
  ## 3.5.0 — 2026-06-01
4
10
 
5
11
  **100% prod-ready arc.** Final cleanup pass after the 3.4.x publication. Closes every finding from two rounds of adversarial verification: legacy/dead-API code removed, BaaS dual-transport collapsed onto the shared HttpClient, path-traversal exposure closed via `encodePathParam` repo-wide, typed signer surfaces narrowed off `any`, test coverage taken from 62% → 90% statements / 49% → 81% branches / 64% → 85% functions / 63% → 91% lines, README + compodoc shipped, and one phantom test spec (615 lines that never imported the class it claimed to test) replaced with 43 real tests.
package/dist/index.d.ts CHANGED
@@ -487,6 +487,30 @@ declare const TokenInfoSchema: z.ZodObject<{
487
487
  circulatingSupply?: string | undefined;
488
488
  }>;
489
489
  export type TokenInfo = z.infer<typeof TokenInfoSchema>;
490
+ declare const RuleRefSchema: z.ZodObject<{
491
+ chain: z.ZodEnum<[
492
+ "hedera",
493
+ "xrpl",
494
+ "polkadot",
495
+ "solana",
496
+ "stellar",
497
+ "ethereum",
498
+ "polygon",
499
+ "bitcoin",
500
+ "cardano"
501
+ ]>;
502
+ topicId: z.ZodString;
503
+ consensusTimestamp: z.ZodString;
504
+ }, "strip", z.ZodTypeAny, {
505
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
506
+ topicId: string;
507
+ consensusTimestamp: string;
508
+ }, {
509
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
510
+ topicId: string;
511
+ consensusTimestamp: string;
512
+ }>;
513
+ export type RuleRefInput = z.infer<typeof RuleRefSchema>;
490
514
  declare const CreateAccountRequestSchema: z.ZodObject<{
491
515
  chain: z.ZodEnum<[
492
516
  "hedera",
@@ -511,6 +535,30 @@ declare const CreateAccountRequestSchema: z.ZodObject<{
511
535
  "full"
512
536
  ]>>;
513
537
  appOwnerPublicKey: z.ZodOptional<z.ZodString>;
538
+ ruleRef: z.ZodOptional<z.ZodObject<{
539
+ chain: z.ZodEnum<[
540
+ "hedera",
541
+ "xrpl",
542
+ "polkadot",
543
+ "solana",
544
+ "stellar",
545
+ "ethereum",
546
+ "polygon",
547
+ "bitcoin",
548
+ "cardano"
549
+ ]>;
550
+ topicId: z.ZodString;
551
+ consensusTimestamp: z.ZodString;
552
+ }, "strip", z.ZodTypeAny, {
553
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
554
+ topicId: string;
555
+ consensusTimestamp: string;
556
+ }, {
557
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
558
+ topicId: string;
559
+ consensusTimestamp: string;
560
+ }>>;
561
+ entityType: z.ZodOptional<z.ZodString>;
514
562
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
515
563
  }, "strip", z.ZodTypeAny, {
516
564
  chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
@@ -524,6 +572,12 @@ declare const CreateAccountRequestSchema: z.ZodObject<{
524
572
  appOwnerPublicKey?: string | undefined;
525
573
  memo?: string | undefined;
526
574
  payerAccountId?: string | undefined;
575
+ ruleRef?: {
576
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
577
+ topicId: string;
578
+ consensusTimestamp: string;
579
+ } | undefined;
580
+ entityType?: string | undefined;
527
581
  }, {
528
582
  chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
529
583
  initialBalance: string;
@@ -536,6 +590,12 @@ declare const CreateAccountRequestSchema: z.ZodObject<{
536
590
  memo?: string | undefined;
537
591
  payerAccountId?: string | undefined;
538
592
  immutable?: boolean | undefined;
593
+ ruleRef?: {
594
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
595
+ topicId: string;
596
+ consensusTimestamp: string;
597
+ } | undefined;
598
+ entityType?: string | undefined;
539
599
  }>;
540
600
  export type CreateAccountRequest = z.infer<typeof CreateAccountRequestSchema>;
541
601
  declare const CreateAccountResponseSchema: z.ZodObject<{
@@ -694,6 +754,30 @@ declare const CreateTokenRequestSchema: z.ZodObject<{
694
754
  validatorTopicId: z.ZodString;
695
755
  immutable: z.ZodDefault<z.ZodBoolean>;
696
756
  payerAccountId: z.ZodOptional<z.ZodString>;
757
+ ruleRef: z.ZodOptional<z.ZodObject<{
758
+ chain: z.ZodEnum<[
759
+ "hedera",
760
+ "xrpl",
761
+ "polkadot",
762
+ "solana",
763
+ "stellar",
764
+ "ethereum",
765
+ "polygon",
766
+ "bitcoin",
767
+ "cardano"
768
+ ]>;
769
+ topicId: z.ZodString;
770
+ consensusTimestamp: z.ZodString;
771
+ }, "strip", z.ZodTypeAny, {
772
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
773
+ topicId: string;
774
+ consensusTimestamp: string;
775
+ }, {
776
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
777
+ topicId: string;
778
+ consensusTimestamp: string;
779
+ }>>;
780
+ entityType: z.ZodOptional<z.ZodString>;
697
781
  metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
698
782
  }, "strip", z.ZodTypeAny, {
699
783
  symbol: string;
@@ -716,6 +800,12 @@ declare const CreateTokenRequestSchema: z.ZodObject<{
716
800
  initialSupply: string;
717
801
  metadata?: Record<string, any> | undefined;
718
802
  payerAccountId?: string | undefined;
803
+ ruleRef?: {
804
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
805
+ topicId: string;
806
+ consensusTimestamp: string;
807
+ } | undefined;
808
+ entityType?: string | undefined;
719
809
  treasury?: string | undefined;
720
810
  }, {
721
811
  symbol: string;
@@ -738,6 +828,12 @@ declare const CreateTokenRequestSchema: z.ZodObject<{
738
828
  metadata?: Record<string, any> | undefined;
739
829
  payerAccountId?: string | undefined;
740
830
  immutable?: boolean | undefined;
831
+ ruleRef?: {
832
+ chain: "hedera" | "xrpl" | "polkadot" | "solana" | "stellar" | "ethereum" | "polygon" | "bitcoin" | "cardano";
833
+ topicId: string;
834
+ consensusTimestamp: string;
835
+ } | undefined;
836
+ entityType?: string | undefined;
741
837
  treasury?: string | undefined;
742
838
  }>;
743
839
  export type CreateTokenRequest = z.infer<typeof CreateTokenRequestSchema>;
@@ -2591,6 +2687,8 @@ export type PrepareTransferRequest = {
2591
2687
  securityMode?: SecurityMode;
2592
2688
  appOwnerPublicKey?: string;
2593
2689
  ss58Format?: number;
2690
+ ruleRef?: RuleRefInput;
2691
+ entityType?: string;
2594
2692
  };
2595
2693
  export type PrepareNftMintRequest = {
2596
2694
  chain: ChainType;
@@ -3818,6 +3916,22 @@ export declare class AgentsClient {
3818
3916
  success: boolean;
3819
3917
  }>;
3820
3918
  }
3919
+ export type BuildAttestation = {
3920
+ readonly version: "1";
3921
+ readonly appId: string;
3922
+ readonly developerWallet: string;
3923
+ readonly developerChain: ChainType;
3924
+ readonly framework: "ionic" | "nestjs";
3925
+ readonly sdkVersion: string;
3926
+ readonly imageDigest: string;
3927
+ readonly bundleSha256: string;
3928
+ readonly cliVersion: string;
3929
+ readonly builtAt: number;
3930
+ };
3931
+ export declare function canonicalizeAttestation(att: BuildAttestation): string;
3932
+ export declare function computeAttestationHash(att: BuildAttestation): string;
3933
+ export declare function signAttestation(att: BuildAttestation, xrplSeed: string): string;
3934
+ export declare function verifyAttestation(att: BuildAttestation, signature: string, walletAddress: string): boolean;
3821
3935
  export type BaasService = "auth" | "database" | "storage" | "functions" | "messaging";
3822
3936
  export type BaasSupportedChain = "hedera" | "xrpl" | "polkadot" | "solana";
3823
3937
  export type BaasEndpoints = {
@@ -4146,6 +4260,10 @@ export type BaasDeployRequest = {
4146
4260
  memory?: string;
4147
4261
  };
4148
4262
  strategy?: "rolling" | "recreate";
4263
+ attestation?: {
4264
+ payload: BuildAttestation;
4265
+ signature: string;
4266
+ };
4149
4267
  };
4150
4268
  export type BaasDeployResponse = {
4151
4269
  appId: string;
package/dist/index.js CHANGED
@@ -78,11 +78,11 @@ var require_utils = __commonJS({
78
78
  u8Array[OriginalBuffer] = buffer;
79
79
  return u8Array;
80
80
  }
81
- var bytesToHex2 = (bytes) => {
81
+ var bytesToHex3 = (bytes) => {
82
82
  const buf = Buffer.from(bytes);
83
83
  return buf.toString("hex").toUpperCase();
84
84
  };
85
- exports.bytesToHex = bytesToHex2;
85
+ exports.bytesToHex = bytesToHex3;
86
86
  var hexToBytes2 = (hex) => {
87
87
  if (!shared_1.HEX_REGEX.test(hex)) {
88
88
  throw new Error("Invalid hex string");
@@ -479,7 +479,7 @@ var require_lib = __commonJS({
479
479
  return Uint8Array.from(res);
480
480
  }
481
481
  };
482
- var createBase58check = (sha2562) => /* @__PURE__ */ chain(checksum(4, (data) => sha2562(sha2562(data))), exports.base58);
482
+ var createBase58check = (sha2563) => /* @__PURE__ */ chain(checksum(4, (data) => sha2563(sha2563(data))), exports.base58);
483
483
  exports.createBase58check = createBase58check;
484
484
  exports.base58check = exports.createBase58check;
485
485
  var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join(""));
@@ -3062,7 +3062,7 @@ var require_weierstrass = __commonJS({
3062
3062
  }
3063
3063
  return { seed, k2sig };
3064
3064
  }
3065
- function sign(message, secretKey, opts = {}) {
3065
+ function sign2(message, secretKey, opts = {}) {
3066
3066
  message = (0, utils_ts_1.ensureBytes)("message", message);
3067
3067
  const { seed, k2sig } = prepSig(message, secretKey, opts);
3068
3068
  const drbg = (0, utils_ts_1.createHmacDrbg)(hash.outputLen, Fn.BYTES, hmac);
@@ -3096,7 +3096,7 @@ var require_weierstrass = __commonJS({
3096
3096
  return false;
3097
3097
  return sig;
3098
3098
  }
3099
- function verify(signature, message, publicKey, opts = {}) {
3099
+ function verify2(signature, message, publicKey, opts = {}) {
3100
3100
  const { lowS, prehash, format } = validateSigOpts(opts, defaultSigOpts);
3101
3101
  publicKey = (0, utils_ts_1.ensureBytes)("publicKey", publicKey);
3102
3102
  message = validateMsgAndHash((0, utils_ts_1.ensureBytes)("message", message), prehash);
@@ -3135,8 +3135,8 @@ var require_weierstrass = __commonJS({
3135
3135
  utils,
3136
3136
  lengths,
3137
3137
  Point,
3138
- sign,
3139
- verify,
3138
+ sign: sign2,
3139
+ verify: verify2,
3140
3140
  recoverPublicKey,
3141
3141
  Signature,
3142
3142
  hash
@@ -4326,7 +4326,7 @@ var require_edwards = __commonJS({
4326
4326
  const msg = (0, utils_ts_1.concatBytes)(...msgs);
4327
4327
  return modN_LE(cHash(domain(msg, (0, utils_ts_1.ensureBytes)("context", context), !!prehash)));
4328
4328
  }
4329
- function sign(msg, secretKey, options = {}) {
4329
+ function sign2(msg, secretKey, options = {}) {
4330
4330
  msg = (0, utils_ts_1.ensureBytes)("message", msg);
4331
4331
  if (prehash)
4332
4332
  msg = prehash(msg);
@@ -4341,7 +4341,7 @@ var require_edwards = __commonJS({
4341
4341
  return (0, utils_ts_1._abytes2)(rs, lengths.signature, "result");
4342
4342
  }
4343
4343
  const verifyOpts = { zip215: true };
4344
- function verify(sig, msg, publicKey, options = verifyOpts) {
4344
+ function verify2(sig, msg, publicKey, options = verifyOpts) {
4345
4345
  const { context, zip215 } = options;
4346
4346
  const len = lengths.signature;
4347
4347
  sig = (0, utils_ts_1.ensureBytes)("signature", sig, len);
@@ -4431,8 +4431,8 @@ var require_edwards = __commonJS({
4431
4431
  return Object.freeze({
4432
4432
  keygen,
4433
4433
  getPublicKey,
4434
- sign,
4435
- verify,
4434
+ sign: sign2,
4435
+ verify: verify2,
4436
4436
  utils,
4437
4437
  Point,
4438
4438
  lengths
@@ -5053,7 +5053,7 @@ var require_dist2 = __commonJS({
5053
5053
  return (0, ripple_address_codec_1.encodeSeed)(entropy, type);
5054
5054
  }
5055
5055
  exports.generateSeed = generateSeed;
5056
- function deriveKeypair(seed, options) {
5056
+ function deriveKeypair2(seed, options) {
5057
5057
  var _a;
5058
5058
  const decoded = (0, ripple_address_codec_1.decodeSeed)(seed);
5059
5059
  const proposedAlgorithm = (_a = options === null || options === void 0 ? void 0 : options.algorithm) !== null && _a !== void 0 ? _a : decoded.type;
@@ -5067,27 +5067,27 @@ var require_dist2 = __commonJS({
5067
5067
  }
5068
5068
  return keypair;
5069
5069
  }
5070
- exports.deriveKeypair = deriveKeypair;
5071
- function sign(messageHex, privateKey) {
5070
+ exports.deriveKeypair = deriveKeypair2;
5071
+ function sign2(messageHex, privateKey) {
5072
5072
  const algorithm = (0, getAlgorithmFromKey_1.getAlgorithmFromPrivateKey)(privateKey);
5073
5073
  return getSigningScheme(algorithm).sign((0, utils_1.hexToBytes)(messageHex), privateKey);
5074
5074
  }
5075
- exports.sign = sign;
5076
- function verify(messageHex, signature, publicKey) {
5075
+ exports.sign = sign2;
5076
+ function verify2(messageHex, signature, publicKey) {
5077
5077
  const algorithm = (0, getAlgorithmFromKey_1.getAlgorithmFromPublicKey)(publicKey);
5078
5078
  return getSigningScheme(algorithm).verify((0, utils_1.hexToBytes)(messageHex), signature, publicKey);
5079
5079
  }
5080
- exports.verify = verify;
5080
+ exports.verify = verify2;
5081
5081
  function computePublicKeyHash(publicKeyBytes) {
5082
5082
  return (0, ripemd160_1.ripemd160)((0, sha256_1.sha256)(publicKeyBytes));
5083
5083
  }
5084
5084
  function deriveAddressFromBytes(publicKeyBytes) {
5085
5085
  return (0, ripple_address_codec_1.encodeAccountID)(computePublicKeyHash(publicKeyBytes));
5086
5086
  }
5087
- function deriveAddress(publicKey) {
5087
+ function deriveAddress2(publicKey) {
5088
5088
  return deriveAddressFromBytes((0, utils_1.hexToBytes)(publicKey));
5089
5089
  }
5090
- exports.deriveAddress = deriveAddress;
5090
+ exports.deriveAddress = deriveAddress2;
5091
5091
  function deriveNodeAddress(publicKey) {
5092
5092
  const generatorBytes = (0, ripple_address_codec_1.decodeNodePublic)(publicKey);
5093
5093
  const accountPublicBytes = (0, utils_2.accountPublicFromPublicGenerator)(generatorBytes);
@@ -5643,6 +5643,14 @@ var PreparedTransactionSovereigntySchema = zod.z.discriminatedUnion("mode", [
5643
5643
  authorizationSet: PreparedTransactionAuthorizationSetSchema.optional()
5644
5644
  })
5645
5645
  ]);
5646
+ var RuleRefSchema = zod.z.object({
5647
+ /** Chain whose HCS the rule was published on (canonically 'hedera'). */
5648
+ chain: ChainTypeSchema,
5649
+ /** HCS topic ID the rule message was published to. */
5650
+ topicId: zod.z.string().min(1),
5651
+ /** HCS consensus timestamp of the rule message. */
5652
+ consensusTimestamp: zod.z.string().min(1)
5653
+ });
5646
5654
  var CreateAccountRequestSchema = zod.z.object({
5647
5655
  chain: ChainTypeSchema,
5648
5656
  initialBalance: zod.z.string(),
@@ -5682,6 +5690,22 @@ var CreateAccountRequestSchema = zod.z.object({
5682
5690
  * The owner key + TSS network key form a threshold-2 multi-sig.
5683
5691
  */
5684
5692
  appOwnerPublicKey: zod.z.string().optional(),
5693
+ /**
5694
+ * The entity's canonical `ruleRef` (HCS pointer to its `ValidatorRules`). When
5695
+ * present, the chain adapter stamps the IMMUTABLE creation-tx rule anchor
5696
+ * (`rule:<topicId>@<consensusTimestamp>:<entityType>`) — distinct from the
5697
+ * mutable validator-binding memo — so the sign-gate resolves the rule on-chain
5698
+ * (kind:'ref') rather than trusting the replicated binding
5699
+ * (RFC 2026-06-15-onchain-rule-anchor §6.1). Absent ⇒ the degraded
5700
+ * `rule:bootstrap:<entityType>` marker when `entityType` is supplied.
5701
+ */
5702
+ ruleRef: RuleRefSchema.optional(),
5703
+ /**
5704
+ * Entity-type tag stamped into the rule anchor (e.g. 'wallet', 'account').
5705
+ * Supply it to enable the on-chain anchor; omit for the prior memo-less
5706
+ * (legacy) behaviour.
5707
+ */
5708
+ entityType: zod.z.string().min(1).optional(),
5685
5709
  metadata: zod.z.record(zod.z.any()).optional()
5686
5710
  });
5687
5711
  zod.z.object({
@@ -5769,6 +5793,21 @@ var CreateTokenRequestSchema = zod.z.object({
5769
5793
  immutable: zod.z.boolean().default(true),
5770
5794
  /** See CreateAccountRequestSchema.payerAccountId — same resolution rules. */
5771
5795
  payerAccountId: zod.z.string().optional(),
5796
+ /**
5797
+ * The entity's canonical `ruleRef` (HCS pointer to its `ValidatorRules`). When
5798
+ * present, the chain adapter stamps the IMMUTABLE creation-tx rule anchor
5799
+ * (`rule:<topicId>@<consensusTimestamp>:<entityType>`) — distinct from the
5800
+ * mutable validator-binding token memo — so the sign-gate resolves the rule
5801
+ * on-chain (kind:'ref') rather than trusting the replicated binding
5802
+ * (RFC 2026-06-15-onchain-rule-anchor §6.1). Absent ⇒ the degraded
5803
+ * `rule:bootstrap:<entityType>` marker when `entityType` is supplied.
5804
+ */
5805
+ ruleRef: RuleRefSchema.optional(),
5806
+ /**
5807
+ * Entity-type tag stamped into the rule anchor (e.g. 'token'). Supply it to
5808
+ * enable the on-chain anchor; omit for the prior memo-less behaviour.
5809
+ */
5810
+ entityType: zod.z.string().min(1).optional(),
5772
5811
  metadata: zod.z.record(zod.z.any()).optional()
5773
5812
  });
5774
5813
  zod.z.object({
@@ -9688,11 +9727,28 @@ var SmartGatewayClient = class {
9688
9727
  return this.http.get("/status");
9689
9728
  }
9690
9729
  /**
9691
- * Check gateway readiness. Returns either `{ status: 'ready', ... }` with
9692
- * a verified host count or `{ status: 'not_ready', reason, ... }`.
9730
+ * Check gateway readiness. Resolves to either `{ status: 'ready', ... }`
9731
+ * with a verified host count or `{ status: 'not_ready', reason, ... }`.
9732
+ *
9733
+ * NOTE: `/api/v3/ready` returns **HTTP 503** when not ready (so load
9734
+ * balancers / k8s probes drain the origin). This method unwraps that 503's
9735
+ * body and still RESOLVES to a `GatewayReadinessResponse` — it does not
9736
+ * throw for a not-ready gateway. Genuine errors (non-readiness 503s, 5xx,
9737
+ * network) still throw.
9693
9738
  */
9694
9739
  async getReadiness() {
9695
- return this.http.get("/ready");
9740
+ try {
9741
+ return await this.http.get("/ready");
9742
+ } catch (err) {
9743
+ if (err instanceof SdkHttpError && err.statusCode === 503) {
9744
+ const d = err.details;
9745
+ const body = d?.context ?? d;
9746
+ if (body?.status === "not_ready") {
9747
+ return body;
9748
+ }
9749
+ }
9750
+ throw err;
9751
+ }
9696
9752
  }
9697
9753
  /** Check gateway liveness. */
9698
9754
  async getLiveness() {
@@ -11436,6 +11492,49 @@ async function verifyPqcEnvelope(envelope, options = {}) {
11436
11492
  }
11437
11493
  return { valid: true, version, details };
11438
11494
  }
11495
+ var { deriveKeypair, deriveAddress, sign, verify } = require_dist2();
11496
+ function canonicalizeAttestation(att) {
11497
+ return JSON.stringify(att, Object.keys(att).sort());
11498
+ }
11499
+ function computeAttestationHash(att) {
11500
+ const canonical = canonicalizeAttestation(att);
11501
+ const digest = sha256.sha256(new TextEncoder().encode(canonical));
11502
+ return bytesToHex2(digest);
11503
+ }
11504
+ function signAttestation(att, xrplSeed) {
11505
+ const { publicKey, privateKey } = deriveKeypair(xrplSeed);
11506
+ const messageHex = attestationMessageHex(att);
11507
+ const signature = sign(messageHex, privateKey);
11508
+ return `${publicKey}.${signature}`;
11509
+ }
11510
+ function verifyAttestation(att, signature, walletAddress) {
11511
+ try {
11512
+ const sep = signature.indexOf(".");
11513
+ if (sep <= 0 || sep === signature.length - 1) {
11514
+ return false;
11515
+ }
11516
+ const publicKey = signature.slice(0, sep);
11517
+ const sigHex = signature.slice(sep + 1);
11518
+ if (deriveAddress(publicKey) !== walletAddress) {
11519
+ return false;
11520
+ }
11521
+ const messageHex = attestationMessageHex(att);
11522
+ return verify(messageHex, sigHex, publicKey);
11523
+ } catch {
11524
+ return false;
11525
+ }
11526
+ }
11527
+ function attestationMessageHex(att) {
11528
+ const hash = computeAttestationHash(att);
11529
+ return Buffer.from(hash, "utf-8").toString("hex").toUpperCase();
11530
+ }
11531
+ function bytesToHex2(bytes) {
11532
+ let s = "";
11533
+ for (let i = 0; i < bytes.length; i++) {
11534
+ s += bytes[i].toString(16).padStart(2, "0");
11535
+ }
11536
+ return s;
11537
+ }
11439
11538
 
11440
11539
  // src/rules/atoms/index.ts
11441
11540
  var atom = {
@@ -12940,7 +13039,9 @@ exports.atom = atom;
12940
13039
  exports.auth = auth_exports;
12941
13040
  exports.baas = baas_exports;
12942
13041
  exports.bridge = bridge_exports;
13042
+ exports.canonicalizeAttestation = canonicalizeAttestation;
12943
13043
  exports.chains = chains_exports;
13044
+ exports.computeAttestationHash = computeAttestationHash;
12944
13045
  exports.createHttpClient = createHttpClient;
12945
13046
  exports.createResilientFetchWithBreaker = createResilientFetchWithBreaker;
12946
13047
  exports.createXrplWeb3Signer = createXrplWeb3Signer;
@@ -12974,6 +13075,7 @@ exports.resilientFetch = resilientFetch;
12974
13075
  exports.resolveNetwork = resolveNetwork;
12975
13076
  exports.resources = resources_exports;
12976
13077
  exports.settlement = settlement_exports;
13078
+ exports.signAttestation = signAttestation;
12977
13079
  exports.simpleAMM = simpleAMM;
12978
13080
  exports.simpleStaking = simpleStaking;
12979
13081
  exports.soulboundNft = soulboundNft;
@@ -12989,6 +13091,7 @@ exports.utilityToken = utilityToken;
12989
13091
  exports.validate = validate;
12990
13092
  exports.validateAgentRules = validateAgentRules;
12991
13093
  exports.validateEnvelopeSchema = validateEnvelopeSchema;
13094
+ exports.verifyAttestation = verifyAttestation;
12992
13095
  exports.verifyPqcAttestation = verifyPqcAttestation;
12993
13096
  exports.verifyPqcEnvelope = verifyPqcEnvelope;
12994
13097
  exports.vestingSchedule = vestingSchedule;