@naculus/connect-appkit-core 0.2.8 → 0.4.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/dist/index.cjs CHANGED
@@ -37,6 +37,7 @@ __export(src_exports, {
37
37
  clearOneInAppNotification: () => clearOneInAppNotification,
38
38
  compareCostsKey: () => compareCostsKey,
39
39
  createDecimalsCache: () => createDecimalsCache,
40
+ createDelegationFrameworkAdapter: () => createDelegationFrameworkAdapter,
40
41
  createDelegationPolicyFlow: () => createDelegationPolicyFlow,
41
42
  createNotification: () => createNotification,
42
43
  createNotificationSettingsStorage: () => createNotificationSettingsStorage,
@@ -44,6 +45,7 @@ __export(src_exports, {
44
45
  defaultSiwxDomain: () => defaultSiwxDomain,
45
46
  defaultSiwxUri: () => defaultSiwxUri,
46
47
  describeChain: () => describeChain,
48
+ describePayment: () => describePayment,
47
49
  eip155ChainIdToNumber: () => eip155ChainIdToNumber,
48
50
  encodeErc20Approve: () => encodeErc20Approve,
49
51
  encodeErc20Transfer: () => encodeErc20Transfer,
@@ -871,8 +873,104 @@ function assertHexSignature(value) {
871
873
  return value;
872
874
  }
873
875
 
874
- // src/delegation-policy.ts
876
+ // src/delegation-framework-adapter.ts
875
877
  var import_connect_core15 = require("@naculus/connect-core");
878
+ function createDelegationFrameworkAdapter(options) {
879
+ const { manager, rpc, codec } = options;
880
+ return {
881
+ route: "eip7702",
882
+ async check({ policy }) {
883
+ const ready = policy.scope.mode === "eip7702" && policy.status === "active" && Boolean(policy.authorized);
884
+ return {
885
+ ready,
886
+ authorizationInstalled: ready,
887
+ sponsored: false,
888
+ promptless: true,
889
+ executorAddress: import_connect_core15.DELEGATION_FRAMEWORK.eip7702StatelessDeleGator,
890
+ reason: ready ? "The session key redeems its delegation; the chain enforces the caveats." : "This policy has no attached EIP-7702 delegation."
891
+ };
892
+ },
893
+ async prepare({ policy, transaction }) {
894
+ if (!transaction.to) {
895
+ throw new import_connect_core15.WalletError(
896
+ "invalid_input",
897
+ "A delegated execution needs a target."
898
+ );
899
+ }
900
+ let value;
901
+ try {
902
+ value = BigInt(transaction.value ?? "0");
903
+ } catch {
904
+ throw new import_connect_core15.WalletError(
905
+ "invalid_input",
906
+ "Transaction value is not a quantity."
907
+ );
908
+ }
909
+ const execution = {
910
+ target: transaction.to,
911
+ value,
912
+ callData: transaction.data ?? "0x"
913
+ };
914
+ const call = await manager.buildDelegationRedemption(
915
+ policy.id,
916
+ execution
917
+ );
918
+ const chainId = options.chainId();
919
+ if (chainId !== call.chainId) {
920
+ throw new import_connect_core15.WalletError(
921
+ "chain_mismatch",
922
+ `The delegation is for chain ${call.chainId}, not ${String(chainId)}.`
923
+ );
924
+ }
925
+ const from = (0, import_connect_core15.sessionKeyAddress)(policy.publicKey);
926
+ const [nonce, gas, fees] = await Promise.all([
927
+ rpc.getTransactionCount(from),
928
+ rpc.estimateGas({ from, to: call.to, data: call.data }),
929
+ rpc.fees()
930
+ ]);
931
+ const unsigned = {
932
+ type: "eip1559",
933
+ chainId,
934
+ nonce,
935
+ to: call.to,
936
+ value: 0n,
937
+ data: call.data,
938
+ gas,
939
+ maxFeePerGas: fees.maxFeePerGas,
940
+ maxPriorityFeePerGas: fees.maxPriorityFeePerGas
941
+ };
942
+ const payload = {
943
+ outerTx: {
944
+ to: call.to,
945
+ value: "0x0",
946
+ data: call.data,
947
+ chainId,
948
+ gas: `0x${gas.toString(16)}`
949
+ },
950
+ execution,
951
+ unsigned
952
+ };
953
+ return {
954
+ digest: codec.signingHash(unsigned),
955
+ transaction,
956
+ payload
957
+ };
958
+ },
959
+ async broadcast({ prepared, signature }) {
960
+ const { unsigned } = prepared.payload;
961
+ const hash = await rpc.sendRawTransaction(
962
+ codec.serialize(unsigned, signature)
963
+ );
964
+ return { route: "eip7702", hash, status: "submitted" };
965
+ }
966
+ };
967
+ }
968
+
969
+ // src/delegation-policy.ts
970
+ var import_connect_core16 = require("@naculus/connect-core");
971
+ function delegatesToStatelessDeleGator(delegation) {
972
+ return delegation.delegated === true && delegation.delegate?.toLowerCase() === import_connect_core16.DELEGATION_FRAMEWORK.eip7702StatelessDeleGator.toLowerCase();
973
+ }
876
974
  function sorted(values) {
877
975
  return values ? [...values].map((value) => value.toLowerCase()).sort() : null;
878
976
  }
@@ -919,12 +1017,13 @@ function buildDelegationPolicyMessage(policy, origin) {
919
1017
  ${JSON.stringify(payload)}`;
920
1018
  }
921
1019
  function isVerifiablePolicy(policy) {
922
- return policy.status === "active" && Boolean(policy.authorized) && policy.scope.mode === "offchain";
1020
+ return policy.status === "active" && Boolean(policy.authorized) && (policy.scope.mode === "offchain" || policy.scope.mode === "eip7702");
923
1021
  }
924
1022
  function createDelegationPolicyFlow(deps) {
925
1023
  const { manager, origin } = deps;
926
1024
  const verifyStoredPolicy = async (policy) => {
927
1025
  if (!isVerifiablePolicy(policy)) return false;
1026
+ if (policy.scope.mode === "eip7702") return true;
928
1027
  return manager.verifyOffchainAuthorization(
929
1028
  policy.id,
930
1029
  buildDelegationPolicyMessage(policy, origin),
@@ -934,28 +1033,29 @@ function createDelegationPolicyFlow(deps) {
934
1033
  const createPolicy = async (scope) => {
935
1034
  const signer = deps.signer();
936
1035
  if (!signer) {
937
- throw new import_connect_core15.WalletError("wallet_unavailable", "No active EVM account");
1036
+ throw new import_connect_core16.WalletError("wallet_unavailable", "No active EVM account");
938
1037
  }
1038
+ if (scope.mode === "eip7702") return createDelegatedPolicy(scope, signer);
939
1039
  if (scope.mode && scope.mode !== "offchain") {
940
- throw new import_connect_core15.WalletError(
1040
+ throw new import_connect_core16.WalletError(
941
1041
  "method_not_allowed",
942
- "This flow creates signed off-chain policies only. EIP-7702 and AA-module policies require a configured on-chain execution adapter."
1042
+ "This flow creates off-chain and EIP-7702 policies only; AA-module policies need an on-chain module."
943
1043
  );
944
1044
  }
945
1045
  if (scope.allowedRecipients && scope.allowedRecipients.length > 0) {
946
- throw new import_connect_core15.WalletError(
1046
+ throw new import_connect_core16.WalletError(
947
1047
  "method_not_allowed",
948
1048
  "Recipient-limited policies are not supported by this flow: its executions sign raw digests, which connect-core refuses while allowedRecipients is set."
949
1049
  );
950
1050
  }
951
1051
  if (!deps.encryptionKeyConfigured) {
952
- throw new import_connect_core15.WalletError(
1052
+ throw new import_connect_core16.WalletError(
953
1053
  "method_not_allowed",
954
1054
  "Persistent delegation policies require a host-provided encryptionKey. The deterministic compatibility fallback is not a production key boundary."
955
1055
  );
956
1056
  }
957
1057
  if (!deps.storageAvailable()) {
958
- throw new import_connect_core15.WalletError(
1058
+ throw new import_connect_core16.WalletError(
959
1059
  "storage_unavailable",
960
1060
  "Persistent delegation policy storage is unavailable in this browser"
961
1061
  );
@@ -969,7 +1069,7 @@ function createDelegationPolicyFlow(deps) {
969
1069
  const message = buildDelegationPolicyMessage(draft, origin);
970
1070
  const signature = await deps.signMessage(message);
971
1071
  if (!/^0x[0-9a-fA-F]{130}$/.test(signature)) {
972
- throw new import_connect_core15.WalletError(
1072
+ throw new import_connect_core16.WalletError(
973
1073
  "invalid_input",
974
1074
  "Wallet did not return a valid 65-byte EVM policy signature"
975
1075
  );
@@ -980,7 +1080,7 @@ function createDelegationPolicyFlow(deps) {
980
1080
  signerAddress: signer
981
1081
  });
982
1082
  if (!recovers) {
983
- throw new import_connect_core15.WalletError(
1083
+ throw new import_connect_core16.WalletError(
984
1084
  "invalid_input",
985
1085
  "Policy signature does not recover to the connected EVM account"
986
1086
  );
@@ -995,13 +1095,13 @@ function createDelegationPolicyFlow(deps) {
995
1095
  (policy) => policy.id === draft?.id
996
1096
  );
997
1097
  if (!authorized?.authorized) {
998
- throw new import_connect_core15.WalletError(
1098
+ throw new import_connect_core16.WalletError(
999
1099
  "invalid_input",
1000
1100
  "Policy authorization was not persisted"
1001
1101
  );
1002
1102
  }
1003
1103
  if (!await verifyStoredPolicy(authorized)) {
1004
- throw new import_connect_core15.WalletError(
1104
+ throw new import_connect_core16.WalletError(
1005
1105
  "invalid_input",
1006
1106
  "Persisted policy signature did not verify against its stored scope and origin"
1007
1107
  );
@@ -1018,6 +1118,66 @@ function createDelegationPolicyFlow(deps) {
1018
1118
  throw cause instanceof Error ? cause : new Error("Policy creation failed");
1019
1119
  }
1020
1120
  };
1121
+ const createDelegatedPolicy = async (scope, signer) => {
1122
+ if (!deps.signTypedData || !deps.chainId) {
1123
+ throw new import_connect_core16.WalletError(
1124
+ "method_not_allowed",
1125
+ "EIP-7702 policies need the wallet's signTypedData and the current chain."
1126
+ );
1127
+ }
1128
+ if (!deps.encryptionKeyConfigured) {
1129
+ throw new import_connect_core16.WalletError(
1130
+ "method_not_allowed",
1131
+ "Persistent delegation policies require a host-provided encryptionKey. The deterministic compatibility fallback is not a production key boundary."
1132
+ );
1133
+ }
1134
+ if (!deps.storageAvailable()) {
1135
+ throw new import_connect_core16.WalletError(
1136
+ "storage_unavailable",
1137
+ "Persistent delegation policy storage is unavailable in this browser"
1138
+ );
1139
+ }
1140
+ if (!delegatesToStatelessDeleGator(deps.delegation())) {
1141
+ throw new import_connect_core16.WalletError(
1142
+ "method_not_allowed",
1143
+ `The account must first delegate to EIP7702StatelessDeleGatorImpl (${import_connect_core16.DELEGATION_FRAMEWORK.eip7702StatelessDeleGator}).`
1144
+ );
1145
+ }
1146
+ const chainId = deps.chainId();
1147
+ if (chainId === null || !Number.isSafeInteger(chainId)) {
1148
+ throw new import_connect_core16.WalletError("wallet_unavailable", "No connected EVM chain");
1149
+ }
1150
+ let draft = null;
1151
+ try {
1152
+ draft = await manager.createSessionKey(
1153
+ { ...scope, mode: "eip7702" },
1154
+ signer
1155
+ );
1156
+ const delegation = await manager.prepareDelegation(draft.id, chainId);
1157
+ const signature = await deps.signTypedData(
1158
+ (0, import_connect_core16.delegationTypedData)(delegation)
1159
+ );
1160
+ if (!/^0x[0-9a-fA-F]{130}$/.test(signature)) {
1161
+ throw new import_connect_core16.WalletError(
1162
+ "invalid_input",
1163
+ "Wallet did not return a valid 65-byte EVM signature"
1164
+ );
1165
+ }
1166
+ await manager.attachDelegation(
1167
+ draft.id,
1168
+ delegation,
1169
+ signature
1170
+ );
1171
+ await deps.refresh();
1172
+ return (await manager.listSessions()).find((s) => s.id === draft?.id) ?? draft;
1173
+ } catch (cause) {
1174
+ if (draft) await manager.revokeSession(draft.id).catch(() => {
1175
+ });
1176
+ await deps.refresh().catch(() => {
1177
+ });
1178
+ throw cause;
1179
+ }
1180
+ };
1021
1181
  const revokePolicy = async (policyId) => {
1022
1182
  await manager.revokeSession(policyId);
1023
1183
  await deps.refresh();
@@ -1050,16 +1210,21 @@ function createDelegationPolicyFlow(deps) {
1050
1210
  const delegationMatches = Boolean(
1051
1211
  adapter?.route !== "eip7702" || delegation.delegated === true && adapterCheck?.executorAddress && delegation.delegate?.toLowerCase() === adapterCheck.executorAddress.toLowerCase()
1052
1212
  );
1213
+ const delegatedPolicy = policy?.scope.mode === "eip7702";
1053
1214
  const policyReady = Boolean(
1054
- policy?.status === "active" && policy.authorized && authorizationVerified && policy.scope.mode === "offchain" && signerMatches && scope.valid
1215
+ policy?.status === "active" && policy.authorized && authorizationVerified && (policy.scope.mode === "offchain" || delegatedPolicy) && signerMatches && scope.valid
1055
1216
  );
1056
1217
  const adapterSponsorshipReady = Boolean(
1057
1218
  deps.sponsorship !== "required" || adapterCheck?.sponsored
1058
1219
  );
1059
1220
  const broadcastReady = Boolean(
1060
- policyReady && callCount === 1 && adapterCheck?.ready && adapterCheck.authorizationInstalled && adapterCheck.promptless && adapterSponsorshipReady && delegationMatches
1221
+ policyReady && callCount === 1 && adapterCheck?.ready && adapterCheck.authorizationInstalled && adapterCheck.promptless && adapterSponsorshipReady && delegationMatches && // An eip7702 policy executes only through a redemption: the key
1222
+ // signs nothing else, so only an eip7702 adapter can carry it.
1223
+ (!delegatedPolicy || adapter?.route === "eip7702")
1224
+ );
1225
+ const ready = Boolean(
1226
+ policyReady && (delegatedPolicy ? broadcastReady : plan.route || broadcastReady)
1061
1227
  );
1062
- const ready = Boolean(policyReady && (plan.route || broadcastReady));
1063
1228
  const reason = !policy ? "Policy not found." : policy.status !== "active" ? `Policy is ${policy.status}.` : !policy.authorized ? "The main wallet has not signed this policy." : !authorizationVerified ? "The persisted policy signature no longer matches its scope, signer, or origin." : !signerMatches ? "The connected account is not the policy signer." : !scope.valid ? scope.reason ?? "The transaction is outside the policy scope." : broadcastReady ? `The configured ${adapter?.route ?? "AA/7702"} adapter can submit this policy-authorized operation without another main-wallet prompt.${adapterCheck?.sponsored ? " Gas sponsorship is guaranteed." : ""} ${adapterCheck?.reason ?? "The on-chain execution adapter is ready."}` : !adapter ? `${plan.reason} The signed off-chain policy permits this request; an AA/7702 adapter is still required to broadcast without another wallet prompt.` : !adapterCheck?.ready || !adapterCheck.authorizationInstalled ? `${plan.reason} ${adapterCheck?.reason ?? "The execution adapter is not ready."}` : !adapterCheck.promptless ? `${plan.reason} The configured adapter would invoke the main wallet again, so promptless broadcast is not ready.` : !adapterSponsorshipReady ? `${plan.reason} Sponsored gas is required, but the configured adapter does not guarantee sponsorship.` : callCount !== 1 ? `${plan.reason} This policy adapter prepares one execution at a time and cannot claim a multi-call broadcast.` : !delegationMatches ? `${plan.reason} The configured EIP-7702 executor does not match the account's on-chain delegation.` : !plan.route ? plan.reason : `${plan.reason} ${adapterCheck.reason}`;
1064
1229
  return {
1065
1230
  policy,
@@ -1085,37 +1250,76 @@ function createDelegationPolicyFlow(deps) {
1085
1250
  digest,
1086
1251
  tx
1087
1252
  );
1253
+ const signRedemption = (policyId, prepared) => {
1254
+ const payload = prepared.payload;
1255
+ if (!payload?.outerTx || !payload.execution) {
1256
+ throw new import_connect_core16.WalletError(
1257
+ "invalid_input",
1258
+ "The EIP-7702 adapter did not return a redemption to sign."
1259
+ );
1260
+ }
1261
+ if (prepared.transaction.chainId !== void 0 && prepared.transaction.chainId !== payload.outerTx.chainId) {
1262
+ throw new import_connect_core16.WalletError(
1263
+ "chain_mismatch",
1264
+ `The delegation is for chain ${String(payload.outerTx.chainId)}, not ${prepared.transaction.chainId}.`
1265
+ );
1266
+ }
1267
+ const { execution } = payload;
1268
+ if (typeof execution.value !== "bigint" || execution.value < 0n || !sameExecutionIntent(prepared.transaction, {
1269
+ to: execution.target,
1270
+ data: execution.callData,
1271
+ value: `0x${execution.value.toString(16)}`,
1272
+ chainId: prepared.transaction.chainId
1273
+ })) {
1274
+ throw new import_connect_core16.WalletError(
1275
+ "invalid_input",
1276
+ "The EIP-7702 adapter's execution differs from the requested transaction."
1277
+ );
1278
+ }
1279
+ return manager.signDelegationRedemption(
1280
+ policyId,
1281
+ prepared.digest,
1282
+ payload.outerTx,
1283
+ payload.execution
1284
+ );
1285
+ };
1088
1286
  const signPolicyDigest = async (policyId, digest, tx) => {
1089
1287
  const preview = await previewPolicyExecution(policyId, tx, 1, "any");
1288
+ if (preview.policy?.scope.mode === "eip7702") {
1289
+ throw new import_connect_core16.WalletError(
1290
+ "method_not_allowed",
1291
+ "An EIP-7702 policy signs only its delegation redemptions; use executePolicy."
1292
+ );
1293
+ }
1090
1294
  if (!preview.ready) {
1091
- throw new import_connect_core15.WalletError("method_not_allowed", preview.reason);
1295
+ throw new import_connect_core16.WalletError("method_not_allowed", preview.reason);
1092
1296
  }
1093
1297
  return signVerified(policyId, digest, tx);
1094
1298
  };
1095
1299
  const executePolicy = async (policyId, tx) => {
1096
1300
  const adapter = deps.adapter;
1097
1301
  if (!adapter) {
1098
- throw new import_connect_core15.WalletError(
1302
+ throw new import_connect_core16.WalletError(
1099
1303
  "method_not_allowed",
1100
1304
  "No session-policy-aware AA/7702 execution adapter is configured."
1101
1305
  );
1102
1306
  }
1103
1307
  const preview = await previewPolicyExecution(policyId, tx, 1, "any");
1104
1308
  if (!preview.broadcastReady || !preview.policy) {
1105
- throw new import_connect_core15.WalletError("method_not_allowed", preview.reason);
1309
+ throw new import_connect_core16.WalletError("method_not_allowed", preview.reason);
1106
1310
  }
1107
1311
  const prepared = await adapter.prepare({
1108
1312
  policy: preview.policy,
1109
1313
  transaction: tx
1110
1314
  });
1111
1315
  if (!/^0x[0-9a-fA-F]{64}$/.test(prepared.digest)) {
1112
- throw new import_connect_core15.WalletError(
1316
+ throw new import_connect_core16.WalletError(
1113
1317
  "invalid_input",
1114
1318
  "Execution adapter returned a digest that is not 32 bytes."
1115
1319
  );
1116
1320
  }
1117
1321
  if (!sameExecutionIntent(tx, prepared.transaction)) {
1118
- throw new import_connect_core15.WalletError(
1322
+ throw new import_connect_core16.WalletError(
1119
1323
  "invalid_input",
1120
1324
  "Execution adapter changed the requested target, value, data, or chain."
1121
1325
  );
@@ -1127,23 +1331,19 @@ function createDelegationPolicyFlow(deps) {
1127
1331
  const delegation = deps.delegation();
1128
1332
  const currentDelegationMatches = adapter.route !== "eip7702" || delegation.delegated === true && currentCheck.executorAddress !== void 0 && delegation.delegate?.toLowerCase() === currentCheck.executorAddress.toLowerCase();
1129
1333
  if (!currentCheck.ready || !currentCheck.authorizationInstalled || !currentCheck.promptless || deps.sponsorship === "required" && !currentCheck.sponsored || !currentDelegationMatches) {
1130
- throw new import_connect_core15.WalletError(
1334
+ throw new import_connect_core16.WalletError(
1131
1335
  "method_not_allowed",
1132
1336
  currentCheck.reason || "The on-chain policy authorization is not ready."
1133
1337
  );
1134
1338
  }
1135
- const signature = await signVerified(
1136
- policyId,
1137
- prepared.digest,
1138
- prepared.transaction
1139
- );
1339
+ const signature = preview.policy.scope.mode === "eip7702" ? await signRedemption(policyId, prepared) : await signVerified(policyId, prepared.digest, prepared.transaction);
1140
1340
  const submission = await adapter.broadcast({
1141
1341
  policy: preview.policy,
1142
1342
  prepared,
1143
1343
  signature
1144
1344
  });
1145
1345
  if (submission.route !== adapter.route || submission.status !== "submitted" || !/^0x[0-9a-fA-F]{64}$/.test(submission.hash)) {
1146
- throw new import_connect_core15.WalletError(
1346
+ throw new import_connect_core16.WalletError(
1147
1347
  "invalid_input",
1148
1348
  "Execution adapter returned an invalid submission result."
1149
1349
  );
@@ -1161,8 +1361,66 @@ function createDelegationPolicyFlow(deps) {
1161
1361
  };
1162
1362
  }
1163
1363
 
1364
+ // src/payment-fetch.ts
1365
+ function record(value) {
1366
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
1367
+ }
1368
+ function text(value) {
1369
+ return typeof value === "string" && value !== "" ? value : null;
1370
+ }
1371
+ function requestUrl(input) {
1372
+ if (input instanceof URL) return input.href;
1373
+ if (typeof input !== "string") return input.url;
1374
+ try {
1375
+ return new Request(input).url;
1376
+ } catch {
1377
+ return input;
1378
+ }
1379
+ }
1380
+ function describePayment(input, result) {
1381
+ const paid = record(result.paid);
1382
+ if (!paid) return null;
1383
+ const resource = requestUrl(input);
1384
+ if (typeof paid.scheme === "string" && typeof paid.network === "string") {
1385
+ const settlement = record(result.settlement);
1386
+ return {
1387
+ protocol: "x402",
1388
+ resource,
1389
+ chainId: text(paid.network),
1390
+ asset: text(paid.asset),
1391
+ payTo: text(paid.payTo),
1392
+ amount: text(paid.amount),
1393
+ // A hash reported for another chain is not this payment's.
1394
+ reference: settlement?.success === true && settlement.network === paid.network ? text(settlement.transaction) : null
1395
+ };
1396
+ }
1397
+ const challenge = record(record(paid.challenge)?.params);
1398
+ const request = record(paid.request);
1399
+ if (challenge && request) {
1400
+ const chainId = challenge.method === "evm" && typeof request.chainId === "number" && Number.isSafeInteger(request.chainId) ? `eip155:${request.chainId}` : challenge.method === "solana" && typeof request.network === "string" && /^solana:[1-9A-HJ-NP-Za-km-z]{32}$/.test(request.network) ? request.network : null;
1401
+ return {
1402
+ protocol: "mpp",
1403
+ resource,
1404
+ chainId,
1405
+ asset: text(request.currency),
1406
+ payTo: text(request.recipient),
1407
+ amount: text(request.amount),
1408
+ reference: text(record(result.receipt)?.reference)
1409
+ };
1410
+ }
1411
+ return {
1412
+ protocol: "unknown",
1413
+ resource,
1414
+ chainId: null,
1415
+ asset: null,
1416
+ payTo: null,
1417
+ amount: null,
1418
+ reference: null
1419
+ };
1420
+ }
1421
+
1164
1422
  // src/web3-store.ts
1165
- var import_connect_core16 = require("@naculus/connect-core");
1423
+ var import_connect_core17 = require("@naculus/connect-core");
1166
1424
  function withTimeout(promise, ms, label = "Operation") {
1167
1425
  let timeoutId;
1168
1426
  const timeout = new Promise((_, reject) => {
@@ -1184,7 +1442,7 @@ async function withRetry(fn, options) {
1184
1442
  lastError = error;
1185
1443
  if (attempt < options.maxRetries) {
1186
1444
  const delay = options.baseDelay * 2 ** attempt;
1187
- import_connect_core16.logger.warn(
1445
+ import_connect_core17.logger.warn(
1188
1446
  "appkit/core",
1189
1447
  `Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`
1190
1448
  );
@@ -1308,6 +1566,7 @@ function siwxResultToSession(result, now = /* @__PURE__ */ new Date()) {
1308
1566
  clearOneInAppNotification,
1309
1567
  compareCostsKey,
1310
1568
  createDecimalsCache,
1569
+ createDelegationFrameworkAdapter,
1311
1570
  createDelegationPolicyFlow,
1312
1571
  createNotification,
1313
1572
  createNotificationSettingsStorage,
@@ -1315,6 +1574,7 @@ function siwxResultToSession(result, now = /* @__PURE__ */ new Date()) {
1315
1574
  defaultSiwxDomain,
1316
1575
  defaultSiwxUri,
1317
1576
  describeChain,
1577
+ describePayment,
1318
1578
  eip155ChainIdToNumber,
1319
1579
  encodeErc20Approve,
1320
1580
  encodeErc20Transfer,