@fased/fased 0.1.64 → 0.1.65

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 (91) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +16 -9
  3. package/config/signer-policies/README.md +10 -1
  4. package/config/signer-protocol-v2.json +2 -0
  5. package/dist/brand.js +1 -1
  6. package/dist/build-info.json +3 -3
  7. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  8. package/dist/control-ui/assets/{app-bR-fO5ty.js → app-MaQnPa5G.js} +5 -5
  9. package/dist/control-ui/assets/{index-ckCxHwjy.js → index-D4YMr1fA.js} +3 -3
  10. package/dist/control-ui/assets/{mining-BgHFh0ei.js → mining-qMYs4aD-.js} +120 -120
  11. package/dist/control-ui/index.html +1 -1
  12. package/dist/control-ui/version.json +1 -1
  13. package/dist/extensions/sat-mining/src/rpc-read.js +59 -20
  14. package/dist/extensions/sat-mining/src/solana-submit.js +251 -8
  15. package/dist/extensions/sat-mining/src/submission-ledger.js +1 -1
  16. package/dist/plugin-sdk/{audio-preflight-BYxAt775.js → audio-preflight-I4IngVlJ.js} +1 -1
  17. package/dist/plugin-sdk/channel-plugin-common.d.ts +2 -2
  18. package/dist/plugin-sdk/{chunk-items-DIRHG2gJ.js → chunk-items-DLQ6_lLK.js} +1 -1
  19. package/dist/plugin-sdk/command-status.js +1 -1
  20. package/dist/plugin-sdk/{config-schema-BOT7kHb6.js → config-schema-D_8FVI1C.js} +28 -8
  21. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  22. package/dist/plugin-sdk/discord.d.ts +3 -3
  23. package/dist/plugin-sdk/index.d.ts +5 -5
  24. package/dist/plugin-sdk/index.js +1 -1
  25. package/dist/plugin-sdk/{monitor-BCFDaqJ-.js → monitor-B4KF4Kpo.js} +3 -3
  26. package/dist/plugin-sdk/{monitor-BgbjRiPM.js → monitor-Bb6x1KAG.js} +3 -3
  27. package/dist/plugin-sdk/{openresponses-http-DFf87SMM.js → openresponses-http-DCTO8JkL.js} +1 -1
  28. package/dist/plugin-sdk/{pairing-message-CS-9BHug.d.ts → pairing-message-DHPDFZbC.d.ts} +1 -1
  29. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +1 -1
  30. package/dist/plugin-sdk/sat-runtime.d.ts +18 -2
  31. package/dist/plugin-sdk/sat-runtime.js +1 -1
  32. package/dist/plugin-sdk/{slack-BUTt8cxK.js → slack-BHmvqgjH.js} +3 -3
  33. package/dist/plugin-sdk/slack.d.ts +3 -3
  34. package/dist/plugin-sdk/{sticker-cache-D0wHVqjt.js → sticker-cache-By5AcorL.js} +2 -2
  35. package/dist/plugin-sdk/{telegram-actions-CC_qN4v0.js → telegram-actions-DGnBz1YT.js} +2 -2
  36. package/dist/plugin-sdk/telegram.d.ts +3 -3
  37. package/dist/plugin-sdk/{tmp-fased-dir-xOTGlzBE.d.ts → tmp-fased-dir-EJGTmL1Q.d.ts} +1 -1
  38. package/dist/plugin-sdk/{types-C3avNytw.d.ts → types-BdwdFCD6.d.ts} +2 -2
  39. package/dist/plugin-sdk/{types-DWfbSAaM.d.ts → types-BrCpYMxn.d.ts} +1 -1
  40. package/dist/plugin-sdk/{web-BXsJ1vqe.js → web-DUJwrTYs.js} +1 -1
  41. package/dist/plugin-sdk/whatsapp.d.ts +3 -3
  42. package/dist/wallet/local-socket-signer-protocol.js +18 -0
  43. package/dist/wallet/signer-protocol-v2.generated.js +2 -0
  44. package/dist/wallet/wallet-policy.js +3 -1
  45. package/extensions/acpx/package.json +1 -1
  46. package/extensions/bluebubbles/package.json +1 -1
  47. package/extensions/copilot-proxy/package.json +1 -1
  48. package/extensions/diagnostics-otel/package.json +1 -1
  49. package/extensions/fased-federation/package.json +1 -1
  50. package/extensions/google-gemini-cli-auth/package.json +1 -1
  51. package/extensions/imessage/package.json +1 -1
  52. package/extensions/irc/package.json +1 -1
  53. package/extensions/line/package.json +1 -1
  54. package/extensions/llm-task/package.json +1 -1
  55. package/extensions/lobster/package.json +1 -1
  56. package/extensions/matrix/CHANGELOG.md +6 -0
  57. package/extensions/matrix/package.json +1 -1
  58. package/extensions/mattermost/package.json +1 -1
  59. package/extensions/memory-core/package.json +2 -2
  60. package/extensions/memory-lancedb/package.json +1 -1
  61. package/extensions/minimax-portal-auth/package.json +1 -1
  62. package/extensions/msteams/CHANGELOG.md +6 -0
  63. package/extensions/msteams/package.json +1 -1
  64. package/extensions/nextcloud-talk/package.json +1 -1
  65. package/extensions/nostr/CHANGELOG.md +6 -0
  66. package/extensions/nostr/package.json +1 -1
  67. package/extensions/open-prose/package.json +1 -1
  68. package/extensions/sat-mining/index.ts +89 -1
  69. package/extensions/sat-mining/package.json +1 -1
  70. package/extensions/sat-mining/src/audit-store.ts +45 -4
  71. package/extensions/sat-mining/src/client.ts +13 -0
  72. package/extensions/sat-mining/src/rpc-read.ts +105 -21
  73. package/extensions/sat-mining/src/runtime.ts +2 -0
  74. package/extensions/sat-mining/src/solana-submit.ts +358 -21
  75. package/extensions/sat-mining/src/submission-ledger.ts +2 -1
  76. package/extensions/signal/package.json +1 -1
  77. package/extensions/synology-chat/package.json +1 -1
  78. package/extensions/tlon/package.json +1 -1
  79. package/extensions/twitch/CHANGELOG.md +6 -0
  80. package/extensions/twitch/package.json +1 -1
  81. package/extensions/voice-call/CHANGELOG.md +6 -0
  82. package/extensions/voice-call/package.json +1 -1
  83. package/extensions/zalo/CHANGELOG.md +6 -0
  84. package/extensions/zalo/package.json +1 -1
  85. package/extensions/zalouser/CHANGELOG.md +6 -0
  86. package/extensions/zalouser/package.json +1 -1
  87. package/install.sh +14 -18
  88. package/package.json +1 -1
  89. package/scripts/fased-managed-updater.mjs +1 -1
  90. package/scripts/fased-signer-owner-policy.mjs +13 -1
  91. package/scripts/start-managed.sh +4 -0
@@ -14,7 +14,7 @@
14
14
  <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
15
15
  <link rel="apple-touch-icon" sizes="180x180" href="./apple-touch-icon.png" />
16
16
  <script data-fased-boot-watchdog src="./boot-watchdog.js" defer></script>
17
- <script type="module" crossorigin src="./assets/index-ckCxHwjy.js"></script>
17
+ <script type="module" crossorigin src="./assets/index-D4YMr1fA.js"></script>
18
18
  <link rel="stylesheet" crossorigin href="./assets/index-RwVraC3c.css">
19
19
  </head>
20
20
  <body>
@@ -1 +1 @@
1
- {"version":"0.1.64"}
1
+ {"version":"0.1.65"}
@@ -25,6 +25,7 @@ const SAT_DISPUTE_SEED = "sat_dispute";
25
25
  const MINING_STAKE_SEED = "mining_stake";
26
26
  const TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
27
27
  const ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
28
+ const ADDRESS_LOOKUP_TABLE_PROGRAM_ID = "AddressLookupTab1e1111111111111111111111111";
28
29
  function assertDedicatedBondProgramConfigured(env = process.env) {
29
30
  const resolved = resolveSatBondProgramIdFromEnv(env);
30
31
  if (!resolved.trim()) {
@@ -578,7 +579,8 @@ function decodeSatCycleSettlementProgressV2(data, address) {
578
579
  finalizeExclusiveUntilSlot: readU64Number(body, 984),
579
580
  scoreExclusiveUntilSlot: readU64Number(body, 992),
580
581
  distributeExclusiveUntilSlot: readU64Number(body, 1e3),
581
- keeperBountyPaidLamports: readU64String(body, 1008)
582
+ keeperBountyPaidLamports: readU64String(body, 1008),
583
+ keeperBountyUnpaidLamports: readU64String(body, 1016)
582
584
  };
583
585
  }
584
586
  function decodeSatTreasuryState(data, address) {
@@ -1269,7 +1271,7 @@ function createReadConnection(solana, rpc) {
1269
1271
  try {
1270
1272
  return await callEndpoint(secondary, "fallback", rpc.secondaryUrl);
1271
1273
  } catch (secondaryError) {
1272
- throw new Error(`rpc ${method} failed on primary (${String(primaryError instanceof Error ? primaryError.message : primaryError)}) and fallback (${String(secondaryError instanceof Error ? secondaryError.message : secondaryError)})`);
1274
+ throw new Error(`rpc ${method} failed on primary (${String(redactSensitiveUrlLikeString(primaryError instanceof Error ? primaryError.message : String(primaryError)))}) and fallback (${String(redactSensitiveUrlLikeString(secondaryError instanceof Error ? secondaryError.message : String(secondaryError)))})`);
1273
1275
  }
1274
1276
  }
1275
1277
  });
@@ -1312,12 +1314,18 @@ async function resolveBondProgramContext(env) {
1312
1314
  programId: new solana.PublicKey(SAT_BOND_PROGRAM_ID())
1313
1315
  };
1314
1316
  }
1315
- const SAT_PROTOCOL_VAULT_ACCOUNT_SPACE = 0;
1316
- const SAT_CYCLE_STATE_ACCOUNT_SPACE = 336;
1317
- const SAT_CYCLE_REGISTRY_META_ACCOUNT_SPACE = 88;
1318
- const SAT_CYCLE_REGISTRY_PAGE_ACCOUNT_SPACE = 2072;
1319
- const SAT_CYCLE_SETTLEMENT_PROGRESS_V2_ACCOUNT_SPACE = 1048;
1320
- const SAT_MINER_CYCLE_ACCOUNT_SPACE = 296;
1317
+ const SAT_RENT_ACCOUNT_SPACES = {
1318
+ protocolVault: 0,
1319
+ cycleState: 376,
1320
+ cycleRegistryMeta: 88,
1321
+ cycleRegistryPage: 2072,
1322
+ cycleSettlementProgressV2: 1048,
1323
+ minerCycle: 352,
1324
+ unlockInterval: 80
1325
+ };
1326
+ function calculateSatRevealSharedRentLamports(params) {
1327
+ return params.cycleSettlementProgressLamports + params.cycleRegistryPageLamports + params.unlockIntervalLamports;
1328
+ }
1321
1329
  function normalizeReadRpcConfig(rpc) {
1322
1330
  return typeof rpc === "string" ? {
1323
1331
  primaryUrl: rpc,
@@ -1376,7 +1384,7 @@ async function rpcRequestOnce(rpcUrl, method, params) {
1376
1384
  });
1377
1385
  });
1378
1386
  req.setTimeout(satRpcRequestTimeoutMs(), () => {
1379
- req.destroy(new Error(`rpc ${method} timed out after ${satRpcRequestTimeoutMs()}ms (${rpcUrl})`));
1387
+ req.destroy(new Error(`rpc ${method} timed out after ${satRpcRequestTimeoutMs()}ms (${redactSensitiveUrlLikeString(rpcUrl)})`));
1380
1388
  });
1381
1389
  req.on("error", (error) => finishReject(error));
1382
1390
  req.write(body);
@@ -1422,8 +1430,8 @@ async function rpcRequest(rpc, method, params) {
1422
1430
  return result;
1423
1431
  } catch (secondaryError) {
1424
1432
  markReadRpcFailure(secondaryError, normalized.secondaryUrl);
1425
- const primaryMessage = primaryError instanceof Error ? primaryError.message : String(primaryError);
1426
- const secondaryMessage = secondaryError instanceof Error ? secondaryError.message : String(secondaryError);
1433
+ const primaryMessage = redactSensitiveUrlLikeString(primaryError instanceof Error ? primaryError.message : String(primaryError));
1434
+ const secondaryMessage = redactSensitiveUrlLikeString(secondaryError instanceof Error ? secondaryError.message : String(secondaryError));
1427
1435
  throw new Error(`rpc ${method} failed on primary (${primaryMessage}) and fallback (${secondaryMessage})`);
1428
1436
  }
1429
1437
  }
@@ -1569,6 +1577,25 @@ async function inspectSatChainSlot(_config) {
1569
1577
  const rpc = resolveEffectiveReadRpcConfig();
1570
1578
  return await rpcRequest(rpc, "getSlot", []);
1571
1579
  }
1580
+ async function inspectSatAddressLookupTable(_config, params) {
1581
+ const { solana, connection } = await resolveConnection(process.env);
1582
+ const address = new solana.PublicKey(params.address);
1583
+ const account = await connection.getAccountInfo(address, "confirmed");
1584
+ if (!account) {
1585
+ return null;
1586
+ }
1587
+ if (!account.owner.equals(new solana.PublicKey(ADDRESS_LOOKUP_TABLE_PROGRAM_ID))) {
1588
+ throw new Error("SAT distribution lookup table has the wrong program owner");
1589
+ }
1590
+ const state = solana.AddressLookupTableAccount.deserialize(account.data);
1591
+ return {
1592
+ address: address.toBase58(),
1593
+ authority: state.authority?.toBase58() ?? null,
1594
+ addresses: state.addresses.map((entry) => entry.toBase58()),
1595
+ active: state.deactivationSlot === 18446744073709551615n,
1596
+ lastExtendedSlot: state.lastExtendedSlot
1597
+ };
1598
+ }
1572
1599
  async function inspectSatLamportBalance(_config, params) {
1573
1600
  const rpc = resolveEffectiveReadRpcConfig();
1574
1601
  return await fetchLamportBalanceRaw(rpc, params.address);
@@ -1728,6 +1755,7 @@ async function inspectSatMiningStatusAccounts(_config, params) {
1728
1755
  const mint = new solana.PublicKey(SAT_MINT_ADDRESS());
1729
1756
  const [globalAddress] = solana.PublicKey.findProgramAddressSync([Buffer.from("sat_global_state")], programId);
1730
1757
  const [currentCycleAddress] = solana.PublicKey.findProgramAddressSync([Buffer.from("sat_cycle_state"), encodeU64(currentCycleId)], programId);
1758
+ const [currentSettlementProgressAddress] = solana.PublicKey.findProgramAddressSync([Buffer.from("sat_cycle_settlement_progress_v2"), encodeU64(currentCycleId)], programId);
1731
1759
  const [treasuryStateAddress] = solana.PublicKey.findProgramAddressSync([Buffer.from("sat_treasury_state")], programId);
1732
1760
  const [treasury] = solana.PublicKey.findProgramAddressSync([Buffer.from("treasury")], programId);
1733
1761
  const currentMinerCycleAddress = owner ? solana.PublicKey.findProgramAddressSync([
@@ -1745,6 +1773,7 @@ async function inspectSatMiningStatusAccounts(_config, params) {
1745
1773
  const treasuryAta = deriveAssociatedTokenAddress(solana, treasury, mint);
1746
1774
  const coreEntries = [
1747
1775
  ["currentCycle", currentCycleAddress],
1776
+ ["currentSettlementProgress", currentSettlementProgressAddress],
1748
1777
  ["currentMinerCycle", currentMinerCycleAddress],
1749
1778
  ["claimMinerCycle", claimMinerCycleAddress],
1750
1779
  ["minerCapital", minerCapitalAddress],
@@ -1768,6 +1797,7 @@ async function inspectSatMiningStatusAccounts(_config, params) {
1768
1797
  const recordFor = (address) => address ? byAddress.get(address.toBase58()) ?? null : null;
1769
1798
  const globalRecord = recordFor(globalAddress);
1770
1799
  const currentCycleRecord = recordFor(currentCycleAddress);
1800
+ const currentSettlementProgressRecord = recordFor(currentSettlementProgressAddress);
1771
1801
  const currentMinerCycleRecord = recordFor(currentMinerCycleAddress);
1772
1802
  const claimMinerCycleRecord = recordFor(claimMinerCycleAddress);
1773
1803
  const minerCapitalRecord = recordFor(minerCapitalAddress);
@@ -1776,6 +1806,7 @@ async function inspectSatMiningStatusAccounts(_config, params) {
1776
1806
  const treasuryAtaRecord = recordFor(treasuryAta);
1777
1807
  const globalState = globalRecord?.data ? decodeSatGlobalState(globalRecord.data, globalAddress.toBase58()) : null;
1778
1808
  const currentCycle = currentCycleRecord?.data ? decodeSatCycle(currentCycleRecord.data, currentCycleAddress.toBase58()) : null;
1809
+ const currentSettlementProgress = currentSettlementProgressRecord?.data ? decodeSatCycleSettlementProgressV2(currentSettlementProgressRecord.data, currentSettlementProgressAddress.toBase58()) : null;
1779
1810
  const currentMinerCycle = currentMinerCycleRecord?.data ? decodeSatMinerCycle(currentMinerCycleRecord.data, currentMinerCycleAddress?.toBase58() ?? "") : null;
1780
1811
  const claimMinerCycle = claimMinerCycleRecord?.data ? decodeSatMinerCycle(claimMinerCycleRecord.data, claimMinerCycleAddress?.toBase58() ?? "") : null;
1781
1812
  const minerCapital = minerCapitalRecord?.data ? decodeSatMinerCapital(minerCapitalRecord.data, minerCapitalAddress?.toBase58() ?? "") : null;
@@ -1791,6 +1822,7 @@ async function inspectSatMiningStatusAccounts(_config, params) {
1791
1822
  } : null;
1792
1823
  writeRpcCacheValue(`view:global-state:${rpcCacheScope(rpc)}:${globalAddress.toBase58()}`, SAT_RPC_STABLE_VIEW_CACHE_TTL_MS, globalState);
1793
1824
  writeRpcCacheValue(`view:cycle:${rpcCacheScope(rpc)}:${currentCycleId}`, SAT_RPC_LIVE_VIEW_CACHE_TTL_MS, currentCycle);
1825
+ writeRpcCacheValue(`view:settlement-progress:${rpcCacheScope(rpc)}:${currentCycleId}`, SAT_RPC_LIVE_VIEW_CACHE_TTL_MS, currentSettlementProgress);
1794
1826
  if (owner && currentMinerCycleAddress) {
1795
1827
  writeRpcCacheValue(`view:miner-cycle:${rpcCacheScope(rpc)}:${authority}:${currentCycleId}`, SAT_RPC_LIVE_VIEW_CACHE_TTL_MS, currentMinerCycle);
1796
1828
  }
@@ -1807,6 +1839,7 @@ async function inspectSatMiningStatusAccounts(_config, params) {
1807
1839
  return {
1808
1840
  globalState,
1809
1841
  currentCycle,
1842
+ currentSettlementProgress,
1810
1843
  currentMinerCycle,
1811
1844
  claimMinerCycle,
1812
1845
  minerCapital,
@@ -2172,16 +2205,21 @@ async function inspectSatRentExemptionLamports(config) {
2172
2205
  const rpc = resolveEffectiveReadRpcConfig();
2173
2206
  const registryReserveTargetLamports = resolveSatGenesisProfileContract(config.network).registryReserveTargetLamports;
2174
2207
  return await getOrLoadRpcCacheValue(`view:rent-exemption:${rpcCacheScope(rpc)}:${registryReserveTargetLamports}`, SAT_RPC_RENT_EXEMPTION_CACHE_TTL_MS, async () => {
2175
- const [protocolVaultLamports, cycleStateLamports, cycleRegistryMetaLamports, cycleRegistryPageLamports, cycleSettlementProgressLamports, minerCycleLamports] = await Promise.all([
2176
- connection.getMinimumBalanceForRentExemption(SAT_PROTOCOL_VAULT_ACCOUNT_SPACE),
2177
- connection.getMinimumBalanceForRentExemption(SAT_CYCLE_STATE_ACCOUNT_SPACE),
2178
- connection.getMinimumBalanceForRentExemption(SAT_CYCLE_REGISTRY_META_ACCOUNT_SPACE),
2179
- connection.getMinimumBalanceForRentExemption(SAT_CYCLE_REGISTRY_PAGE_ACCOUNT_SPACE),
2180
- connection.getMinimumBalanceForRentExemption(SAT_CYCLE_SETTLEMENT_PROGRESS_V2_ACCOUNT_SPACE),
2181
- connection.getMinimumBalanceForRentExemption(SAT_MINER_CYCLE_ACCOUNT_SPACE)
2208
+ const [protocolVaultLamports, cycleStateLamports, cycleRegistryMetaLamports, cycleRegistryPageLamports, cycleSettlementProgressLamports, minerCycleLamports, unlockIntervalLamports] = await Promise.all([
2209
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.protocolVault),
2210
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.cycleState),
2211
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.cycleRegistryMeta),
2212
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.cycleRegistryPage),
2213
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.cycleSettlementProgressV2),
2214
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.minerCycle),
2215
+ connection.getMinimumBalanceForRentExemption(SAT_RENT_ACCOUNT_SPACES.unlockInterval)
2182
2216
  ]);
2183
2217
  const openCycleLamports = cycleStateLamports + cycleRegistryMetaLamports;
2184
- const submitCycleSharedLamports = cycleSettlementProgressLamports + cycleRegistryPageLamports;
2218
+ const submitCycleSharedLamports = calculateSatRevealSharedRentLamports({
2219
+ cycleSettlementProgressLamports,
2220
+ cycleRegistryPageLamports,
2221
+ unlockIntervalLamports
2222
+ });
2185
2223
  return {
2186
2224
  registryReserveTargetLamports: String(registryReserveTargetLamports),
2187
2225
  protocolVaultLamports: String(protocolVaultLamports),
@@ -2190,6 +2228,7 @@ async function inspectSatRentExemptionLamports(config) {
2190
2228
  cycleRegistryPageLamports: String(cycleRegistryPageLamports),
2191
2229
  cycleSettlementProgressLamports: String(cycleSettlementProgressLamports),
2192
2230
  minerCycleLamports: String(minerCycleLamports),
2231
+ unlockIntervalLamports: String(unlockIntervalLamports),
2193
2232
  openCycleLamports: String(openCycleLamports),
2194
2233
  submitCycleSharedLamports: String(submitCycleSharedLamports),
2195
2234
  submitCycleSignerLamports: String(minerCycleLamports)
@@ -2454,4 +2493,4 @@ function sortableValue(row, sortBy) {
2454
2493
  }
2455
2494
 
2456
2495
  //#endregion
2457
- export { inspectSatBondPosition, inspectSatBondStakingDistributor, inspectSatBondStakingPosition, inspectSatChainSlot, inspectSatCycle, inspectSatCycleRegistryMeta, inspectSatMinerCyclesByAddress, invalidateSatReadCaches };
2496
+ export { inspectSatAddressLookupTable, inspectSatBondPosition, inspectSatBondStakingDistributor, inspectSatBondStakingPosition, inspectSatChainSlot, inspectSatCycle, inspectSatCycleRegistryMeta, inspectSatMinerCyclesByAddress, invalidateSatReadCaches };
@@ -7,7 +7,7 @@ import { resolveWalletProviderId } from "../../../wallet/wallet-provider-resolve
7
7
  import { createSignerReviewApprovalRequest } from "../../../wallet/wallet-send-approvals.js";
8
8
  import "../../../plugin-sdk/sat-runtime.js";
9
9
  import { SAT_BOND_INSTRUCTION_DISCRIMINATORS, SAT_INSTRUCTION_DISCRIMINATORS, SAT_PROTOCOL_CONSTANTS, resolveSatGenesisProfileContract } from "./protocol-contract.js";
10
- import { inspectSatCycle, inspectSatCycleRegistryMeta, inspectSatMinerCyclesByAddress } from "./rpc-read.js";
10
+ import { inspectSatAddressLookupTable, inspectSatChainSlot, inspectSatCycle, inspectSatCycleRegistryMeta, inspectSatMinerCyclesByAddress } from "./rpc-read.js";
11
11
  import { decodeHash32 } from "./hash-spec.js";
12
12
  import { resolveSatSignerCodec } from "./signer-codec-manifest.js";
13
13
  import { buildSatSubmissionOperationKey, claimSatSubmission, digestSatSubmissionIntent, updateSatSubmission, waitForSatSubmissionLease } from "./submission-ledger.js";
@@ -49,6 +49,8 @@ const MINING_STAKE_SEED = "mining_stake";
49
49
  const TOKEN_PROGRAM_ID = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
50
50
  const ASSOCIATED_TOKEN_PROGRAM_ID = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
51
51
  const SLOT_HASHES_SYSVAR_ID = "SysvarS1otHashes111111111111111111111111111";
52
+ const SAT_DISTRIBUTION_LOOKUP_MIN_MINERS = 16;
53
+ const SAT_LOOKUP_TABLE_EXTEND_CHUNK_SIZE = 20;
52
54
  const IX = SAT_INSTRUCTION_DISCRIMINATORS;
53
55
  const BOND_IX = SAT_BOND_INSTRUCTION_DISCRIMINATORS;
54
56
  const VAULT_BOND_ACTIONS = new Set([
@@ -256,6 +258,7 @@ async function buildLocalSignerInstructionRequest(params) {
256
258
  isSigner: key.isSigner,
257
259
  isWritable: key.isWritable
258
260
  })),
261
+ ...params.spec.addressLookupTables?.length ? { addressLookupTables: params.spec.addressLookupTables } : {},
259
262
  ...context ? { context } : {}
260
263
  };
261
264
  }
@@ -290,8 +293,9 @@ async function requireTypedSatSignerCapabilities(socketPath, intentType) {
290
293
  "signerOwnedStateRecheck",
291
294
  "durableReviewAuthorization"
292
295
  ].filter((feature) => !features.has(feature)) : [];
293
- if (result.ready !== true || protocol?.current !== 2 || typeof protocol.min !== "number" || protocol.min > 2 || typeof protocol.max !== "number" || protocol.max < 2 || !capabilities?.intentTypes?.includes(intentType) || missingFeatures.length > 0 || intentType === "solana.vaultBondAction" && !features.has("typedVaultBondActions") || missingVaultReviewFeatures.length > 0 || missingStates.length > 0) {
294
- throw new Error(`local-socket-signer does not support the required typed SAT protocol-v2 contract${missingFeatures.length > 0 ? `; missing features: ${missingFeatures.join(", ")}` : ""}${missingVaultReviewFeatures.length > 0 ? `; missing reviewed Vault features: ${missingVaultReviewFeatures.join(", ")}` : ""}${missingStates.length > 0 ? `; missing states: ${missingStates.join(", ")}` : ""}`);
296
+ const missingLookupFeatures = intentType === "solana.satLookupTable" && !features.has("typedSATAddressLookupTables") ? ["typedSATAddressLookupTables"] : [];
297
+ if (result.ready !== true || protocol?.current !== 2 || typeof protocol.min !== "number" || protocol.min > 2 || typeof protocol.max !== "number" || protocol.max < 2 || !capabilities?.intentTypes?.includes(intentType) || missingFeatures.length > 0 || missingLookupFeatures.length > 0 || intentType === "solana.vaultBondAction" && !features.has("typedVaultBondActions") || missingVaultReviewFeatures.length > 0 || missingStates.length > 0) {
298
+ throw new Error(`local-socket-signer does not support the required typed SAT protocol-v2 contract${missingFeatures.length > 0 ? `; missing features: ${missingFeatures.join(", ")}` : ""}${missingVaultReviewFeatures.length > 0 ? `; missing reviewed Vault features: ${missingVaultReviewFeatures.join(", ")}` : ""}${missingLookupFeatures.length > 0 ? `; missing SAT lookup features: ${missingLookupFeatures.join(", ")}` : ""}${missingStates.length > 0 ? `; missing states: ${missingStates.join(", ")}` : ""}`);
295
299
  }
296
300
  }
297
301
  async function reconcileTypedSatOperation(params) {
@@ -320,6 +324,11 @@ function assertSatSignerOperationIdentity(operation, requestId) {
320
324
  function signerStateForLedger(state) {
321
325
  return state;
322
326
  }
327
+ function assertSatLookupTableAction(value) {
328
+ if (value !== "create" && value !== "extend" && value !== "deactivate" && value !== "close") {
329
+ throw new Error(`unsupported SAT lookup-table action ${value}`);
330
+ }
331
+ }
323
332
  var SatSubmissionUnresolvedError = class extends Error {
324
333
  constructor(params) {
325
334
  super(`SAT signer operation ${params.requestId} remains ${params.state}${params.signature ? ` with signature ${params.signature}` : ""}; it is unresolved and must be reconciled with the same idempotency key before any new submission${params.detail ? ` (${params.detail})` : ""}`);
@@ -329,10 +338,22 @@ var SatSubmissionUnresolvedError = class extends Error {
329
338
  }
330
339
  };
331
340
  async function executeTypedSatIntent(params) {
332
- const isVaultBond = params.action !== "cleanupBatch" && VAULT_BOND_ACTIONS.has(params.action);
333
- const intentType = isVaultBond ? "solana.vaultBondAction" : "solana.satAction";
341
+ const isLookupTable = params.lookupTable != null;
342
+ const isVaultBond = !isLookupTable && params.action !== "cleanupBatch" && VAULT_BOND_ACTIONS.has(params.action);
343
+ const intentType = isLookupTable ? "solana.satLookupTable" : isVaultBond ? "solana.vaultBondAction" : "solana.satAction";
334
344
  await requireTypedSatSignerCapabilities(params.socketPath, intentType);
335
- const intent = isVaultBond ? (() => {
345
+ const intent = isLookupTable ? (() => {
346
+ if (params.instruction || params.instructions || !params.lookupTable) {
347
+ throw new Error("typed SAT lookup-table execution accepts only semantic lookup details");
348
+ }
349
+ const action = params.action;
350
+ assertSatLookupTableAction(action);
351
+ return {
352
+ type: "solana.satLookupTable",
353
+ action,
354
+ lookupTable: params.lookupTable
355
+ };
356
+ })() : isVaultBond ? (() => {
336
357
  if (!params.instruction || params.instructions) {
337
358
  throw new Error("typed Vault bond execution requires exactly one semantic instruction");
338
359
  }
@@ -637,9 +658,171 @@ async function executeTypedSatIntent(params) {
637
658
  signature: operation.signature
638
659
  };
639
660
  }
661
+ function assertSatLookupTableEnabled(env) {
662
+ if (String(env.FASED_SAT_ENABLE_ALT_V0 ?? "").trim() !== "1") {
663
+ throw new Error("SAT ALT/v0 support is disabled; set FASED_SAT_ENABLE_ALT_V0=1");
664
+ }
665
+ }
666
+ async function executeTypedSatLookupOperation(params) {
667
+ return await executeTypedSatIntent({
668
+ socketPath: params.context.socketPath,
669
+ walletId: params.context.walletId,
670
+ action: params.action,
671
+ lookupTable: {
672
+ address: params.address,
673
+ ...params.recentSlot == null ? {} : { recentSlot: String(params.recentSlot) },
674
+ ...params.addresses?.length ? { addresses: params.addresses } : {}
675
+ },
676
+ cluster: resolveSatCluster(params.cfg),
677
+ env: params.context.effectiveEnv
678
+ });
679
+ }
680
+ async function readValidatedSatLookupTable(params) {
681
+ const state = await inspectSatAddressLookupTable(params.config, { address: params.address });
682
+ if (!state) {
683
+ return null;
684
+ }
685
+ if (state.authority !== params.authority) {
686
+ throw new Error("SAT distribution lookup table is not controlled by the Mining signer");
687
+ }
688
+ if (!state.active) {
689
+ throw new Error("SAT distribution lookup table is not active");
690
+ }
691
+ return state;
692
+ }
693
+ async function waitForSatLookupTable(params) {
694
+ let lastError;
695
+ for (let attempt = 0; attempt < 24; attempt += 1) {
696
+ try {
697
+ const state = await readValidatedSatLookupTable(params);
698
+ if (state) {
699
+ const currentSlot = await inspectSatChainSlot(params.config);
700
+ if (!params.requireNextSlot || currentSlot > state.lastExtendedSlot) {
701
+ return state;
702
+ }
703
+ }
704
+ } catch (error) {
705
+ lastError = error;
706
+ }
707
+ await new Promise((resolve) => setTimeout(resolve, 250));
708
+ }
709
+ throw new Error(`SAT distribution lookup table did not become active for use within 6s${lastError instanceof Error ? `: ${lastError.message}` : ""}`);
710
+ }
711
+ async function ensureSatDistributionLookupTable(params) {
712
+ assertSatLookupTableEnabled(params.context.effectiveEnv);
713
+ const desiredAddresses = [...new Set(params.addresses.map((entry) => entry.trim()))].filter(Boolean);
714
+ if (desiredAddresses.length === 0 || desiredAddresses.length > 256) {
715
+ throw new Error("SAT distribution lookup table requires 1-256 exact account addresses");
716
+ }
717
+ let lookupTable = params.lookupTableAddress?.trim() ?? "";
718
+ let state = lookupTable ? await readValidatedSatLookupTable({
719
+ config: params.config,
720
+ address: lookupTable,
721
+ authority: params.context.signerAddress
722
+ }) : null;
723
+ let created = false;
724
+ const transactionHashes = [];
725
+ if (!lookupTable) {
726
+ const currentSlot = await inspectSatChainSlot(params.config);
727
+ const recentSlot = Math.max(0, currentSlot - 1);
728
+ const [, derivedAddress] = params.context.solana.AddressLookupTableProgram.createLookupTable({
729
+ authority: params.context.signer,
730
+ payer: params.context.signer,
731
+ recentSlot
732
+ });
733
+ lookupTable = derivedAddress.toBase58();
734
+ state = await readValidatedSatLookupTable({
735
+ config: params.config,
736
+ address: lookupTable,
737
+ authority: params.context.signerAddress
738
+ });
739
+ if (!state) {
740
+ try {
741
+ const submitted = await executeTypedSatLookupOperation({
742
+ context: params.context,
743
+ cfg: params.cfg,
744
+ action: "create",
745
+ address: lookupTable,
746
+ recentSlot
747
+ });
748
+ transactionHashes.push(submitted.signature);
749
+ created = true;
750
+ } catch (error) {
751
+ if (error instanceof SatSubmissionUnresolvedError) {
752
+ throw error;
753
+ }
754
+ try {
755
+ state = await waitForSatLookupTable({
756
+ config: params.config,
757
+ address: lookupTable,
758
+ authority: params.context.signerAddress,
759
+ requireNextSlot: false
760
+ });
761
+ } catch {
762
+ throw error;
763
+ }
764
+ }
765
+ state ??= await waitForSatLookupTable({
766
+ config: params.config,
767
+ address: lookupTable,
768
+ authority: params.context.signerAddress,
769
+ requireNextSlot: false
770
+ });
771
+ }
772
+ }
773
+ if (!state) {
774
+ throw new Error("SAT distribution lookup table was not found at the confirmed commitment");
775
+ }
776
+ const existing = new Set(state.addresses);
777
+ const missing = desiredAddresses.filter((entry) => !existing.has(entry));
778
+ for (let offset = 0; offset < missing.length; offset += SAT_LOOKUP_TABLE_EXTEND_CHUNK_SIZE) {
779
+ const addresses = missing.slice(offset, offset + SAT_LOOKUP_TABLE_EXTEND_CHUNK_SIZE);
780
+ try {
781
+ const submitted = await executeTypedSatLookupOperation({
782
+ context: params.context,
783
+ cfg: params.cfg,
784
+ action: "extend",
785
+ address: lookupTable,
786
+ addresses
787
+ });
788
+ transactionHashes.push(submitted.signature);
789
+ } catch (error) {
790
+ if (error instanceof SatSubmissionUnresolvedError) {
791
+ throw error;
792
+ }
793
+ const concurrentState = await waitForSatLookupTable({
794
+ config: params.config,
795
+ address: lookupTable,
796
+ authority: params.context.signerAddress,
797
+ requireNextSlot: false
798
+ }).catch(() => null);
799
+ if (!concurrentState || addresses.some((address) => !concurrentState.addresses.includes(address))) {
800
+ throw error;
801
+ }
802
+ }
803
+ }
804
+ const ready = await waitForSatLookupTable({
805
+ config: params.config,
806
+ address: lookupTable,
807
+ authority: params.context.signerAddress,
808
+ requireNextSlot: true
809
+ });
810
+ for (const address of desiredAddresses) {
811
+ if (!ready.addresses.includes(address)) {
812
+ throw new Error(`SAT distribution lookup table did not persist required account ${address}`);
813
+ }
814
+ }
815
+ return {
816
+ lookupTable,
817
+ created,
818
+ extended: missing.length > 0,
819
+ addressCount: ready.addresses.length,
820
+ transactionHashes
821
+ };
822
+ }
640
823
  async function submitInstructionViaLocalSigner(params) {
641
824
  const context = await prepareLocalSignerSubmitContext(params.cfg, params.env);
642
- const request = await buildLocalSignerInstructionRequest({
825
+ const baseRequest = await buildLocalSignerInstructionRequest({
643
826
  solana: context.solana,
644
827
  signer: context.signer,
645
828
  env: context.effectiveEnv,
@@ -648,6 +831,23 @@ async function submitInstructionViaLocalSigner(params) {
648
831
  if (!context.walletId) {
649
832
  throw new Error("typed SAT signing requires an explicit mining walletId");
650
833
  }
834
+ let managedLookupTable;
835
+ if (params.manageAddressLookupTable) {
836
+ managedLookupTable = await ensureSatDistributionLookupTable({
837
+ context: {
838
+ ...context,
839
+ walletId: context.walletId
840
+ },
841
+ cfg: params.cfg,
842
+ config: params.cfg,
843
+ lookupTableAddress: params.manageAddressLookupTable.lookupTableAddress,
844
+ addresses: baseRequest.keys.filter((key) => !key.isSigner).map((key) => key.pubkey)
845
+ });
846
+ }
847
+ const request = managedLookupTable ? {
848
+ ...baseRequest,
849
+ addressLookupTables: [managedLookupTable.lookupTable]
850
+ } : baseRequest;
651
851
  const submitted = await executeTypedSatIntent({
652
852
  socketPath: context.socketPath,
653
853
  walletId: context.walletId,
@@ -660,7 +860,17 @@ async function submitInstructionViaLocalSigner(params) {
660
860
  txHash: submitted.signature,
661
861
  signer: context.signerAddress,
662
862
  signerState: submitted.state,
663
- requestId: submitted.requestId
863
+ requestId: submitted.requestId,
864
+ ...request.addressLookupTables?.length ? {
865
+ transactionVersion: "v0",
866
+ lookupTableAddress: request.addressLookupTables[0]
867
+ } : { transactionVersion: "legacy" },
868
+ ...managedLookupTable ? {
869
+ lookupTableCreated: managedLookupTable.created,
870
+ lookupTableExtended: managedLookupTable.extended,
871
+ lookupTableAddressCount: managedLookupTable.addressCount,
872
+ lookupTableTransactionHashes: managedLookupTable.transactionHashes
873
+ } : {}
664
874
  };
665
875
  }
666
876
  async function submitInstruction(params) {
@@ -673,6 +883,8 @@ async function submitInstruction(params) {
673
883
  env: effectiveEnv,
674
884
  data: params.data,
675
885
  programId: params.programId,
886
+ addressLookupTables: params.addressLookupTables,
887
+ manageAddressLookupTable: params.manageAddressLookupTable,
676
888
  accountResolver: params.accountResolver
677
889
  });
678
890
  }
@@ -2530,10 +2742,13 @@ async function submitSatScoreCyclePage(_config, params) {
2530
2742
  }
2531
2743
  async function submitSatDistributeCyclePage(_config, params) {
2532
2744
  const cfg = loadConfigForSatRuntime(_config);
2745
+ const lookupTableAddress = params.lookupTableAddress?.trim() ?? "";
2746
+ const requiresLookupTable = (params.minerCycleAccounts?.length ?? 0) >= SAT_DISTRIBUTION_LOOKUP_MIN_MINERS;
2533
2747
  return submitInstruction({
2534
2748
  cfg,
2535
2749
  env: process.env,
2536
2750
  data: buildDistributeCyclePageData(params),
2751
+ ...lookupTableAddress || requiresLookupTable ? { manageAddressLookupTable: { ...lookupTableAddress ? { lookupTableAddress } : {} } } : {},
2537
2752
  accountResolver: async (solana, signer) => {
2538
2753
  const programId = new solana.PublicKey(SAT_PROGRAM_ID());
2539
2754
  const [satCycleState] = solana.PublicKey.findProgramAddressSync([Buffer.from(SAT_CYCLE_STATE_SEED), encodeU64(params.cycleId)], programId);
@@ -2635,6 +2850,34 @@ async function submitSatDistributeCyclePage(_config, params) {
2635
2850
  }
2636
2851
  });
2637
2852
  }
2853
+ async function submitSatCleanupDistributionLookupTable(_config, params) {
2854
+ const cfg = loadConfigForSatRuntime(_config);
2855
+ const context = await prepareLocalSignerSubmitContext(cfg, process.env);
2856
+ assertSatLookupTableEnabled(context.effectiveEnv);
2857
+ if (!context.walletId) {
2858
+ throw new Error("typed SAT lookup-table cleanup requires an explicit mining walletId");
2859
+ }
2860
+ const lookupTable = params.lookupTableAddress.trim();
2861
+ if (!lookupTable) {
2862
+ throw new Error("SAT distribution lookup table address is required");
2863
+ }
2864
+ const submitted = await executeTypedSatLookupOperation({
2865
+ context: {
2866
+ ...context,
2867
+ walletId: context.walletId
2868
+ },
2869
+ cfg,
2870
+ action: params.action,
2871
+ address: lookupTable
2872
+ });
2873
+ return {
2874
+ lookupTable,
2875
+ action: params.action,
2876
+ transactionHashes: [submitted.signature],
2877
+ signerState: submitted.state,
2878
+ requestId: submitted.requestId
2879
+ };
2880
+ }
2638
2881
  async function submitSatClaimCycleRewards(_config, params) {
2639
2882
  const cfg = loadConfigForSatRuntime(_config);
2640
2883
  return submitInstruction({
@@ -63,7 +63,7 @@ function buildSatSubmissionOperationKey(intent) {
63
63
  action: candidate.action,
64
64
  keys: candidate.keys
65
65
  };
66
- }) : intent.keys;
66
+ }) : intent.keys ?? intent.lookupTable;
67
67
  return `${action}:${sha256(JSON.stringify(canonicalize(accountShape))).slice(0, 24)}`;
68
68
  }
69
69
  function normalizeStateKey(value) {
@@ -1,4 +1,4 @@
1
- import { Et as isAudioAttachment, St as normalizeMediaAttachments, Tt as runCapability, bt as buildProviderRegistry, wt as resolveMediaAttachmentLocalRoots, xt as createMediaAttachmentCache } from "./config-schema-BOT7kHb6.js";
1
+ import { Et as isAudioAttachment, St as normalizeMediaAttachments, Tt as runCapability, bt as buildProviderRegistry, wt as resolveMediaAttachmentLocalRoots, xt as createMediaAttachmentCache } from "./config-schema-D_8FVI1C.js";
2
2
  import "./runtime-2B9_WKoI.js";
3
3
  import "./subsystem-DBPNbQDQ.js";
4
4
  import { i as logVerbose, s as shouldLogVerbose } from "./globals-B_jjtAje.js";
@@ -1,5 +1,5 @@
1
1
  import { n as DEFAULT_ACCOUNT_ID, r as normalizeAccountId } from "./session-key--_1zVBRB.js";
2
2
  import { Y as ChannelMessageActionContext, n as ChannelPlugin, ut as getChatChannelMeta } from "./types.plugin-BcSBq42x.js";
3
- import { _ as FasedAgentPluginApi, t as PluginRuntime } from "./types-DWfbSAaM.js";
4
- import { a as buildChannelConfigSchema, c as emptyPluginConfigSchema, i as setAccountEnabledInConfigSection, n as formatPairingApproveHint, o as applyAccountNameToChannelSection, r as deleteAccountFromConfigSection, s as migrateBaseNameToDefaultAccount, t as PAIRING_APPROVED_MESSAGE } from "./pairing-message-CS-9BHug.js";
3
+ import { _ as FasedAgentPluginApi, t as PluginRuntime } from "./types-BrCpYMxn.js";
4
+ import { a as buildChannelConfigSchema, c as emptyPluginConfigSchema, i as setAccountEnabledInConfigSection, n as formatPairingApproveHint, o as applyAccountNameToChannelSection, r as deleteAccountFromConfigSection, s as migrateBaseNameToDefaultAccount, t as PAIRING_APPROVED_MESSAGE } from "./pairing-message-DHPDFZbC.js";
5
5
  export { type ChannelMessageActionContext, type ChannelPlugin, DEFAULT_ACCOUNT_ID, type FasedAgentPluginApi, PAIRING_APPROVED_MESSAGE, type PluginRuntime, applyAccountNameToChannelSection, buildChannelConfigSchema, deleteAccountFromConfigSection, emptyPluginConfigSchema, formatPairingApproveHint, getChatChannelMeta, migrateBaseNameToDefaultAccount, normalizeAccountId, setAccountEnabledInConfigSection };
@@ -1,4 +1,4 @@
1
- import { an as wrapExternalContent } from "./config-schema-BOT7kHb6.js";
1
+ import { an as wrapExternalContent } from "./config-schema-D_8FVI1C.js";
2
2
 
3
3
  //#region src/security/channel-metadata.ts
4
4
  const DEFAULT_MAX_CHARS = 800;
@@ -1,4 +1,4 @@
1
- import { Ht as buildCommandsMessage, Ut as buildCommandsMessagePaginated, Wt as buildHelpMessage } from "./config-schema-BOT7kHb6.js";
1
+ import { Ht as buildCommandsMessage, Ut as buildCommandsMessagePaginated, Wt as buildHelpMessage } from "./config-schema-D_8FVI1C.js";
2
2
  import "./runtime-2B9_WKoI.js";
3
3
  import "./subsystem-DBPNbQDQ.js";
4
4
  import "./globals-B_jjtAje.js";