@aastar/sdk 0.24.1 → 0.25.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.
Files changed (132) hide show
  1. package/dist/UserClient-5PQP6APK.js +6 -0
  2. package/dist/{UserClient-KYDCMAIU.js.map → UserClient-5PQP6APK.js.map} +1 -1
  3. package/dist/UserClient-CD7R3335.cjs +15 -0
  4. package/dist/{UserClient-S6LS3CB6.cjs.map → UserClient-CD7R3335.cjs.map} +1 -1
  5. package/dist/account.cjs +8 -8
  6. package/dist/account.js +3 -3
  7. package/dist/addresses-D12T3kLs.d.cts +210 -0
  8. package/dist/addresses-D12T3kLs.d.ts +210 -0
  9. package/dist/admin.cjs +4 -4
  10. package/dist/admin.js +3 -3
  11. package/dist/airaccount.cjs +111 -103
  12. package/dist/airaccount.d.cts +1 -1
  13. package/dist/airaccount.d.ts +1 -1
  14. package/dist/airaccount.js +3 -3
  15. package/dist/channel.cjs +7 -7
  16. package/dist/channel.js +3 -3
  17. package/dist/{chunk-72JZKARR.cjs → chunk-2RHBOBL7.cjs} +6 -6
  18. package/dist/{chunk-72JZKARR.cjs.map → chunk-2RHBOBL7.cjs.map} +1 -1
  19. package/dist/{chunk-BYVG7MO7.js → chunk-6DZCDV4Q.js} +2137 -13
  20. package/dist/chunk-6DZCDV4Q.js.map +1 -0
  21. package/dist/{chunk-VEAYV52I.cjs → chunk-6IZASQSB.cjs} +236 -109
  22. package/dist/chunk-6IZASQSB.cjs.map +1 -0
  23. package/dist/{chunk-NVYVTCHJ.cjs → chunk-7HTUDNH3.cjs} +11 -11
  24. package/dist/{chunk-NVYVTCHJ.cjs.map → chunk-7HTUDNH3.cjs.map} +1 -1
  25. package/dist/{chunk-PNBK2CLK.js → chunk-7JVL5CU3.js} +3 -3
  26. package/dist/{chunk-PNBK2CLK.js.map → chunk-7JVL5CU3.js.map} +1 -1
  27. package/dist/{chunk-654GQ7G7.js → chunk-A4FO6FKN.js} +3 -3
  28. package/dist/{chunk-654GQ7G7.js.map → chunk-A4FO6FKN.js.map} +1 -1
  29. package/dist/{chunk-A4ICWCHR.cjs → chunk-CI4UJW5Y.cjs} +5 -5
  30. package/dist/{chunk-A4ICWCHR.cjs.map → chunk-CI4UJW5Y.cjs.map} +1 -1
  31. package/dist/{chunk-RZ2M2RVP.js → chunk-COTHBCR2.js} +3 -3
  32. package/dist/{chunk-RZ2M2RVP.js.map → chunk-COTHBCR2.js.map} +1 -1
  33. package/dist/{chunk-2UC7UPHV.js → chunk-D2RDBN46.js} +227 -102
  34. package/dist/chunk-D2RDBN46.js.map +1 -0
  35. package/dist/{chunk-WVOJV4Q5.cjs → chunk-FIMXPANS.cjs} +4 -4
  36. package/dist/{chunk-WVOJV4Q5.cjs.map → chunk-FIMXPANS.cjs.map} +1 -1
  37. package/dist/{chunk-MXJEULSE.cjs → chunk-G33MXEHU.cjs} +29 -2
  38. package/dist/chunk-G33MXEHU.cjs.map +1 -0
  39. package/dist/{chunk-D667CUUS.cjs → chunk-GASCTLKR.cjs} +9 -9
  40. package/dist/{chunk-D667CUUS.cjs.map → chunk-GASCTLKR.cjs.map} +1 -1
  41. package/dist/{chunk-PXQDAFXD.js → chunk-IG4BG25C.js} +6 -6
  42. package/dist/{chunk-PXQDAFXD.js.map → chunk-IG4BG25C.js.map} +1 -1
  43. package/dist/{chunk-5PH5CSM7.cjs → chunk-J3UAXGNP.cjs} +16 -16
  44. package/dist/{chunk-5PH5CSM7.cjs.map → chunk-J3UAXGNP.cjs.map} +1 -1
  45. package/dist/{chunk-WC25H5VG.js → chunk-JCEUTCFZ.js} +4 -4
  46. package/dist/{chunk-WC25H5VG.js.map → chunk-JCEUTCFZ.js.map} +1 -1
  47. package/dist/{chunk-MOJJ7QF6.cjs → chunk-KOWTQJIX.cjs} +2177 -49
  48. package/dist/chunk-KOWTQJIX.cjs.map +1 -0
  49. package/dist/chunk-L6D2AGTF.js +500 -0
  50. package/dist/chunk-L6D2AGTF.js.map +1 -0
  51. package/dist/{chunk-VHY6R2PI.cjs → chunk-LRPAX5AG.cjs} +32 -32
  52. package/dist/{chunk-VHY6R2PI.cjs.map → chunk-LRPAX5AG.cjs.map} +1 -1
  53. package/dist/{chunk-UCLK6LTB.js → chunk-MBWBHKUE.js} +28 -3
  54. package/dist/chunk-MBWBHKUE.js.map +1 -0
  55. package/dist/{chunk-BOVDJSMK.cjs → chunk-NHDZQPDE.cjs} +26 -26
  56. package/dist/{chunk-BOVDJSMK.cjs.map → chunk-NHDZQPDE.cjs.map} +1 -1
  57. package/dist/{chunk-HNJBQR5U.cjs → chunk-OBPTMV5W.cjs} +5 -5
  58. package/dist/{chunk-HNJBQR5U.cjs.map → chunk-OBPTMV5W.cjs.map} +1 -1
  59. package/dist/{chunk-JMW5AHLC.js → chunk-QTXPAGNX.js} +9 -9
  60. package/dist/{chunk-JMW5AHLC.js.map → chunk-QTXPAGNX.js.map} +1 -1
  61. package/dist/{chunk-WVJ4LQVB.js → chunk-UANSP3OK.js} +3 -3
  62. package/dist/{chunk-WVJ4LQVB.js.map → chunk-UANSP3OK.js.map} +1 -1
  63. package/dist/{chunk-DAMWXGKD.js → chunk-UTSFTWFC.js} +3 -3
  64. package/dist/{chunk-DAMWXGKD.js.map → chunk-UTSFTWFC.js.map} +1 -1
  65. package/dist/chunk-WTURYJEA.cjs +504 -0
  66. package/dist/chunk-WTURYJEA.cjs.map +1 -0
  67. package/dist/{chunk-LDARLWS3.js → chunk-YR7CTWY6.js} +3 -3
  68. package/dist/{chunk-LDARLWS3.js.map → chunk-YR7CTWY6.js.map} +1 -1
  69. package/dist/{contract-addresses-RABD77VP.cjs → contract-addresses-6K6IB5OB.cjs} +13 -13
  70. package/dist/{contract-addresses-RABD77VP.cjs.map → contract-addresses-6K6IB5OB.cjs.map} +1 -1
  71. package/dist/{contract-addresses-TVXSRQ7I.js → contract-addresses-CHZ7PK5H.js} +3 -3
  72. package/dist/{contract-addresses-TVXSRQ7I.js.map → contract-addresses-CHZ7PK5H.js.map} +1 -1
  73. package/dist/core.cjs +285 -261
  74. package/dist/core.d.cts +6 -175
  75. package/dist/core.d.ts +6 -175
  76. package/dist/core.js +2 -2
  77. package/dist/dapp.cjs +6 -6
  78. package/dist/dapp.js +3 -3
  79. package/dist/email.cjs +91 -0
  80. package/dist/email.cjs.map +1 -0
  81. package/dist/email.d.cts +115 -0
  82. package/dist/email.d.ts +115 -0
  83. package/dist/email.js +88 -0
  84. package/dist/email.js.map +1 -0
  85. package/dist/enduser.cjs +7 -7
  86. package/dist/enduser.js +4 -4
  87. package/dist/identity.cjs +6 -6
  88. package/dist/identity.js +3 -3
  89. package/dist/index.cjs +406 -374
  90. package/dist/index.d.cts +3 -2
  91. package/dist/index.d.ts +3 -2
  92. package/dist/index.js +17 -17
  93. package/dist/kms.cjs +111 -103
  94. package/dist/kms.d.cts +199 -19
  95. package/dist/kms.d.ts +199 -19
  96. package/dist/kms.js +3 -3
  97. package/dist/operator.cjs +7 -7
  98. package/dist/operator.js +3 -3
  99. package/dist/paymaster.cjs +16 -16
  100. package/dist/paymaster.js +3 -3
  101. package/dist/{src-N72HAQXS.cjs → src-DNURNUIA.cjs} +287 -263
  102. package/dist/src-DNURNUIA.cjs.map +1 -0
  103. package/dist/{src-72GWEAPA.cjs → src-DZDH3BSU.cjs} +18 -18
  104. package/dist/src-DZDH3BSU.cjs.map +1 -0
  105. package/dist/{src-UNS5B7FX.js → src-EVM7OESP.js} +5 -5
  106. package/dist/src-EVM7OESP.js.map +1 -0
  107. package/dist/src-FY3KAPPC.js +5 -0
  108. package/dist/src-FY3KAPPC.js.map +1 -0
  109. package/dist/tokens.cjs +12 -4
  110. package/dist/tokens.d.cts +133 -1
  111. package/dist/tokens.d.ts +133 -1
  112. package/dist/tokens.js +3 -3
  113. package/dist/x402.cjs +26 -26
  114. package/dist/x402.js +3 -3
  115. package/package.json +17 -2
  116. package/dist/UserClient-KYDCMAIU.js +0 -6
  117. package/dist/UserClient-S6LS3CB6.cjs +0 -15
  118. package/dist/chunk-2UC7UPHV.js.map +0 -1
  119. package/dist/chunk-7RVONA2R.js +0 -226
  120. package/dist/chunk-7RVONA2R.js.map +0 -1
  121. package/dist/chunk-BYVG7MO7.js.map +0 -1
  122. package/dist/chunk-GDH4DSVM.cjs +0 -228
  123. package/dist/chunk-GDH4DSVM.cjs.map +0 -1
  124. package/dist/chunk-MOJJ7QF6.cjs.map +0 -1
  125. package/dist/chunk-MXJEULSE.cjs.map +0 -1
  126. package/dist/chunk-UCLK6LTB.js.map +0 -1
  127. package/dist/chunk-VEAYV52I.cjs.map +0 -1
  128. package/dist/src-5URXSFKD.js +0 -5
  129. package/dist/src-5URXSFKD.js.map +0 -1
  130. package/dist/src-72GWEAPA.cjs.map +0 -1
  131. package/dist/src-N72HAQXS.cjs.map +0 -1
  132. package/dist/src-UNS5B7FX.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkXQROKLZI_cjs = require('./chunk-XQROKLZI.cjs');
4
- var chunkMOJJ7QF6_cjs = require('./chunk-MOJJ7QF6.cjs');
5
- var chunkMXJEULSE_cjs = require('./chunk-MXJEULSE.cjs');
4
+ var chunkKOWTQJIX_cjs = require('./chunk-KOWTQJIX.cjs');
5
+ var chunkG33MXEHU_cjs = require('./chunk-G33MXEHU.cjs');
6
6
  var viem = require('viem');
7
7
  var axios = require('axios');
8
8
  var crypto = require('crypto');
@@ -13,7 +13,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
13
  var axios__default = /*#__PURE__*/_interopDefault(axios);
14
14
 
15
15
  // ../airaccount/src/server/constants/entrypoint.ts
16
- var CORE_SEPOLIA = chunkMXJEULSE_cjs.CANONICAL_ADDRESSES[11155111];
16
+ var CORE_SEPOLIA = chunkG33MXEHU_cjs.CANONICAL_ADDRESSES[11155111];
17
17
  var EntryPointVersion = /* @__PURE__ */ ((EntryPointVersion2) => {
18
18
  EntryPointVersion2["V0_6"] = "0.6";
19
19
  EntryPointVersion2["V0_7"] = "0.7";
@@ -728,7 +728,7 @@ function toGuardianSpecs(p) {
728
728
  return specs;
729
729
  }
730
730
  function buildFullInitConfig(p) {
731
- return chunkMOJJ7QF6_cjs.buildInitConfig({
731
+ return chunkKOWTQJIX_cjs.buildInitConfig({
732
732
  guardians: toGuardianSpecs(p),
733
733
  dailyLimit: p.dailyLimit,
734
734
  ...p.approvedAlgIds ? { approvedAlgIds: p.approvedAlgIds } : {},
@@ -761,7 +761,7 @@ function initConfigFromRecord(record) {
761
761
  const guardians = record.guardianSpecs.map(
762
762
  (s) => "p256" in s ? { p256: { x: s.p256.x, y: s.p256.y } } : { ecdsa: s.ecdsa }
763
763
  );
764
- return chunkMOJJ7QF6_cjs.buildInitConfig({
764
+ return chunkKOWTQJIX_cjs.buildInitConfig({
765
765
  guardians,
766
766
  dailyLimit: record.dailyLimit ? BigInt(record.dailyLimit) : 0n,
767
767
  ...record.approvedAlgIds ? { approvedAlgIds: record.approvedAlgIds } : {},
@@ -1109,7 +1109,7 @@ var AccountManager = class {
1109
1109
  this.logger.log(
1110
1110
  `[AccountManager] account created with ${params.p256Guardians.length} P-256 guardian(s): ${accountAddress}`
1111
1111
  );
1112
- if (chunkMOJJ7QF6_cjs.needsValidatorRouter(config.approvedAlgIds)) {
1112
+ if (chunkKOWTQJIX_cjs.needsValidatorRouter(config.approvedAlgIds)) {
1113
1113
  this.logger.log(
1114
1114
  `[AccountManager] account ${accountAddress} approved a router-delegated algorithm (approvedAlgIds=[${config.approvedAlgIds.join(", ")}]); use deployAndWireValidator(userId, { walletClient }) to deploy + setValidator(router) in one call (or ensureValidatorRouter(userId) after a manual deploy) \u2014 required for those algIds to validate.`
1115
1115
  );
@@ -1146,11 +1146,11 @@ var AccountManager = class {
1146
1146
  if (!approvedAlgIds || approvedAlgIds.length === 0) {
1147
1147
  return { set: false, reason: "no approvedAlgIds / not router-delegated" };
1148
1148
  }
1149
- if (!chunkMOJJ7QF6_cjs.needsValidatorRouter(approvedAlgIds)) {
1149
+ if (!chunkKOWTQJIX_cjs.needsValidatorRouter(approvedAlgIds)) {
1150
1150
  return { set: false, reason: "no router-delegated algorithm" };
1151
1151
  }
1152
1152
  const chainId = this.ethereum.getChainId();
1153
- const canonicalRouter = chunkMXJEULSE_cjs.getCanonicalAddresses(chainId)?.aaStarValidator;
1153
+ const canonicalRouter = chunkG33MXEHU_cjs.getCanonicalAddresses(chainId)?.aaStarValidator;
1154
1154
  const router = opts?.router ?? canonicalRouter;
1155
1155
  if (!router || router.toLowerCase() === viem.zeroAddress) {
1156
1156
  return { set: false, reason: `no canonical validator router for chain ${chainId}` };
@@ -1176,7 +1176,7 @@ var AccountManager = class {
1176
1176
  router
1177
1177
  };
1178
1178
  }
1179
- const tx = await chunkMOJJ7QF6_cjs.airAccountActions(account.address)(walletClient).setValidator({
1179
+ const tx = await chunkKOWTQJIX_cjs.airAccountActions(account.address)(walletClient).setValidator({
1180
1180
  validator: router,
1181
1181
  account: walletClient.account
1182
1182
  });
@@ -1212,7 +1212,7 @@ var AccountManager = class {
1212
1212
  }
1213
1213
  if (!code || code === "0x") {
1214
1214
  const config = initConfigFromRecord(account);
1215
- deployTx = await chunkMOJJ7QF6_cjs.airAccountFactoryActions(account.factoryAddress)(walletClient).createAccount({
1215
+ deployTx = await chunkKOWTQJIX_cjs.airAccountFactoryActions(account.factoryAddress)(walletClient).createAccount({
1216
1216
  owner: account.signerAddress,
1217
1217
  salt: BigInt(account.salt),
1218
1218
  config,
@@ -1616,7 +1616,12 @@ var TransferManager = class {
1616
1616
  );
1617
1617
  const userOpHash = await this.ethereum.getUserOpHash(userOp, version);
1618
1618
  await this.signer.ensureSigner(userId);
1619
- const assertionCtx = params.passkeyAssertion ? { assertion: params.passkeyAssertion } : void 0;
1619
+ if (params.webAuthnAssertion && params.passkeyAssertion) {
1620
+ throw new Error(
1621
+ "Provide either webAuthnAssertion (preferred) or passkeyAssertion, not both."
1622
+ );
1623
+ }
1624
+ const assertionCtx = params.webAuthnAssertion ? { webAuthnAssertion: params.webAuthnAssertion } : params.passkeyAssertion ? { assertion: params.passkeyAssertion } : void 0;
1620
1625
  let useECDSA = false;
1621
1626
  let isCompositeValidator = false;
1622
1627
  if (version === "0.7" /* V0_7 */ || version === "0.8" /* V0_8 */) {
@@ -1626,6 +1631,11 @@ var TransferManager = class {
1626
1631
  account.address
1627
1632
  ));
1628
1633
  }
1634
+ if (assertionCtx && "webAuthnAssertion" in assertionCtx && !useECDSA && !(params.useAirAccountTiering && this.guardChecker)) {
1635
+ throw new Error(
1636
+ "A one-time webAuthnAssertion cannot authorize the legacy non-tiered BLS dual-sign (two owner signatures, one spent challenge). Use useAirAccountTiering:true (single owner signature), or supply two assertions via the legacy path."
1637
+ );
1638
+ }
1629
1639
  if (useECDSA) {
1630
1640
  const ecdsaSig = await this.signer.signMessage(
1631
1641
  userId,
@@ -2122,7 +2132,7 @@ var BLSSignatureService = class {
2122
2132
  }
2123
2133
  return nodes;
2124
2134
  }
2125
- async generateBLSSignature(userId, userOpHash, ctx) {
2135
+ async generateBLSSignature(userId, userOpHash, ctx, options) {
2126
2136
  const manager = await this.ensureInitialized();
2127
2137
  const activeNodes = await this.getActiveSignerNodes();
2128
2138
  if (activeNodes.length < 1) {
@@ -2181,11 +2191,7 @@ var BLSSignatureService = class {
2181
2191
  `Wallet address mismatch! Wallet: ${walletAddress}, Expected: ${account.signerAddress}`
2182
2192
  );
2183
2193
  }
2184
- const aaSignature = await this.signer.signMessage(
2185
- userId,
2186
- viem.hexToBytes(userOpHash),
2187
- ctx
2188
- );
2194
+ const aaSignature = options?.skipOwnerOpSignature ? "0x" : await this.signer.signMessage(userId, viem.hexToBytes(userOpHash), ctx);
2189
2195
  const messagePointHash = chunkXQROKLZI_cjs.keccak256(messagePoint);
2190
2196
  const messagePointSignature = await this.signer.signMessage(
2191
2197
  userId,
@@ -2202,6 +2208,11 @@ var BLSSignatureService = class {
2202
2208
  };
2203
2209
  }
2204
2210
  async packSignature(blsData) {
2211
+ if (!blsData.aaSignature || blsData.aaSignature === "0x") {
2212
+ throw new Error(
2213
+ "packSignature requires aaSignature; this BLSSignatureData was generated with skipOwnerOpSignature (Tier-2/3 only). Use packCumulativeT2/T3Signature instead."
2214
+ );
2215
+ }
2205
2216
  const manager = await this.ensureInitialized();
2206
2217
  return manager.packSignature(blsData);
2207
2218
  }
@@ -2231,7 +2242,9 @@ var BLSSignatureService = class {
2231
2242
  if (!p256Signature) {
2232
2243
  throw new Error(`P256 signature required for Tier ${tier}`);
2233
2244
  }
2234
- const blsData = await this.generateBLSSignature(userId, userOpHash, ctx);
2245
+ const blsData = await this.generateBLSSignature(userId, userOpHash, ctx, {
2246
+ skipOwnerOpSignature: true
2247
+ });
2235
2248
  if (tier === 2) {
2236
2249
  const t2Data = {
2237
2250
  p256Signature,
@@ -2259,6 +2272,84 @@ var BLSSignatureService = class {
2259
2272
  return manager.packCumulativeT3Signature(t3Data);
2260
2273
  }
2261
2274
  };
2275
+ var ALG_NAMES = {
2276
+ [chunkXQROKLZI_cjs.ALG_BLS]: "BLS (0x01)",
2277
+ [chunkXQROKLZI_cjs.ALG_ECDSA]: "ECDSA (0x02)",
2278
+ [chunkXQROKLZI_cjs.ALG_P256]: "P256 (0x03)",
2279
+ [chunkXQROKLZI_cjs.ALG_CUMULATIVE_T2]: "Cumulative T2 (0x04)",
2280
+ [chunkXQROKLZI_cjs.ALG_CUMULATIVE_T3]: "Cumulative T3 (0x05)"
2281
+ };
2282
+ var GuardChecker = class {
2283
+ constructor(ethereum, logger) {
2284
+ this.ethereum = ethereum;
2285
+ this.logger = logger ?? new ConsoleLogger("[GuardChecker]");
2286
+ }
2287
+ logger;
2288
+ /**
2289
+ * Fetch tier limits from an AirAccount contract.
2290
+ */
2291
+ async fetchTierConfig(accountAddress) {
2292
+ const account = this.ethereum.getAccountContract(accountAddress);
2293
+ return readAccountTierLimits(account);
2294
+ }
2295
+ /**
2296
+ * Fetch guard status from the account's GlobalGuard.
2297
+ */
2298
+ async fetchGuardStatus(accountAddress) {
2299
+ const account = this.ethereum.getAccountContract(accountAddress);
2300
+ const guardAddress = await readAccountGuardAddress(account);
2301
+ if (guardAddress === viem.zeroAddress) {
2302
+ return {
2303
+ hasGuard: false,
2304
+ guardAddress: viem.zeroAddress,
2305
+ dailyLimit: 0n,
2306
+ dailyRemaining: 0n
2307
+ };
2308
+ }
2309
+ const guard = viem.getContract({
2310
+ address: guardAddress,
2311
+ abi: viem.parseAbi(GLOBAL_GUARD_ABI),
2312
+ client: this.ethereum.getProvider()
2313
+ });
2314
+ const { dailyLimit, dailyRemaining } = await readGuardDailyAllowance(guard);
2315
+ return {
2316
+ hasGuard: true,
2317
+ guardAddress,
2318
+ dailyLimit,
2319
+ dailyRemaining
2320
+ };
2321
+ }
2322
+ /**
2323
+ * Pre-check a transaction: determine tier, check guard limits and algorithm approval.
2324
+ * Returns errors array (empty = OK to proceed).
2325
+ */
2326
+ async preCheck(accountAddress, value) {
2327
+ const errors = [];
2328
+ const tierConfig = await this.fetchTierConfig(accountAddress);
2329
+ const tier = chunkXQROKLZI_cjs.resolveTier(value, tierConfig);
2330
+ const algId = chunkXQROKLZI_cjs.algIdForTier(tier);
2331
+ const guard = await this.fetchGuardStatus(accountAddress);
2332
+ if (!guard.hasGuard) {
2333
+ return { ok: true, errors: [], tier, algId };
2334
+ }
2335
+ if (guard.dailyLimit > 0n && value > guard.dailyRemaining) {
2336
+ errors.push(
2337
+ `Daily limit exceeded: requesting ${value} wei but only ${guard.dailyRemaining} remaining (limit: ${guard.dailyLimit})`
2338
+ );
2339
+ }
2340
+ const accountContract = this.ethereum.getAccountContract(accountAddress);
2341
+ const isApproved = await readAlgorithmApproved(accountContract, algId);
2342
+ if (!isApproved) {
2343
+ errors.push(
2344
+ `Algorithm ${ALG_NAMES[algId] ?? `0x${algId.toString(16)}`} is not approved by the account`
2345
+ );
2346
+ }
2347
+ if (errors.length > 0) {
2348
+ this.logger.warn(`Pre-check failed for ${accountAddress}: ${errors.join("; ")}`);
2349
+ }
2350
+ return { ok: errors.length === 0, errors, tier, algId };
2351
+ }
2352
+ };
2262
2353
  var ERC20_ABI_PARSED = viem.parseAbi(ERC20_ABI);
2263
2354
  var TokenService = class {
2264
2355
  constructor(ethereum) {
@@ -2385,7 +2476,8 @@ var AirAccountServerClient = class {
2385
2476
  this.tokens,
2386
2477
  config.storage,
2387
2478
  config.signer,
2388
- logger
2479
+ logger,
2480
+ new GuardChecker(this.ethereum, logger)
2389
2481
  );
2390
2482
  }
2391
2483
  };
@@ -2920,84 +3012,6 @@ async function isOapdDeployed(provider, config) {
2920
3012
  const code = await provider.getCode({ address });
2921
3013
  return code !== void 0 && code !== "0x";
2922
3014
  }
2923
- var ALG_NAMES = {
2924
- [chunkXQROKLZI_cjs.ALG_BLS]: "BLS (0x01)",
2925
- [chunkXQROKLZI_cjs.ALG_ECDSA]: "ECDSA (0x02)",
2926
- [chunkXQROKLZI_cjs.ALG_P256]: "P256 (0x03)",
2927
- [chunkXQROKLZI_cjs.ALG_CUMULATIVE_T2]: "Cumulative T2 (0x04)",
2928
- [chunkXQROKLZI_cjs.ALG_CUMULATIVE_T3]: "Cumulative T3 (0x05)"
2929
- };
2930
- var GuardChecker = class {
2931
- constructor(ethereum, logger) {
2932
- this.ethereum = ethereum;
2933
- this.logger = logger ?? new ConsoleLogger("[GuardChecker]");
2934
- }
2935
- logger;
2936
- /**
2937
- * Fetch tier limits from an AirAccount contract.
2938
- */
2939
- async fetchTierConfig(accountAddress) {
2940
- const account = this.ethereum.getAccountContract(accountAddress);
2941
- return readAccountTierLimits(account);
2942
- }
2943
- /**
2944
- * Fetch guard status from the account's GlobalGuard.
2945
- */
2946
- async fetchGuardStatus(accountAddress) {
2947
- const account = this.ethereum.getAccountContract(accountAddress);
2948
- const guardAddress = await readAccountGuardAddress(account);
2949
- if (guardAddress === viem.zeroAddress) {
2950
- return {
2951
- hasGuard: false,
2952
- guardAddress: viem.zeroAddress,
2953
- dailyLimit: 0n,
2954
- dailyRemaining: 0n
2955
- };
2956
- }
2957
- const guard = viem.getContract({
2958
- address: guardAddress,
2959
- abi: viem.parseAbi(GLOBAL_GUARD_ABI),
2960
- client: this.ethereum.getProvider()
2961
- });
2962
- const { dailyLimit, dailyRemaining } = await readGuardDailyAllowance(guard);
2963
- return {
2964
- hasGuard: true,
2965
- guardAddress,
2966
- dailyLimit,
2967
- dailyRemaining
2968
- };
2969
- }
2970
- /**
2971
- * Pre-check a transaction: determine tier, check guard limits and algorithm approval.
2972
- * Returns errors array (empty = OK to proceed).
2973
- */
2974
- async preCheck(accountAddress, value) {
2975
- const errors = [];
2976
- const tierConfig = await this.fetchTierConfig(accountAddress);
2977
- const tier = chunkXQROKLZI_cjs.resolveTier(value, tierConfig);
2978
- const algId = chunkXQROKLZI_cjs.algIdForTier(tier);
2979
- const guard = await this.fetchGuardStatus(accountAddress);
2980
- if (!guard.hasGuard) {
2981
- return { ok: true, errors: [], tier, algId };
2982
- }
2983
- if (guard.dailyLimit > 0n && value > guard.dailyRemaining) {
2984
- errors.push(
2985
- `Daily limit exceeded: requesting ${value} wei but only ${guard.dailyRemaining} remaining (limit: ${guard.dailyLimit})`
2986
- );
2987
- }
2988
- const accountContract = this.ethereum.getAccountContract(accountAddress);
2989
- const isApproved = await readAlgorithmApproved(accountContract, algId);
2990
- if (!isApproved) {
2991
- errors.push(
2992
- `Algorithm ${ALG_NAMES[algId] ?? `0x${algId.toString(16)}`} is not approved by the account`
2993
- );
2994
- }
2995
- if (errors.length > 0) {
2996
- this.logger.warn(`Pre-check failed for ${accountAddress}: ${errors.join("; ")}`);
2997
- }
2998
- return { ok: errors.length === 0, errors, tier, algId };
2999
- }
3000
- };
3001
3015
  var FORCE_EXIT_ABI = [
3002
3016
  // ERC-7579 module lifecycle
3003
3017
  "function onInstall(bytes calldata data) external",
@@ -4250,14 +4264,21 @@ async function buildAuthenticationCredential(opts) {
4250
4264
  }
4251
4265
  };
4252
4266
  }
4267
+ function commitChallenge(nonceBase64Url, payload) {
4268
+ const nonce = base64UrlDecode(nonceBase64Url);
4269
+ const payloadBytes = typeof payload === "string" ? hexToBytes4(payload) : payload;
4270
+ const committed = crypto.createHash("sha256").update(nonce).update(payloadBytes).digest();
4271
+ return base64UrlEncode(new Uint8Array(committed));
4272
+ }
4253
4273
  async function runWebAuthnCeremony(begin, options) {
4254
4274
  const begun = await begin();
4255
- const challenge = begun?.Options?.challenge;
4256
- if (!begun?.ChallengeId || !challenge) {
4275
+ const nonce = begun?.Options?.challenge;
4276
+ if (!begun?.ChallengeId || !nonce) {
4257
4277
  throw new Error(
4258
4278
  "WebAuthn ceremony: begin endpoint did not return a ChallengeId + Options.challenge"
4259
4279
  );
4260
4280
  }
4281
+ const challenge = options.payload ? commitChallenge(nonce, options.payload) : nonce;
4261
4282
  const credential = await buildAuthenticationCredential({
4262
4283
  challenge,
4263
4284
  signer: options.signer,
@@ -4583,27 +4604,100 @@ var KmsManager = class {
4583
4604
  return this.client.post("/BeginAuthentication", { KeyId: keyId });
4584
4605
  }
4585
4606
  // ── Factory ─────────────────────────────────────────────────────
4607
+ /**
4608
+ * Create a KMS signer that authorizes each signature with a LEGACY raw passkey
4609
+ * assertion (reusable, no challenge consumption).
4610
+ *
4611
+ * @deprecated The KMS (v0.20.0+) rejects legacy raw passkey assertions for
4612
+ * signing/mutating operations (`/SignHash` → 400, "no challenge binding —
4613
+ * replayable"), unless `KMS_ALLOW_LEGACY_PASSKEY=1` is set on the KMS (test
4614
+ * only). Prefer {@link createKmsSignerWithCeremony}, which runs a one-time
4615
+ * challenge-bound WebAuthn ceremony per signature.
4616
+ */
4586
4617
  createKmsSigner(keyId, address, assertionProvider) {
4587
4618
  this.ensureEnabled();
4588
- return new KmsSigner(keyId, address, this, assertionProvider);
4619
+ return new KmsSigner(keyId, address, this, { mode: "legacy", assertionProvider });
4620
+ }
4621
+ /**
4622
+ * Create a KMS signer that authorizes each signature with a one-time,
4623
+ * challenge-bound WebAuthn ceremony (production-safe; replay-protected).
4624
+ *
4625
+ * Every `signMessage` call runs a FRESH ceremony (BeginAuthentication →
4626
+ * authenticator assertion → `/SignHash` with the `WebAuthn` field), because the
4627
+ * KMS consumes the challenge atomically (one challenge ⇒ one signature). A
4628
+ * Tier-2/3 BLS transfer that needs N owner signatures therefore triggers N
4629
+ * ceremonies — see {@link BLSSignatureService} (which now skips the unused
4630
+ * userOpHash owner-ECDSA for tiered signatures, so Tier-2 needs only one).
4631
+ *
4632
+ * @param ceremonySigner authenticator that signs the WebAuthn challenge
4633
+ * (a browser passkey on the client, or {@link P256PasskeySigner} server-side).
4634
+ */
4635
+ createKmsSignerWithCeremony(keyId, address, ceremonySigner, ceremonyOptions, commitPayload = false) {
4636
+ this.ensureEnabled();
4637
+ return new KmsSigner(keyId, address, this, {
4638
+ mode: "ceremony",
4639
+ ceremonySigner,
4640
+ ceremonyOptions,
4641
+ commitPayload
4642
+ });
4589
4643
  }
4590
4644
  };
4591
4645
  var KmsSigner = class {
4592
- constructor(keyId, _address, kmsManager, assertionProvider) {
4646
+ constructor(keyId, _address, kmsManager, auth) {
4593
4647
  this.keyId = keyId;
4594
4648
  this._address = _address;
4595
4649
  this.kmsManager = kmsManager;
4596
- this.assertionProvider = assertionProvider;
4650
+ this.auth = auth;
4597
4651
  }
4598
4652
  async getAddress() {
4599
4653
  return this._address;
4600
4654
  }
4601
- async signMessage(message) {
4655
+ /**
4656
+ * EIP-191 personal-sign over a digest. A string is hashed as UTF-8 text, a byte
4657
+ * array as raw bytes — byte-identical to ethers `hashMessage`.
4658
+ *
4659
+ * @param webAuthnAssertion OPTIONAL pre-built, one-time ceremony assertion. Use
4660
+ * this in server flows where the passkey lives on the USER's device: the
4661
+ * frontend runs the BeginAuthentication ceremony and the backend forwards the
4662
+ * resulting `{ ChallengeId, Credential }` here. When supplied it takes
4663
+ * precedence over the signer's baked-in auth mode. Each assertion is one-time
4664
+ * (the KMS consumes the challenge), so a caller that needs N signatures must
4665
+ * supply N distinct assertions.
4666
+ *
4667
+ * WYSIWYS (AirAccount #68): the frontend MUST build the assertion over the
4668
+ * payload-committed challenge `commitChallenge(nonce, hashOf(message))`, not the
4669
+ * raw nonce — otherwise a compromised host could swap the signed payload. The
4670
+ * raw-nonce assertion only works while the KMS runs in transition mode. (The
4671
+ * signer's own ceremony mode does this automatically.)
4672
+ */
4673
+ async signMessage(message, webAuthnAssertion) {
4602
4674
  const messageHash = hashMessage(message);
4603
- const assertion = await this.assertionProvider();
4604
- const signResponse = await this.kmsManager.signHash(messageHash, assertion, {
4605
- Address: this._address
4606
- });
4675
+ const target = { Address: this._address };
4676
+ if (webAuthnAssertion) {
4677
+ const signResponse2 = await this.kmsManager.signHashWithWebAuthn(
4678
+ messageHash,
4679
+ webAuthnAssertion.ChallengeId,
4680
+ webAuthnAssertion.Credential,
4681
+ target
4682
+ );
4683
+ return "0x" + signResponse2.Signature;
4684
+ }
4685
+ if (this.auth.mode === "ceremony") {
4686
+ const assertion2 = await this.kmsManager.runAuthenticationCeremony(
4687
+ this.keyId,
4688
+ this.auth.ceremonySigner,
4689
+ this.auth.commitPayload ? { ...this.auth.ceremonyOptions, payload: messageHash } : this.auth.ceremonyOptions
4690
+ );
4691
+ const signResponse2 = await this.kmsManager.signHashWithWebAuthn(
4692
+ messageHash,
4693
+ assertion2.ChallengeId,
4694
+ assertion2.Credential,
4695
+ target
4696
+ );
4697
+ return "0x" + signResponse2.Signature;
4698
+ }
4699
+ const assertion = await this.auth.assertionProvider();
4700
+ const signResponse = await this.kmsManager.signHash(messageHash, assertion, target);
4607
4701
  return "0x" + signResponse.Signature;
4608
4702
  }
4609
4703
  };
@@ -4989,6 +5083,37 @@ var LocalWalletSigner = class {
4989
5083
  return { address: this.account.address };
4990
5084
  }
4991
5085
  };
5086
+
5087
+ // ../airaccount/src/server/adapters/kms-signer-adapter.ts
5088
+ var KmsSignerAdapter = class {
5089
+ constructor(kms, resolveKey) {
5090
+ this.kms = kms;
5091
+ this.resolveKey = resolveKey;
5092
+ }
5093
+ async getAddress(userId) {
5094
+ return (await this.resolveKey(userId)).address;
5095
+ }
5096
+ async ensureSigner(userId) {
5097
+ return { address: (await this.resolveKey(userId)).address };
5098
+ }
5099
+ async signMessage(userId, message, ctx) {
5100
+ const { address } = await this.resolveKey(userId);
5101
+ const hash = hashMessage(message);
5102
+ const target = { Address: address };
5103
+ if (ctx && "webAuthnAssertion" in ctx) {
5104
+ const { ChallengeId, Credential } = ctx.webAuthnAssertion;
5105
+ const res = await this.kms.signHashWithWebAuthn(hash, ChallengeId, Credential, target);
5106
+ return "0x" + res.Signature;
5107
+ }
5108
+ if (ctx && "assertion" in ctx) {
5109
+ const res = await this.kms.signHash(hash, ctx.assertion, target);
5110
+ return "0x" + res.Signature;
5111
+ }
5112
+ throw new Error(
5113
+ "KmsSignerAdapter: KMS signing requires an auth context \u2014 pass a one-time WebAuthnCeremonyContext { webAuthnAssertion } (preferred)."
5114
+ );
5115
+ }
5116
+ };
4992
5117
  /*! Bundled license information:
4993
5118
 
4994
5119
  @noble/curves/nist.js:
@@ -5041,6 +5166,7 @@ exports.KmsMonitorService = KmsMonitorService;
5041
5166
  exports.KmsPaymentSigner = KmsPaymentSigner;
5042
5167
  exports.KmsSessionService = KmsSessionService;
5043
5168
  exports.KmsSigner = KmsSigner;
5169
+ exports.KmsSignerAdapter = KmsSignerAdapter;
5044
5170
  exports.L2_TYPE = L2_TYPE;
5045
5171
  exports.LocalWalletSigner = LocalWalletSigner;
5046
5172
  exports.MAX_GUARDIANS = MAX_GUARDIANS;
@@ -5076,6 +5202,7 @@ exports.buildClientDataJSON = buildClientDataJSON;
5076
5202
  exports.buildFullInitConfig = buildFullInitConfig;
5077
5203
  exports.buildInstallModuleHash = buildInstallModuleHash;
5078
5204
  exports.buildUninstallModuleHash = buildUninstallModuleHash;
5205
+ exports.commitChallenge = commitChallenge;
5079
5206
  exports.computeOapdSalt = computeOapdSalt;
5080
5207
  exports.erc8004AddressesForChain = erc8004AddressesForChain;
5081
5208
  exports.getOapdAddress = getOapdAddress;
@@ -5095,5 +5222,5 @@ exports.serializeGuardianSpecs = serializeGuardianSpecs;
5095
5222
  exports.toGuardianSpecs = toGuardianSpecs;
5096
5223
  exports.validateConfig = validateConfig;
5097
5224
  exports.wrapExecuteUserOp = wrapExecuteUserOp;
5098
- //# sourceMappingURL=chunk-VEAYV52I.cjs.map
5099
- //# sourceMappingURL=chunk-VEAYV52I.cjs.map
5225
+ //# sourceMappingURL=chunk-6IZASQSB.cjs.map
5226
+ //# sourceMappingURL=chunk-6IZASQSB.cjs.map