@ostraagent/mcp 0.1.3 → 0.1.4

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/ostra-mcp.js CHANGED
@@ -18,7 +18,7 @@ var __export = (target, all) => {
18
18
  var define_OSTRA_PACKAGED_default;
19
19
  var init_define_OSTRA_PACKAGED = __esm({
20
20
  "<define:OSTRA_PACKAGED>"() {
21
- define_OSTRA_PACKAGED_default = { version: "0.1.3", deployment: { version: 1, chainId: 4663, fromBlock: "91991509", token: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", batchSettlement: "0x4020074e9dF2ce1deE5A9C1b5c3f541D02a10003", vaultImplementation: "0xD20c6744Cfa46d9ec564b119cC923bAb2f9f9331", vaultBeacon: "0xE9F525B9EaeE48d13AEd28fE146F48f2832a18a0", vaultFactory: "0x043a15c514CFE2c797d33520bFF91a5DCdbf2979", poolImplementation: "0xC04d4a222dC1C966640B977608bE29949b0648ec", poolBeacon: "0x30669Ca534921038a531BBE27116d85bB7406fFF", pool: "0x6ea80F2462e5Fd783B0Ec3B2c7BaC96795980CD6", splitFactory: "0xAAf54A483B2c7c2c5ecFc1eDED5ed1619C1bA882", beaconOwner: "0x55533a51d9bd9b06F2D179d919BB31995EF96E5e", launchpad: { hook: "0x63A784afb8905452aDceC471a45E555F5caE68cC", fees: "0x8e79671DC9729476614C78aFcf2345D4c1963801", launchpad: "0xfC57162C0e3f9773F97fEa8d276e957d7c43A6C5", creatorSplit: "0x987994dE6A1d5303B9e3F50977cB0321BA4D033B", dispatcher: "0x44Bb65164b2855f8E80B142d5Fb9bDb72E869986", locker: "0xb593812363bAd70Ee381c7B54c4FC82b0BA3A4A7", devBuy: "0x0e1Fd799E136dcfEcad5695B07Ac5DAc5B2fF4bc", vesting: "0xadD9C1995910457312c156E7D8120D1b447E179a", airdrop: "0xBC798D956aF4c2B104FFC6106d5322294Bc103bb", owner: "0x6569E27A95a6A3E92A311B4Cc6600fed56aA50A2" }, registry: "0xcE6Cc1f93744f4090DA1444Bb8590d9206157506" }, swapDeployment: { chainId: 4663, fromBlock: "94940585", router: "0x5b9686f384A5Fb768B2360cF0B893F0d1E960B01", stake: "0xaDA4FaB9c8aB9165bf4d6cD9d4Da6d6b32Bb4BC6", buyback: "0xd86083031b7Af66ecD5C9c5e90D4C6d8E661F3f5", spendVerifier: "0x0a0E28a81DE6289e5044950163FfE95b37180e3B", privatePool: "0xe4250895Da2499602Cee4e178Fb46A0cF39F5b76" }, prover: { wasm: "0xd5f3069334ab49a2f955e4b4be9493b80c3f7b2a85f4ff2073a327ef5fbc2747", glue: "0x4bc8bef7c755c83daaf833623f85473a20a7c40b390d8d639d9e4353618a0537" }, relayerUrl: "https://relayer.ostraagent.xyz", keeperUrl: "https://keeper.ostraagent.xyz", aggregatorUrl: "https://aggregator.ostraagent.xyz" };
21
+ define_OSTRA_PACKAGED_default = { version: "0.1.4", deployment: { version: 1, chainId: 4663, fromBlock: "91991509", token: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", batchSettlement: "0x4020074e9dF2ce1deE5A9C1b5c3f541D02a10003", vaultImplementation: "0xD20c6744Cfa46d9ec564b119cC923bAb2f9f9331", vaultBeacon: "0xE9F525B9EaeE48d13AEd28fE146F48f2832a18a0", vaultFactory: "0x043a15c514CFE2c797d33520bFF91a5DCdbf2979", poolImplementation: "0xC04d4a222dC1C966640B977608bE29949b0648ec", poolBeacon: "0x30669Ca534921038a531BBE27116d85bB7406fFF", pool: "0x6ea80F2462e5Fd783B0Ec3B2c7BaC96795980CD6", splitFactory: "0xAAf54A483B2c7c2c5ecFc1eDED5ed1619C1bA882", beaconOwner: "0x55533a51d9bd9b06F2D179d919BB31995EF96E5e", launchpad: { hook: "0x63A784afb8905452aDceC471a45E555F5caE68cC", fees: "0x8e79671DC9729476614C78aFcf2345D4c1963801", launchpad: "0xfC57162C0e3f9773F97fEa8d276e957d7c43A6C5", creatorSplit: "0x987994dE6A1d5303B9e3F50977cB0321BA4D033B", dispatcher: "0x44Bb65164b2855f8E80B142d5Fb9bDb72E869986", locker: "0xb593812363bAd70Ee381c7B54c4FC82b0BA3A4A7", devBuy: "0x0e1Fd799E136dcfEcad5695B07Ac5DAc5B2fF4bc", vesting: "0xadD9C1995910457312c156E7D8120D1b447E179a", airdrop: "0xBC798D956aF4c2B104FFC6106d5322294Bc103bb", owner: "0x6569E27A95a6A3E92A311B4Cc6600fed56aA50A2" }, registry: "0xcE6Cc1f93744f4090DA1444Bb8590d9206157506" }, swapDeployment: { chainId: 4663, fromBlock: "94940585", router: "0x5b9686f384A5Fb768B2360cF0B893F0d1E960B01", stake: "0xaDA4FaB9c8aB9165bf4d6cD9d4Da6d6b32Bb4BC6", buyback: "0xd86083031b7Af66ecD5C9c5e90D4C6d8E661F3f5", spendVerifier: "0x0a0E28a81DE6289e5044950163FfE95b37180e3B", privatePool: "0xe4250895Da2499602Cee4e178Fb46A0cF39F5b76" }, prover: { wasm: "0xd5f3069334ab49a2f955e4b4be9493b80c3f7b2a85f4ff2073a327ef5fbc2747", glue: "0x4bc8bef7c755c83daaf833623f85473a20a7c40b390d8d639d9e4353618a0537" }, relayerUrl: "https://relayer.ostraagent.xyz", keeperUrl: "https://keeper.ostraagent.xyz", aggregatorUrl: "https://aggregator.ostraagent.xyz", aiUrl: "https://ai.ostraagent.xyz" };
22
22
  }
23
23
  });
24
24
 
@@ -11721,7 +11721,7 @@ var init_hash = __esm({
11721
11721
  });
11722
11722
 
11723
11723
  // ../sdk/src/constants.ts
11724
- var ROBINHOOD_CHAIN_ID, ROBINHOOD_PUBLIC_RPC, USDG, USDG_EIP712_DOMAIN, X402_BATCH_SETTLEMENT, X402_BATCH_SETTLEMENT_DOMAIN, X402_MIN_WITHDRAW_DELAY, X402_MAX_WITHDRAW_DELAY, UNISWAP_V4_POOL_MANAGER, CHAINLINK_ETH_USD, CHAINLINK_ETH_USD_DECIMALS, ERC8004_IDENTITY_REGISTRY, WETH, OSTRA, OSTRA_DECIMALS, OSTRA_PONS_CURVE, MULTICALL3, ARBITRUM_NODE_INTERFACE, MAX_FEE_BPS, DEPOSIT_TIMEOUT_SECONDS, VAULT_SWAP_GAS_RESERVE, VAULT_VERSION, VAULT_MAX_URI_LENGTH, VAULT_ACTION, MIN_RECOVERY_DELAY, MAX_RECOVERY_DELAY, POOL_SETTING, CIRCUIT_BREAKER, VAULT_SWAP_GAS, LAUNCHPAD, DEV_BUY, AIRDROP, CREATOR_SPLIT, DEPOSIT_STATUS, BATCH_STATUS;
11724
+ var ROBINHOOD_CHAIN_ID, ROBINHOOD_PUBLIC_RPC, USDG, USDG_EIP712_DOMAIN, X402_BATCH_SETTLEMENT, X402_BATCH_SETTLEMENT_DOMAIN, X402_MIN_WITHDRAW_DELAY, X402_MAX_WITHDRAW_DELAY, UNISWAP_V4_POOL_MANAGER, CHAINLINK_ETH_USD, CHAINLINK_ETH_USD_DECIMALS, ERC8004_IDENTITY_REGISTRY, WETH, OSTRA, OSTRA_DECIMALS, OSTRA_PONS_CURVE, PONS_HOOK, OSTRA_POOL_FEE, OSTRA_POOL_TICK_SPACING, MULTICALL3, ARBITRUM_NODE_INTERFACE, MAX_FEE_BPS, DEPOSIT_TIMEOUT_SECONDS, VAULT_SWAP_GAS_RESERVE, VAULT_VERSION, VAULT_MAX_URI_LENGTH, VAULT_ACTION, MIN_RECOVERY_DELAY, MAX_RECOVERY_DELAY, POOL_SETTING, CIRCUIT_BREAKER, VAULT_SWAP_GAS, LAUNCHPAD, DEV_BUY, AIRDROP, CREATOR_SPLIT, DEPOSIT_STATUS, BATCH_STATUS;
11725
11725
  var init_constants = __esm({
11726
11726
  "../sdk/src/constants.ts"() {
11727
11727
  "use strict";
@@ -11747,6 +11747,9 @@ var init_constants = __esm({
11747
11747
  OSTRA = "0x68Ff81dFFF6eccefb74706fE1e0a86320CB2Eb96";
11748
11748
  OSTRA_DECIMALS = 18;
11749
11749
  OSTRA_PONS_CURVE = "0xef89C3a9832Ae6f8Dc5F785484b1B5cb1120F372";
11750
+ PONS_HOOK = "0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044";
11751
+ OSTRA_POOL_FEE = 0;
11752
+ OSTRA_POOL_TICK_SPACING = 200;
11750
11753
  MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11";
11751
11754
  ARBITRUM_NODE_INTERFACE = "0x00000000000000000000000000000000000000C8";
11752
11755
  MAX_FEE_BPS = 500;
@@ -12123,7 +12126,7 @@ var init_deployment = __esm({
12123
12126
 
12124
12127
  // ../sdk/src/external-abi.ts
12125
12128
  import { parseAbi } from "viem";
12126
- var usdgAbi, chainlinkAggregatorAbi, ponsCurveAbi, multicall3Abi, nodeInterfaceAbi;
12129
+ var usdgAbi, chainlinkAggregatorAbi, ponsCurveAbi, poolManagerExtsloadAbi, multicall3Abi, nodeInterfaceAbi;
12127
12130
  var init_external_abi = __esm({
12128
12131
  "../sdk/src/external-abi.ts"() {
12129
12132
  "use strict";
@@ -12157,6 +12160,7 @@ var init_external_abi = __esm({
12157
12160
  "function getReserves() view returns (uint256 ethReserve, uint256 tokenReserve)",
12158
12161
  "function buy(uint256 ethIn, uint256 minTokensOut, address recipient) payable returns (uint256 tokensOut)"
12159
12162
  ]);
12163
+ poolManagerExtsloadAbi = parseAbi(["function extsload(bytes32 slot) view returns (bytes32)"]);
12160
12164
  multicall3Abi = parseAbi([
12161
12165
  "struct Call3 { address target; bool allowFailure; bytes callData; }",
12162
12166
  "struct Result { bool success; bytes returnData; }",
@@ -13673,7 +13677,7 @@ var init_quote = __esm({
13673
13677
  });
13674
13678
 
13675
13679
  // ../sdk/src/pairs.ts
13676
- import { getAddress as getAddress9, parseAbi as parseAbi2, zeroAddress as zeroAddress6 } from "viem";
13680
+ import { encodeAbiParameters as encodeAbiParameters5, getAddress as getAddress9, hexToBigInt, keccak256 as keccak2569, parseAbi as parseAbi2, toHex as toHex2, zeroAddress as zeroAddress6 } from "viem";
13677
13681
  function findLaunchPair(symbolOrAddress) {
13678
13682
  const s = symbolOrAddress.trim();
13679
13683
  if (/^0x[0-9a-fA-F]{40}$/.test(s)) {
@@ -13688,6 +13692,14 @@ function launchPair(symbolOrAddress) {
13688
13692
  if (q === null) throw new RangeError(`${symbolOrAddress} is not a pair Ostra offers; the pairs are ${LAUNCH_PAIRS.map((x) => x.symbol).join(", ")}`);
13689
13693
  return q;
13690
13694
  }
13695
+ async function readOstraPool(client) {
13696
+ const slot0 = keccak2569(encodeAbiParameters5([{ type: "bytes32" }, { type: "uint256" }], [OSTRA_POOL_ID, POOLS_SLOT2]));
13697
+ const [word, liq] = await Promise.all([
13698
+ client.readContract({ address: UNISWAP_V4_POOL_MANAGER, abi: poolManagerExtsloadAbi, functionName: "extsload", args: [slot0] }),
13699
+ client.readContract({ address: UNISWAP_V4_POOL_MANAGER, abi: poolManagerExtsloadAbi, functionName: "extsload", args: [toHex2(hexToBigInt(slot0) + LIQUIDITY_OFFSET, { size: 32 })] })
13700
+ ]);
13701
+ return { sqrtPriceX96: hexToBigInt(word) & (1n << 160n) - 1n, liquidity: hexToBigInt(liq) & (1n << 128n) - 1n };
13702
+ }
13691
13703
  async function readPairUsdPrice(client, quote) {
13692
13704
  const block = await client.getBlock();
13693
13705
  const now3 = Number(block.timestamp);
@@ -13710,10 +13722,15 @@ async function readPairUsdPrice(client, quote) {
13710
13722
  client.readContract({ address: OSTRA_PONS_CURVE, abi: ponsCurveAbi, functionName: "graduated" }),
13711
13723
  client.readContract({ address: OSTRA_PONS_CURVE, abi: ponsCurveAbi, functionName: "getReserves" })
13712
13724
  ]);
13713
- if (graduated) throw new Error("OSTRA has graduated from its Pons curve and migrated; its price is not read from its new pool yet");
13714
- const [ethReserve, tokenReserve] = reserves;
13715
- if (ethReserve <= 0n || tokenReserve <= 0n) throw new Error(`the OSTRA Pons curve reports reserves of ${ethReserve} wei and ${tokenReserve} tokens`);
13716
- priceE8 = answer * ethReserve / tokenReserve;
13725
+ if (graduated) {
13726
+ const { sqrtPriceX96, liquidity } = await readOstraPool(client);
13727
+ if (sqrtPriceX96 === 0n || liquidity === 0n) throw new Error(`OSTRA's pool ${OSTRA_POOL_ID} has no price or no liquidity in range`);
13728
+ priceE8 = (answer << 192n) / (sqrtPriceX96 * sqrtPriceX96);
13729
+ } else {
13730
+ const [ethReserve, tokenReserve] = reserves;
13731
+ if (ethReserve <= 0n || tokenReserve <= 0n) throw new Error(`the OSTRA Pons curve reports reserves of ${ethReserve} wei and ${tokenReserve} tokens`);
13732
+ priceE8 = answer * ethReserve / tokenReserve;
13733
+ }
13717
13734
  if (priceE8 < 100n) throw new Error(`OSTRA's price (${priceE8} x 0.00000001 USD) is too small to set a market cap in within 1%`);
13718
13735
  }
13719
13736
  if (quote.kind === "stock") {
@@ -13728,7 +13745,7 @@ function usdToQuoteUnits(usdE6, priceE8, decimals) {
13728
13745
  if (priceE8 <= 0n) throw new RangeError("the price must be positive");
13729
13746
  return usdE6 * 10n ** BigInt(decimals) * 100n / priceE8;
13730
13747
  }
13731
- var STOCK_PRICE_MAX_AGE, ETH_PRICE_MAX_AGE, stock, LAUNCH_PAIRS, stockTokenAbi;
13748
+ var STOCK_PRICE_MAX_AGE, ETH_PRICE_MAX_AGE, stock, LAUNCH_PAIRS, stockTokenAbi, OSTRA_POOL_ID, POOLS_SLOT2, LIQUIDITY_OFFSET;
13732
13749
  var init_pairs = __esm({
13733
13750
  "../sdk/src/pairs.ts"() {
13734
13751
  "use strict";
@@ -13783,6 +13800,14 @@ var init_pairs = __esm({
13783
13800
  stock("USO", "United States Oil Fund ETF", "0xa30FA36Db767ad9eD3f7a60fC79526fB4d56D344", "0x75a9c76Ef439e2C7c2E5a34Ab105EcFe3766431c")
13784
13801
  ];
13785
13802
  stockTokenAbi = parseAbi2(["function uiMultiplier() view returns (uint256)"]);
13803
+ OSTRA_POOL_ID = keccak2569(
13804
+ encodeAbiParameters5(
13805
+ [{ type: "address" }, { type: "address" }, { type: "uint24" }, { type: "int24" }, { type: "address" }],
13806
+ [zeroAddress6, OSTRA, OSTRA_POOL_FEE, OSTRA_POOL_TICK_SPACING, PONS_HOOK]
13807
+ )
13808
+ );
13809
+ POOLS_SLOT2 = 6n;
13810
+ LIQUIDITY_OFFSET = 3n;
13786
13811
  }
13787
13812
  });
13788
13813
 
@@ -13813,7 +13838,7 @@ var init_browser = __esm({
13813
13838
  });
13814
13839
 
13815
13840
  // ../sdk/src/deploy.ts
13816
- import { concat as concat3, encodeDeployData, encodeFunctionData as encodeFunctionData5, getAddress as getAddress10, getContractAddress as getContractAddress2, keccak256 as keccak2569, numberToHex as numberToHex2 } from "viem";
13841
+ import { concat as concat3, encodeDeployData, encodeFunctionData as encodeFunctionData5, getAddress as getAddress10, getContractAddress as getContractAddress2, keccak256 as keccak25610, numberToHex as numberToHex2 } from "viem";
13817
13842
  var init_deploy = __esm({
13818
13843
  "../sdk/src/deploy.ts"() {
13819
13844
  "use strict";
@@ -13959,6 +13984,132 @@ var init_amount = __esm({
13959
13984
  }
13960
13985
  });
13961
13986
 
13987
+ // ../core/src/ai.ts
13988
+ import { getAddress as getAddress11 } from "viem";
13989
+ function textStreamAnswer(sse) {
13990
+ let content = "";
13991
+ let reasoning = "";
13992
+ const calls = [];
13993
+ let closing = null;
13994
+ let finish = null;
13995
+ for (const event of sse.split(/\r?\n\r?\n/)) {
13996
+ const lines = event.split(/\r?\n/).filter((l) => l !== "" && !l.startsWith(":"));
13997
+ if (lines.length === 0) continue;
13998
+ const named = lines[0]?.startsWith("event: ") ? lines[0].slice("event: ".length) : null;
13999
+ const data = lines.filter((l) => l.startsWith("data: ")).map((l) => l.slice("data: ".length)).join("\n");
14000
+ if (data === "" || data === "[DONE]") continue;
14001
+ let json;
14002
+ try {
14003
+ json = JSON.parse(data);
14004
+ } catch {
14005
+ continue;
14006
+ }
14007
+ if (named === "ostra" || json.object === "ostra.task") {
14008
+ closing = json;
14009
+ continue;
14010
+ }
14011
+ const choice = json.choices?.[0];
14012
+ if (choice === void 0) continue;
14013
+ if (choice.finish_reason !== null && choice.finish_reason !== void 0) finish = choice.finish_reason;
14014
+ const d = choice.delta ?? {};
14015
+ if (typeof d.content === "string") content += d.content;
14016
+ if (typeof d.reasoning === "string") reasoning += d.reasoning;
14017
+ for (const tc of d.tool_calls ?? []) {
14018
+ const i = typeof tc.index === "number" ? tc.index : 0;
14019
+ const cur = calls[i] ?? (calls[i] = { type: "function", function: { name: "", arguments: "" } });
14020
+ if (typeof tc.id === "string") cur.id = tc.id;
14021
+ if (typeof tc.type === "string") cur.type = tc.type;
14022
+ if (typeof tc.function?.name === "string") cur.function.name += tc.function.name;
14023
+ if (typeof tc.function?.arguments === "string") cur.function.arguments += tc.function.arguments;
14024
+ }
14025
+ }
14026
+ const message = { role: "assistant", content, reasoning: reasoning === "" ? null : reasoning, ...calls.length === 0 ? {} : { tool_calls: calls.filter((c) => c !== void 0) } };
14027
+ if (closing === null) return { error: "stream_incomplete", message: "the answer's stream ended before what it was charged was told", partial: message };
14028
+ const { object: _object, ...rest } = closing;
14029
+ if (typeof rest.error === "string") return { ...rest, partial: message };
14030
+ return { ...rest, message, finish_reason: rest.finish_reason ?? finish };
14031
+ }
14032
+ var AI_TASK_KINDS, AI_MAX_BODY_CHARS, SET_HERE, REQUEST_TIMEOUT_MS, TASK_TIMEOUT_MS, RAW_ANSWER_CHARS, AiService;
14033
+ var init_ai = __esm({
14034
+ "../core/src/ai.ts"() {
14035
+ "use strict";
14036
+ init_define_OSTRA_PACKAGED();
14037
+ init_amount();
14038
+ AI_TASK_KINDS = ["text", "image", "video"];
14039
+ AI_MAX_BODY_CHARS = 48 * 1024 * 1024;
14040
+ SET_HERE = ["task", "max_price", "payer", "stream"];
14041
+ REQUEST_TIMEOUT_MS = 6e4;
14042
+ TASK_TIMEOUT_MS = 66e4;
14043
+ RAW_ANSWER_CHARS = 4e3;
14044
+ AiService = class {
14045
+ #url;
14046
+ #payments;
14047
+ #vault;
14048
+ constructor(config, payments, vault) {
14049
+ if (config.aiUrl === null) throw new Error("Ostra AI is not configured here (OSTRA_AI_URL)");
14050
+ this.#url = config.aiUrl.replace(/\/+$/, "");
14051
+ this.#payments = payments;
14052
+ this.#vault = vault;
14053
+ }
14054
+ /** Runs a `kind` task with `request`'s parameters, paying at most `maxPrice` USDG from a channel of the vault. */
14055
+ async task(kind, request, maxPrice, deposit) {
14056
+ if (!AI_TASK_KINDS.includes(kind)) throw new RangeError(`the task is one of ${AI_TASK_KINDS.join(", ")}`);
14057
+ for (const key of SET_HERE) if (key in request) throw new RangeError(`${key} is set by ostra_ai: leave it out of request`);
14058
+ const units2 = parseTokenAmount(maxPrice);
14059
+ if (units2 <= 0n) throw new RangeError("maxPrice must be positive");
14060
+ const payer = getAddress11(await this.#vault.vaultAddress());
14061
+ const body = JSON.stringify({ ...request, task: kind, max_price: units2.toString(), payer, ...kind === "text" ? { stream: true } : {} });
14062
+ const r = await this.#payments.pay({
14063
+ url: `${this.#url}/v1/ai/${kind}`,
14064
+ method: "POST",
14065
+ headers: { "content-type": "application/json" },
14066
+ body,
14067
+ maxPrice,
14068
+ maxBodyChars: AI_MAX_BODY_CHARS,
14069
+ timeoutMs: TASK_TIMEOUT_MS,
14070
+ ...deposit === void 0 ? {} : { deposit }
14071
+ });
14072
+ let answer;
14073
+ const head = r.body.trimStart();
14074
+ if (r.status === 200 && kind === "text" && (head.startsWith("data:") || head.startsWith(":") || head.startsWith("event:"))) answer = textStreamAnswer(r.body);
14075
+ else {
14076
+ try {
14077
+ answer = JSON.parse(r.body);
14078
+ } catch {
14079
+ answer = r.body.slice(0, RAW_ANSWER_CHARS);
14080
+ }
14081
+ }
14082
+ const failed = answer !== null && typeof answer === "object" && typeof answer.error === "string";
14083
+ const notes = [r.note, r.truncated ? "the answer was longer than ostra_ai reads and was cut" : void 0, r.status === 200 && failed ? "the task failed after it began (answer.error): what it was charged is the vault's credit with Ostra AI" : void 0].filter((x) => x !== void 0);
14084
+ return { status: r.status, paid: r.paid, channel: r.channel, channelLeft: r.channelLeft, answer, ...notes.length === 0 ? {} : { note: notes.join("; ") } };
14085
+ }
14086
+ /** A video job's status; the first final one settles its cost and credits the rest. */
14087
+ async job(id) {
14088
+ if (!/^[0-9a-f]{32}$/.test(id)) throw new RangeError("job is the 32 hex characters ostra_ai gave");
14089
+ const res = await fetch(`${this.#url}/v1/ai/video/${id}`, { signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
14090
+ const text2 = await res.text();
14091
+ try {
14092
+ return { status: res.status, answer: JSON.parse(text2) };
14093
+ } catch {
14094
+ return { status: res.status, answer: text2.slice(0, 2e3) };
14095
+ }
14096
+ }
14097
+ /** Where a finished video job's content is read (no payment). */
14098
+ contentUrl(id) {
14099
+ if (!/^[0-9a-f]{32}$/.test(id)) throw new RangeError("job is the 32 hex characters ostra_ai gave");
14100
+ return `${this.#url}/v1/ai/video/${id}/content`;
14101
+ }
14102
+ /** The vault's credit with Ostra AI (USDG base units). */
14103
+ async credit() {
14104
+ const payer = getAddress11(await this.#vault.vaultAddress());
14105
+ const res = await fetch(`${this.#url}/v1/ai/credits/${payer}`, { signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
14106
+ if (!res.ok) throw new Error(`Ostra AI answered ${res.status} for the vault's credit`);
14107
+ return res.json();
14108
+ }
14109
+ };
14110
+ }
14111
+ });
14112
+
13962
14113
  // ../core/src/chain.ts
13963
14114
  import { createWalletClient } from "viem";
13964
14115
  function tokenBalance(client, token, owner) {
@@ -14053,13 +14204,13 @@ var init_config = __esm({
14053
14204
  });
14054
14205
 
14055
14206
  // ../core/src/relay.ts
14056
- import { decodeFunctionData as decodeFunctionData3, getAddress as getAddress11, isAddress as isAddress5 } from "viem";
14207
+ import { decodeFunctionData as decodeFunctionData3, getAddress as getAddress12, isAddress as isAddress5 } from "viem";
14057
14208
  import { x402Client, x402HTTPClient } from "@x402/core/client";
14058
14209
  import { toClientEvmSigner } from "@x402/evm";
14059
14210
  import { BatchSettlementEvmScheme } from "@x402/evm/batch-settlement/client";
14060
14211
  function address(value, what) {
14061
14212
  if (typeof value !== "string" || !isAddress5(value, { strict: false })) throw new Error(`${what} is not an address`);
14062
- return getAddress11(value);
14213
+ return getAddress12(value);
14063
14214
  }
14064
14215
  function checkSplits(raw, what) {
14065
14216
  if (!Array.isArray(raw)) throw new Error(`${what} are not a list`);
@@ -14080,7 +14231,7 @@ function checkRelayerFacts(raw, want) {
14080
14231
  const f = raw;
14081
14232
  if (f === null || typeof f !== "object") throw new Error("the relayer's terms are not an object");
14082
14233
  if (f.chainId !== want.chainId) throw new Error(`the relayer serves chain ${String(f.chainId)}, not ${want.chainId}`);
14083
- if (address(f.token, "the relayer's token") !== getAddress11(want.token)) throw new Error(`the relayer serves token ${String(f.token)}, not ${want.token}`);
14234
+ if (address(f.token, "the relayer's token") !== getAddress12(want.token)) throw new Error(`the relayer serves token ${String(f.token)}, not ${want.token}`);
14084
14235
  if (f.decimals !== TOKEN_DECIMALS) throw new Error(`the relayer's token has ${String(f.decimals)} decimals, not ${TOKEN_DECIMALS}`);
14085
14236
  if (address(f.priceFeed, "the relayer's price feed") !== CHAINLINK_ETH_USD) throw new Error(`the relayer prices from ${String(f.priceFeed)}, not the Chainlink ETH/USD feed ${CHAINLINK_ETH_USD}`);
14086
14237
  if (f.maxCalls !== MAX_RELAY_CALLS) throw new Error(`the relayer takes ${String(f.maxCalls)} calls per request, not ${MAX_RELAY_CALLS}`);
@@ -14108,10 +14259,10 @@ function relayerChannelDeposit(needed, vaultBalance, keep = 0n) {
14108
14259
  function relayerOfferProblem(r, want) {
14109
14260
  if (r.scheme !== "batch-settlement") return `the offer is ${r.scheme}, not batch-settlement`;
14110
14261
  if (r.network !== want.network) return `the offer is on ${r.network}, not ${want.network}`;
14111
- if (!isAddress5(r.asset, { strict: false }) || getAddress11(r.asset) !== getAddress11(want.config.token)) return `the offer is in ${r.asset}, not ${want.config.token}`;
14112
- if (!isAddress5(r.payTo, { strict: false }) || getAddress11(r.payTo) !== getAddress11(want.config.receiver)) return `the offer pays ${r.payTo}, not the relayer's split ${want.config.receiver}`;
14262
+ if (!isAddress5(r.asset, { strict: false }) || getAddress12(r.asset) !== getAddress12(want.config.token)) return `the offer is in ${r.asset}, not ${want.config.token}`;
14263
+ if (!isAddress5(r.payTo, { strict: false }) || getAddress12(r.payTo) !== getAddress12(want.config.receiver)) return `the offer pays ${r.payTo}, not the relayer's split ${want.config.receiver}`;
14113
14264
  const extra = r.extra ?? {};
14114
- if (typeof extra.receiverAuthorizer !== "string" || !isAddress5(extra.receiverAuthorizer, { strict: false }) || getAddress11(extra.receiverAuthorizer) !== getAddress11(want.config.receiverAuthorizer)) {
14265
+ if (typeof extra.receiverAuthorizer !== "string" || !isAddress5(extra.receiverAuthorizer, { strict: false }) || getAddress12(extra.receiverAuthorizer) !== getAddress12(want.config.receiverAuthorizer)) {
14115
14266
  return `the offer's receiverAuthorizer is ${String(extra.receiverAuthorizer)}, not the relayer's vault ${want.config.receiverAuthorizer}`;
14116
14267
  }
14117
14268
  if (extra.withdrawDelay !== want.config.withdrawDelay) return `the offer's withdrawDelay is ${String(extra.withdrawDelay)}, not the relayer's ${want.config.withdrawDelay} s`;
@@ -14124,7 +14275,7 @@ function relayerOfferProblem(r, want) {
14124
14275
  }
14125
14276
  function openChannelCall(calls, vault, token) {
14126
14277
  for (const c of calls) {
14127
- if (getAddress11(c.to) !== getAddress11(vault)) continue;
14278
+ if (getAddress12(c.to) !== getAddress12(vault)) continue;
14128
14279
  let decoded;
14129
14280
  try {
14130
14281
  decoded = decodeFunctionData3({ abi: ostraVaultAbi, data: c.data });
@@ -14139,7 +14290,7 @@ function openChannelCall(calls, vault, token) {
14139
14290
  }
14140
14291
  return null;
14141
14292
  }
14142
- var RELAYER_DIR, VAULT_SPEND_GAS, REQUEST_TIMEOUT_MS, MAX_STEPS, MAX_RESENDS, LANDED_TIMEOUT_MS, OPEN_READ_TRIES, OPEN_READ_INTERVAL_MS, BPS_DENOMINATOR, now, LocalSender, RelayerUnavailableError, PendingSpendUnpaidError, RelayerError, RelayerStore, RelayerClient;
14293
+ var RELAYER_DIR, VAULT_SPEND_GAS, REQUEST_TIMEOUT_MS2, MAX_STEPS, MAX_RESENDS, LANDED_TIMEOUT_MS, OPEN_READ_TRIES, OPEN_READ_INTERVAL_MS, BPS_DENOMINATOR, now, LocalSender, RelayerUnavailableError, PendingSpendUnpaidError, RelayerError, RelayerStore, RelayerClient;
14143
14294
  var init_relay = __esm({
14144
14295
  "../core/src/relay.ts"() {
14145
14296
  "use strict";
@@ -14150,7 +14301,7 @@ var init_relay = __esm({
14150
14301
  init_config();
14151
14302
  RELAYER_DIR = "relayer";
14152
14303
  VAULT_SPEND_GAS = 400000n;
14153
- REQUEST_TIMEOUT_MS = 24e4;
14304
+ REQUEST_TIMEOUT_MS2 = 24e4;
14154
14305
  MAX_STEPS = 8;
14155
14306
  MAX_RESENDS = 3;
14156
14307
  LANDED_TIMEOUT_MS = 6e4;
@@ -14210,7 +14361,7 @@ var init_relay = __esm({
14210
14361
  #name;
14211
14362
  constructor(agentFolder, chainId, token, relayerVault) {
14212
14363
  this.#folder = agentFolder.folder(RELAYER_DIR);
14213
- this.#name = `${chainId}-${getAddress11(token)}-${getAddress11(relayerVault)}.json`;
14364
+ this.#name = `${chainId}-${getAddress12(token)}-${getAddress12(relayerVault)}.json`;
14214
14365
  }
14215
14366
  async load() {
14216
14367
  const text2 = await this.#folder.read(this.#name);
@@ -14264,7 +14415,7 @@ var init_relay = __esm({
14264
14415
  method,
14265
14416
  headers: body === void 0 ? headers : { "content-type": "application/json", ...headers },
14266
14417
  ...body === void 0 ? {} : { body },
14267
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
14418
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
14268
14419
  });
14269
14420
  } catch (err) {
14270
14421
  throw new RelayerUnavailableError(`the relayer at ${this.url} cannot be reached: ${err.message}`);
@@ -14295,7 +14446,7 @@ var init_relay = __esm({
14295
14446
  functionName: "splitAddress",
14296
14447
  args: [d.token, facts.vault, facts.splits.map((s) => s.recipient), facts.splits.map((s) => s.bps)]
14297
14448
  });
14298
- if (getAddress11(split) !== facts.split) throw new Error(`the relayer's split ${facts.split} is not the OstraSplit of its vault and splits (${split})`);
14449
+ if (getAddress12(split) !== facts.split) throw new Error(`the relayer's split ${facts.split} is not the OstraSplit of its vault and splits (${split})`);
14299
14450
  this.#facts = facts;
14300
14451
  this.#store = new RelayerStore(this.#keys.folder, this.#config.chainId, d.token, facts.vault);
14301
14452
  return facts;
@@ -14317,7 +14468,7 @@ var init_relay = __esm({
14317
14468
  channel: String(open3.channel).toLowerCase(),
14318
14469
  amount: BigInt(String(open3.amount)),
14319
14470
  txHash: String(open3.txHash),
14320
- calls: Array.isArray(open3.calls) ? open3.calls.map((c) => ({ to: getAddress11(c.to), data: c.data })) : []
14471
+ calls: Array.isArray(open3.calls) ? open3.calls.map((c) => ({ to: getAddress12(c.to), data: c.data })) : []
14321
14472
  }
14322
14473
  };
14323
14474
  }
@@ -14371,7 +14522,7 @@ var init_relay = __esm({
14371
14522
  continue;
14372
14523
  }
14373
14524
  const ch = await readChannel(this.#client, this.#config.deployment.batchSettlement, c.channel);
14374
- const usable = payer !== null && getAddress11(c.config.payer) === payer && getAddress11(c.config.receiverAuthorizer) === facts.vault && getAddress11(c.config.receiver) === facts.split && ch.pendingWithdrawal === null && ch.balance - BigInt(c.cumulative) >= amount;
14525
+ const usable = payer !== null && getAddress12(c.config.payer) === payer && getAddress12(c.config.receiverAuthorizer) === facts.vault && getAddress12(c.config.receiver) === facts.split && ch.pendingWithdrawal === null && ch.balance - BigInt(c.cumulative) >= amount;
14375
14526
  if (!usable) {
14376
14527
  c.retired = true;
14377
14528
  await this.#save();
@@ -14439,7 +14590,7 @@ var init_relay = __esm({
14439
14590
  else this.#reserved.delete(reservation.channel);
14440
14591
  }
14441
14592
  async #post(calls, extra, headers = {}) {
14442
- const body = { calls: calls.map((c) => ({ to: getAddress11(c.to), data: c.data })) };
14593
+ const body = { calls: calls.map((c) => ({ to: getAddress12(c.to), data: c.data })) };
14443
14594
  if (extra.prepay === true) body.prepay = true;
14444
14595
  if (extra.payer !== null) body.payer = extra.payer;
14445
14596
  if (extra.allowFailedSwaps === true) body.allowFailedSwaps = true;
@@ -14448,10 +14599,10 @@ var init_relay = __esm({
14448
14599
  /** The x402 HTTP client of relayer channel `c`: the stock batch-settlement client, the vault as payer, the channel's voucher key signing, never depositing. */
14449
14600
  #x402(c) {
14450
14601
  const voucherKey = this.#keys.channelVoucherSigner(this.#config.chainId, this.#config.deployment.token, c.config.salt);
14451
- if (voucherKey.address !== getAddress11(c.config.payerAuthorizer)) throw new Error(`the voucher key of relayer channel ${c.channel} is not derived from this machine's master seed`);
14602
+ if (voucherKey.address !== getAddress12(c.config.payerAuthorizer)) throw new Error(`the voucher key of relayer channel ${c.channel} is not derived from this machine's master seed`);
14452
14603
  const client = this.#client;
14453
14604
  const payer = {
14454
- address: getAddress11(c.config.payer),
14605
+ address: getAddress12(c.config.payer),
14455
14606
  signTypedData: () => Promise.reject(new Error("a vault never signs typed data")),
14456
14607
  readContract: (args) => client.readContract(args)
14457
14608
  };
@@ -14543,11 +14694,11 @@ var init_relay = __esm({
14543
14694
  const config = found.config;
14544
14695
  const id = channelId(config, this.#config.chainId, d.batchSettlement).toLowerCase();
14545
14696
  if (id !== channel.toLowerCase()) throw new Error(`the relayer reports channel ${channel}, but the open in the request is channel ${id}`);
14546
- if (getAddress11(config.receiver) !== facts.split || getAddress11(config.receiverAuthorizer) !== facts.vault || config.withdrawDelay !== facts.gracePeriodSeconds) {
14697
+ if (getAddress12(config.receiver) !== facts.split || getAddress12(config.receiverAuthorizer) !== facts.vault || config.withdrawDelay !== facts.gracePeriodSeconds) {
14547
14698
  throw new Error(`channel ${channel} is not on the relayer's terms`);
14548
14699
  }
14549
14700
  const voucherKey = this.#keys.channelVoucherSigner(this.#config.chainId, d.token, config.salt);
14550
- if (voucherKey.address !== getAddress11(config.payerAuthorizer)) throw new Error(`the voucher key of relayer channel ${channel} is not derived from this machine's master seed`);
14701
+ if (voucherKey.address !== getAddress12(config.payerAuthorizer)) throw new Error(`the voucher key of relayer channel ${channel} is not derived from this machine's master seed`);
14551
14702
  const ch = await this.#openedChannel(id, openTx);
14552
14703
  if (ch.balance !== found.amount || ch.pendingWithdrawal !== null) throw new Error(`relayer channel ${channel} does not hold its deposit of ${found.amount}`);
14553
14704
  const most = debt + await this.#spendBound();
@@ -14702,7 +14853,7 @@ var init_relay = __esm({
14702
14853
  });
14703
14854
 
14704
14855
  // ../core/src/channels.ts
14705
- import { bytesToHex as bytesToHex7, decodeFunctionData as decodeFunctionData4, encodeFunctionData as encodeFunctionData6, getAddress as getAddress12, isAddress as isAddress6, parseAbiItem } from "viem";
14856
+ import { bytesToHex as bytesToHex7, decodeFunctionData as decodeFunctionData4, encodeFunctionData as encodeFunctionData6, getAddress as getAddress13, isAddress as isAddress6, parseAbiItem } from "viem";
14706
14857
  async function channelOpenedLogs(client, vault, channel, fromBlock, toBlock) {
14707
14858
  const out = [];
14708
14859
  for (let from = fromBlock; from <= toBlock; from += LOG_WINDOW_BLOCKS) {
@@ -14718,7 +14869,7 @@ function parseRecipients(input) {
14718
14869
  const out = [];
14719
14870
  for (const r of input) {
14720
14871
  if (!isAddress6(r.recipient, { strict: false })) throw new RangeError(`${r.recipient} is not an address`);
14721
- const recipient = getAddress12(r.recipient);
14872
+ const recipient = getAddress13(r.recipient);
14722
14873
  if (BigInt(recipient) === 0n) throw new RangeError("a recipient must not be the zero address");
14723
14874
  if (!Number.isInteger(r.bps) || r.bps < 1 || r.bps > BPS_DENOMINATOR2) throw new RangeError(`the bps of ${recipient} must be an integer from 1 to ${BPS_DENOMINATOR2}`);
14724
14875
  if (seen.has(recipient)) throw new RangeError(`${recipient} is listed twice`);
@@ -14737,7 +14888,7 @@ function parseGracePeriod(seconds) {
14737
14888
  }
14738
14889
  async function splitAddress(client, config, vault, recipients) {
14739
14890
  const d = config.deployment;
14740
- return getAddress12(
14891
+ return getAddress13(
14741
14892
  await client.readContract({
14742
14893
  address: d.splitFactory,
14743
14894
  abi: ostraSplitFactoryAbi,
@@ -14771,12 +14922,12 @@ async function recoverChannelConfig(client, config, vault, channel) {
14771
14922
  if (log2.transactionHash === null) continue;
14772
14923
  const tx = await client.getTransaction({ hash: log2.transactionHash });
14773
14924
  const calls = [];
14774
- if (tx.to !== null && tx.to !== void 0 && getAddress12(tx.to) === getAddress12(vault)) calls.push({ to: vault, data: tx.input });
14775
- if (tx.to !== null && tx.to !== void 0 && getAddress12(tx.to) === MULTICALL3) {
14925
+ if (tx.to !== null && tx.to !== void 0 && getAddress13(tx.to) === getAddress13(vault)) calls.push({ to: vault, data: tx.input });
14926
+ if (tx.to !== null && tx.to !== void 0 && getAddress13(tx.to) === MULTICALL3) {
14776
14927
  try {
14777
14928
  const decoded = decodeFunctionData4({ abi: multicall3Abi, data: tx.input });
14778
14929
  const inner = decoded.args[0];
14779
- for (const c of inner) if (getAddress12(c.target) === getAddress12(vault)) calls.push({ to: vault, data: c.callData });
14930
+ for (const c of inner) if (getAddress13(c.target) === getAddress13(vault)) calls.push({ to: vault, data: c.callData });
14780
14931
  } catch {
14781
14932
  }
14782
14933
  }
@@ -14856,7 +15007,7 @@ var init_channels = __esm({
14856
15007
  const text2 = await this.#folder.read(name);
14857
15008
  if (text2 === void 0) continue;
14858
15009
  const record = this.#check(JSON.parse(text2), name);
14859
- if (record.chainId === chainId && getAddress12(record.token) === getAddress12(token)) out.push(record);
15010
+ if (record.chainId === chainId && getAddress13(record.token) === getAddress13(token)) out.push(record);
14860
15011
  }
14861
15012
  return out.sort((x, y) => x.createdAt - y.createdAt);
14862
15013
  }
@@ -14904,8 +15055,8 @@ var init_channels = __esm({
14904
15055
  vault,
14905
15056
  channel: opening.channel,
14906
15057
  config: opening.config,
14907
- payee: getAddress12(o.receiverAuthorizer),
14908
- voucherKey: getAddress12(o.payerAuthorizer),
15058
+ payee: getAddress13(o.receiverAuthorizer),
15059
+ voucherKey: getAddress13(o.payerAuthorizer),
14909
15060
  deposit: o.amount.toString(),
14910
15061
  gracePeriod: o.withdrawDelay,
14911
15062
  recipients,
@@ -14941,7 +15092,7 @@ var init_channels = __esm({
14941
15092
  open(input) {
14942
15093
  return this.#serial(async () => {
14943
15094
  if (!isAddress6(input.payee, { strict: false })) throw new RangeError(`${input.payee} is not an address`);
14944
- const payee = getAddress12(input.payee);
15095
+ const payee = getAddress13(input.payee);
14945
15096
  const deposit = parseTokenAmount(input.deposit);
14946
15097
  if (deposit === 0n) throw new RangeError("deposit must be greater than zero");
14947
15098
  const gracePeriod = parseGracePeriod(input.gracePeriod);
@@ -14950,8 +15101,8 @@ var init_channels = __esm({
14950
15101
  if (payeeVault === null) throw new Error(`${payee} is not an Ostra vault; open_channel pays Ostra vaults only (pay other sellers with pay)`);
14951
15102
  if (payeeVault.token !== this.#token()) throw new Error(`the payee vault holds ${payeeVault.token}, not ${this.#token()}`);
14952
15103
  if (input.receiver !== void 0 && recipients.length !== 0) throw new RangeError("a channel names its receiver or the recipients its split is derived from, not both");
14953
- const receiver = input.receiver !== void 0 ? getAddress12(input.receiver) : await splitAddress(this.#client, this.#config, payee, recipients);
14954
- if (receiver === getAddress12("0x0000000000000000000000000000000000000000")) throw new RangeError("the receiver must not be the zero address");
15104
+ const receiver = input.receiver !== void 0 ? getAddress13(input.receiver) : await splitAddress(this.#client, this.#config, payee, recipients);
15105
+ if (receiver === getAddress13("0x0000000000000000000000000000000000000000")) throw new RangeError("the receiver must not be the zero address");
14955
15106
  const salt = randomSalt();
14956
15107
  const voucher = this.#keys.channelVoucherSigner(this.#config.chainId, this.#token(), salt);
14957
15108
  const open3 = { payerAuthorizer: voucher.address, receiver, receiverAuthorizer: payee, withdrawDelay: gracePeriod, salt, amount: deposit };
@@ -14995,7 +15146,7 @@ var init_channels = __esm({
14995
15146
  const view2 = {
14996
15147
  channel: record.channel,
14997
15148
  payee: record.payee,
14998
- receiver: getAddress12(record.config.receiver),
15149
+ receiver: getAddress13(record.config.receiver),
14999
15150
  gracePeriod: record.gracePeriod,
15000
15151
  voucherKey: record.voucherKey,
15001
15152
  closeRequested: record.closeRequested,
@@ -15032,11 +15183,11 @@ var init_channels = __esm({
15032
15183
  const cfg = config ?? await recoverChannelConfig(this.#client, this.#config, vault, channel);
15033
15184
  if (cfg === null) throw new Error(`channel ${channel} was not opened by this agent's vault`);
15034
15185
  const d = this.#config.deployment;
15035
- if (channelId(cfg, this.#config.chainId, d.batchSettlement).toLowerCase() !== channel || getAddress12(cfg.payer) !== vault || getAddress12(cfg.token) !== d.token) {
15186
+ if (channelId(cfg, this.#config.chainId, d.batchSettlement).toLowerCase() !== channel || getAddress13(cfg.payer) !== vault || getAddress13(cfg.token) !== d.token) {
15036
15187
  throw new Error(`channel ${channel} was not opened by this agent's vault`);
15037
15188
  }
15038
15189
  const voucher = this.#keys.channelVoucherSigner(this.#config.chainId, d.token, cfg.salt);
15039
- if (voucher.address !== getAddress12(cfg.payerAuthorizer)) throw new Error(`channel ${channel} uses a voucher key this machine cannot derive`);
15190
+ if (voucher.address !== getAddress13(cfg.payerAuthorizer)) throw new Error(`channel ${channel} uses a voucher key this machine cannot derive`);
15040
15191
  const ch = await this.#read(channel);
15041
15192
  const open3 = {
15042
15193
  payerAuthorizer: cfg.payerAuthorizer,
@@ -15114,7 +15265,7 @@ var init_channels = __esm({
15114
15265
  sent,
15115
15266
  ...extra
15116
15267
  });
15117
- if (getAddress12(record.config.payer) !== getAddress12(record.vault)) throw new Error(`channel ${channel} does not belong to this vault's record`);
15268
+ if (getAddress13(record.config.payer) !== getAddress13(record.vault)) throw new Error(`channel ${channel} does not belong to this vault's record`);
15118
15269
  for (let i = 0; i < MAX_STEPS_PER_CALL; i++) {
15119
15270
  const ch = await this.#read(channel);
15120
15271
  const status = channelStatus(ch);
@@ -15129,7 +15280,7 @@ var init_channels = __esm({
15129
15280
  try {
15130
15281
  if (status === "open") {
15131
15282
  const voucher = this.voucherSigner(record);
15132
- if (voucher.address !== getAddress12(record.config.payerAuthorizer)) throw new Error(`the voucher key of channel ${channel} could not be derived`);
15283
+ if (voucher.address !== getAddress13(record.config.payerAuthorizer)) throw new Error(`the voucher key of channel ${channel} could not be derived`);
15133
15284
  const amount = ch.balance - ch.totalClaimed;
15134
15285
  const closeNonce = await this.#client.readContract({ address: record.vault, abi: ostraVaultAbi, functionName: "closeNonce", args: [channel] });
15135
15286
  const deadline = await chainTime(this.#client) + CLOSE_REQUEST_TTL_SECONDS;
@@ -15319,14 +15470,14 @@ var init_passkey = __esm({
15319
15470
  });
15320
15471
 
15321
15472
  // ../core/src/keys.ts
15322
- import { bytesToHex as bytesToHex9, getAddress as getAddress13, hexToBytes as hexToBytes7 } from "viem";
15473
+ import { bytesToHex as bytesToHex9, getAddress as getAddress14, hexToBytes as hexToBytes7 } from "viem";
15323
15474
  import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
15324
15475
  function chainBytes(chainId) {
15325
15476
  if (!Number.isSafeInteger(chainId) || chainId <= 0) throw new RangeError("chainId must be a positive integer");
15326
15477
  return hexToBytes7(`0x${BigInt(chainId).toString(16).padStart(64, "0")}`);
15327
15478
  }
15328
15479
  function tokenBytes(token) {
15329
- return hexToBytes7(getAddress13(token));
15480
+ return hexToBytes7(getAddress14(token));
15330
15481
  }
15331
15482
  function u64Be(value) {
15332
15483
  if (value < 0n || value > U64_MAX5) throw new RangeError("index out of range");
@@ -15419,7 +15570,7 @@ var init_keys = __esm({
15419
15570
  * payer and the WOTS store stay the agent's.
15420
15571
  */
15421
15572
  async forPrivateVault(chainId, token, index) {
15422
- const folder = this.#root.folder(PRIVATE_DIR).folder(`${chainId}-${getAddress13(token)}-${index}`);
15573
+ const folder = this.#root.folder(PRIVATE_DIR).folder(`${chainId}-${getAddress14(token)}-${index}`);
15423
15574
  await folder.ensure();
15424
15575
  return new _Keys({ master: this.#master, feePayer: this.feePayer, store: this.store, folder, root: this.#root, backupExported: this.#backupExported, escrow: this.escrow });
15425
15576
  }
@@ -15430,7 +15581,7 @@ var init_keys = __esm({
15430
15581
  * agent's folder (ShieldService takes the agent's keys).
15431
15582
  */
15432
15583
  async forCreatorVault(chainId, token) {
15433
- const folder = this.#root.folder(CREATOR_DIR).folder(`${chainId}-${getAddress13(token)}`);
15584
+ const folder = this.#root.folder(CREATOR_DIR).folder(`${chainId}-${getAddress14(token)}`);
15434
15585
  await folder.ensure();
15435
15586
  return new _Keys({ master: this.#master, feePayer: this.feePayer, store: this.store, folder, root: this.#root, backupExported: this.#backupExported, escrow: this.escrow });
15436
15587
  }
@@ -15528,13 +15679,13 @@ var init_keys = __esm({
15528
15679
  });
15529
15680
 
15530
15681
  // ../core/src/pools.ts
15531
- import { getAddress as getAddress14, isAddress as isAddress7, zeroAddress as zeroAddress7 } from "viem";
15682
+ import { getAddress as getAddress15, isAddress as isAddress7, zeroAddress as zeroAddress7 } from "viem";
15532
15683
  function iso(seconds) {
15533
15684
  return new Date(Number(seconds) * 1e3).toISOString();
15534
15685
  }
15535
15686
  function launchedTokenAddress(text2, what = "token") {
15536
15687
  if (!isAddress7(text2, { strict: false })) throw new RangeError(`${what} ${text2} is not an address`);
15537
- return getAddress14(text2);
15688
+ return getAddress15(text2);
15538
15689
  }
15539
15690
  async function readLaunchedPool(client, lp, tokenText) {
15540
15691
  const token = launchedTokenAddress(tokenText);
@@ -15547,7 +15698,7 @@ async function readLaunchedPool(client, lp, tokenText) {
15547
15698
  return { token, id, key, config };
15548
15699
  }
15549
15700
  function quoteOfPool(pool) {
15550
- return getAddress14(pool.config.tokenIs0 ? pool.key.currency1 : pool.key.currency0);
15701
+ return getAddress15(pool.config.tokenIs0 ? pool.key.currency1 : pool.key.currency0);
15551
15702
  }
15552
15703
  async function readPoolView(client, lp, tokenText) {
15553
15704
  const pool = await readLaunchedPool(client, lp, tokenText);
@@ -15581,7 +15732,7 @@ async function readPoolView(client, lp, tokenText) {
15581
15732
  name,
15582
15733
  symbol,
15583
15734
  quote,
15584
- creatorVault: getAddress14(c.creatorVault),
15735
+ creatorVault: getAddress15(c.creatorVault),
15585
15736
  graduated: state.graduated,
15586
15737
  tokensSold: formatUnitsAmount(state.tokensSold < 0n ? 0n : state.tokensSold, 18),
15587
15738
  quoteRaised: fmtQuote(state.quoteRaised),
@@ -15593,7 +15744,7 @@ async function readPoolView(client, lp, tokenText) {
15593
15744
  sellTaxBps: Number(rates[1]),
15594
15745
  antiSnipeBps: Number(rates[2]),
15595
15746
  maxBuy: c.maxBuy === 0n ? null : formatUnitsAmount(c.maxBuy, 18),
15596
- dividendToken: getAddress14(c.dividendToken) === zeroAddress7 ? null : getAddress14(c.dividendToken),
15747
+ dividendToken: getAddress15(c.dividendToken) === zeroAddress7 ? null : getAddress15(c.dividendToken),
15597
15748
  launchedAt: iso(BigInt(c.launchedAt)),
15598
15749
  airdrop: {
15599
15750
  round: round.number,
@@ -15604,7 +15755,7 @@ async function readPoolView(client, lp, tokenText) {
15604
15755
  available: formatUnitsAmount(available, 18),
15605
15756
  nextRoundAmount: formatUnitsAmount(nextAmount, 18)
15606
15757
  },
15607
- creatorShares: shares[0].map((recipient, i) => ({ recipient: getAddress14(recipient), bps: Number(shares[1][i]) })),
15758
+ creatorShares: shares[0].map((recipient, i) => ({ recipient: getAddress15(recipient), bps: Number(shares[1][i]) })),
15608
15759
  rules: {
15609
15760
  quoteDecimals,
15610
15761
  supply: formatUnitsAmount(state.supply, 18),
@@ -15777,7 +15928,7 @@ var init_pending = __esm({
15777
15928
  });
15778
15929
 
15779
15930
  // ../core/src/vault.ts
15780
- import { bytesToHex as bytesToHex10, encodeAbiParameters as encodeAbiParameters5, encodeFunctionData as encodeFunctionData7, getAddress as getAddress15, isAddress as isAddress8, keccak256 as keccak25610, zeroAddress as zeroAddress9 } from "viem";
15931
+ import { bytesToHex as bytesToHex10, encodeAbiParameters as encodeAbiParameters6, encodeFunctionData as encodeFunctionData7, getAddress as getAddress16, isAddress as isAddress8, keccak256 as keccak25611, zeroAddress as zeroAddress9 } from "viem";
15781
15932
  function spendGas(calls) {
15782
15933
  return calls.reduce((gas, c) => gas + reservedSwapGas(c), VAULT_SPEND_GAS);
15783
15934
  }
@@ -15822,9 +15973,9 @@ var init_vault = __esm({
15822
15973
  if (kind === "private" !== (privateIndex !== null)) throw new Error("a private vault, and only a private vault, has an index");
15823
15974
  if (kind === "token" && vaultToken === null) throw new Error("a token vault names its token");
15824
15975
  if (vaultToken !== null && kind !== "token" && kind !== "creator") throw new Error("only a token vault or a creator vault names its token");
15825
- if (vaultToken !== null && getAddress15(vaultToken) === config.deployment.token) throw new Error(`the vault in ${vaultToken} is the ${kind === "creator" ? "USDG creator vault, named without a token" : "buyer vault, not a token vault"}`);
15976
+ if (vaultToken !== null && getAddress16(vaultToken) === config.deployment.token) throw new Error(`the vault in ${vaultToken} is the ${kind === "creator" ? "USDG creator vault, named without a token" : "buyer vault, not a token vault"}`);
15826
15977
  this.kind = kind;
15827
- this.token = vaultToken === null ? config.deployment.token : getAddress15(vaultToken);
15978
+ this.token = vaultToken === null ? config.deployment.token : getAddress16(vaultToken);
15828
15979
  this.privateIndex = privateIndex;
15829
15980
  this.#client = client;
15830
15981
  this.#transport = transport;
@@ -15839,7 +15990,7 @@ var init_vault = __esm({
15839
15990
  setInitCrank(crank) {
15840
15991
  if (this.kind !== "seller") throw new Error(`the ${this.kind} vault is created without a crank`);
15841
15992
  if (!isAddress8(crank, { strict: false })) throw new RangeError("a crank is an address");
15842
- this.#initCrank = getAddress15(crank);
15993
+ this.#initCrank = getAddress16(crank);
15843
15994
  }
15844
15995
  /** A vault in the deployment's token (USDG); else a token vault or a pair's creator vault, paid for by the buyer vault. */
15845
15996
  #inUsdg() {
@@ -15879,10 +16030,10 @@ var init_vault = __esm({
15879
16030
  return null;
15880
16031
  }
15881
16032
  const r = JSON.parse(text2);
15882
- if (r.chainId !== this.#config.chainId || typeof r.token !== "string" || getAddress15(r.token) !== this.token || typeof r.vault !== "string" || !isAddress8(r.vault, { strict: false })) {
16033
+ if (r.chainId !== this.#config.chainId || typeof r.token !== "string" || getAddress16(r.token) !== this.token || typeof r.vault !== "string" || !isAddress8(r.vault, { strict: false })) {
15883
16034
  throw new Error(`${this.#adoptedName()} is not a recovered vault of chain ${this.#config.chainId} in ${this.token}`);
15884
16035
  }
15885
- this.#adopted = getAddress15(r.vault);
16036
+ this.#adopted = getAddress16(r.vault);
15886
16037
  return this.#adopted;
15887
16038
  }
15888
16039
  async vaultAddress() {
@@ -16134,7 +16285,7 @@ var init_vault = __esm({
16134
16285
  const s2 = decodeVaultSpendMessage(message);
16135
16286
  const { devBuy, launchHash: hash } = decodeDevBuyParams(s2.params);
16136
16287
  const lp = this.#config.deployment.launchpad;
16137
- if (lp === void 0 || getAddress15(devBuy) !== lp.devBuy) throw new Error(`the vault signed a DevBuy for ${devBuy}, not this deployment's OstraDevBuy`);
16288
+ if (lp === void 0 || getAddress16(devBuy) !== lp.devBuy) throw new Error(`the vault signed a DevBuy for ${devBuy}, not this deployment's OstraDevBuy`);
16138
16289
  const l = await this.#signedLaunch(vault, v.nonce, hash);
16139
16290
  const call = { to: lp.devBuy, data: launchFromVaultData(l.launch, l.dev, { nextKeyRoot: s2.nextKeyRoot, signature }) };
16140
16291
  const txHash2 = await sender.send([call], { reservation, value: LAUNCHPAD.FEE_WEI });
@@ -16237,7 +16388,7 @@ the signed ${op.what} is kept; the next call on this vault sends it again before
16237
16388
  const amount = parseTokenAmount(amountText);
16238
16389
  if (amount === 0n) throw new RangeError("amount must be greater than zero");
16239
16390
  if (!isAddress8(destinationText, { strict: false })) throw new RangeError(`${destinationText} is not an address`);
16240
- const destination = getAddress15(destinationText);
16391
+ const destination = getAddress16(destinationText);
16241
16392
  if (destination === zeroAddress9) throw new RangeError("the destination must not be the zero address");
16242
16393
  await this.#checkToken();
16243
16394
  const vault = await this.vaultAddress();
@@ -16288,7 +16439,7 @@ the signed withdrawal is kept; the next withdraw or open_channel call sends it a
16288
16439
  if (this.kind === "seller") throw new Error("channels are not opened from the seller vault");
16289
16440
  await this.#checkToken();
16290
16441
  const vault = await this.vaultAddress();
16291
- if (getAddress15(open3.receiverAuthorizer) === vault || getAddress15(open3.receiver) === vault) throw new Error("the channel would pay this agent's own vault");
16442
+ if (getAddress16(open3.receiverAuthorizer) === vault || getAddress16(open3.receiver) === vault) throw new Error("the channel would pay this agent's own vault");
16292
16443
  if (await this.#read(vault) === null) throw new Error(this.#missing());
16293
16444
  await this.requireEth(VAULT_SPEND_GAS, "send the vault operation");
16294
16445
  return this.#paidSpend(this.#sender, async (sender, reservation) => {
@@ -16362,7 +16513,7 @@ the signed channel open is kept; the next open_channel or withdraw call sends it
16362
16513
  setCrankKey(crankText, via) {
16363
16514
  return this.#serial(async () => {
16364
16515
  if (!isAddress8(crankText, { strict: false })) throw new RangeError("a crank is an address");
16365
- const crank = getAddress15(crankText);
16516
+ const crank = getAddress16(crankText);
16366
16517
  const target = crank === zeroAddress9 ? null : crank;
16367
16518
  const vault = await this.vaultAddress();
16368
16519
  if (await this.#read(vault) === null) throw new Error(this.#missing());
@@ -16450,7 +16601,7 @@ the signed operation is kept; the next call on this vault sends it again before
16450
16601
  /** Adds (enabled) or removes a guardian of this vault: another Ostra vault keeps the recovery post-quantum. */
16451
16602
  async setGuardian(guardianText, enabled, via) {
16452
16603
  if (!isAddress8(guardianText, { strict: false })) throw new RangeError(`${guardianText} is not an address`);
16453
- const guardian = getAddress15(guardianText);
16604
+ const guardian = getAddress16(guardianText);
16454
16605
  if (guardian === zeroAddress9) throw new RangeError("a guardian is not the zero address");
16455
16606
  return this.#recoverySpend(
16456
16607
  (v) => signVaultSetGuardian(this.#keychain, v, { chainId: this.#config.chainId, guardian, enabled }),
@@ -16496,7 +16647,7 @@ the signed operation is kept; the next call on this vault sends it again before
16496
16647
  /** As a guardian (this vault), supports moving `vaultText` to `newKeyRootText` (the key root its owner's new device gave). */
16497
16648
  async supportRecovery(vaultText, newKeyRootText, via) {
16498
16649
  if (!isAddress8(vaultText, { strict: false })) throw new RangeError(`${vaultText} is not an address`);
16499
- const target = getAddress15(vaultText);
16650
+ const target = getAddress16(vaultText);
16500
16651
  if (!/^0x[0-9a-fA-F]{64}$/.test(newKeyRootText) || /^0x0{64}$/.test(newKeyRootText)) throw new RangeError("the new key root is 32 bytes of 0x hex, not zero");
16501
16652
  const newKeyRoot = newKeyRootText.toLowerCase();
16502
16653
  return this.#recoverySpend(
@@ -16509,7 +16660,7 @@ the signed operation is kept; the next call on this vault sends it again before
16509
16660
  if (!await read("isGuardian", [vault])) throw new Error(`this vault ${vault} is not a guardian of ${target}`);
16510
16661
  const r = await readRecovery(this.#client, target);
16511
16662
  if (r.threshold === 0) throw new Error(`${target} has recovery turned off`);
16512
- const proposal = keccak25610(encodeAbiParameters5([{ type: "uint32" }, { type: "bytes32" }], [r.round, newKeyRoot]));
16663
+ const proposal = keccak25611(encodeAbiParameters6([{ type: "uint32" }, { type: "bytes32" }], [r.round, newKeyRoot]));
16513
16664
  return await read("supportedBy", [proposal, vault]);
16514
16665
  },
16515
16666
  via
@@ -16525,7 +16676,7 @@ the signed operation is kept; the next call on this vault sends it again before
16525
16676
  return this.#serial(async () => {
16526
16677
  if (this.kind === "private") throw new Error("a private vault is recovered with the seed that unshielded it");
16527
16678
  if (!isAddress8(vaultText, { strict: false })) throw new RangeError(`${vaultText} is not an address`);
16528
- const vault = getAddress15(vaultText);
16679
+ const vault = getAddress16(vaultText);
16529
16680
  const v = await readVault(this.#client, this.#config.deployment, vault);
16530
16681
  if (v === null || v.token !== this.token) throw new Error(`${vault} is not an Ostra vault in ${this.token}`);
16531
16682
  const adopted = await this.#adoptedVault();
@@ -16583,7 +16734,7 @@ the signed operation is kept; the next call on this vault sends it again before
16583
16734
  });
16584
16735
 
16585
16736
  // ../core/src/launchpad.ts
16586
- import { bytesToHex as bytesToHex11, decodeEventLog as decodeEventLog3, encodeFunctionData as encodeFunctionData8, getAddress as getAddress16, isAddress as isAddress9, parseAbiItem as parseAbiItem2, zeroAddress as zeroAddress10 } from "viem";
16737
+ import { bytesToHex as bytesToHex11, decodeEventLog as decodeEventLog3, encodeFunctionData as encodeFunctionData8, getAddress as getAddress17, isAddress as isAddress9, parseAbiItem as parseAbiItem2, zeroAddress as zeroAddress10 } from "viem";
16587
16738
  async function readIpfsJson(uri2) {
16588
16739
  if (uri2 === null || !uri2.startsWith("ipfs://")) return null;
16589
16740
  const path = uri2.slice("ipfs://".length).replace(/^ipfs\//, "");
@@ -16620,7 +16771,7 @@ function nowIso(seconds) {
16620
16771
  }
16621
16772
  function address2(text2, what) {
16622
16773
  if (!isAddress9(text2, { strict: false })) throw new RangeError(`${what} ${text2} is not an address`);
16623
- return getAddress16(text2);
16774
+ return getAddress17(text2);
16624
16775
  }
16625
16776
  function slippage(bps) {
16626
16777
  const s = bps ?? QUOTE_DEFAULT_SLIPPAGE_BPS;
@@ -16723,8 +16874,8 @@ var init_launchpad = __esm({
16723
16874
  */
16724
16875
  async #notStranded(to, paid, what) {
16725
16876
  const v = await readVault(this.#client, this.#config.deployment, to);
16726
- if (v !== null && v.token !== getAddress16(paid)) {
16727
- throw new Error(`${to} is an Ostra vault in ${v.token}: a vault only moves its own token, so ${what} in ${getAddress16(paid)} would be stuck there for good; nothing was signed`);
16877
+ if (v !== null && v.token !== getAddress17(paid)) {
16878
+ throw new Error(`${to} is an Ostra vault in ${v.token}: a vault only moves its own token, so ${what} in ${getAddress17(paid)} would be stuck there for good; nothing was signed`);
16728
16879
  }
16729
16880
  }
16730
16881
  /** The token a pair's vaults hold: the pair's own; WETH for ETH. */
@@ -16816,9 +16967,9 @@ var init_launchpad = __esm({
16816
16967
  const pool = await this.#pool(tokenText);
16817
16968
  const s = await this.tokenVault(pool.token).state();
16818
16969
  let dividends = null;
16819
- if (getAddress16(pool.config.dividendToken) !== zeroAddress10) {
16970
+ if (getAddress17(pool.config.dividendToken) !== zeroAddress10) {
16820
16971
  const owed = await this.#client.readContract({ address: pool.token, abi: ostraTokenAbi, functionName: "dividendOf", args: [s.vault] });
16821
- const decimals = getAddress16(pool.config.dividendToken) === this.#usdg() ? TOKEN_DECIMALS : await tokenDecimals(this.#client, getAddress16(pool.config.dividendToken));
16972
+ const decimals = getAddress17(pool.config.dividendToken) === this.#usdg() ? TOKEN_DECIMALS : await tokenDecimals(this.#client, getAddress17(pool.config.dividendToken));
16822
16973
  dividends = formatUnitsAmount(owed, decimals);
16823
16974
  }
16824
16975
  return { token: pool.token, vault: s.vault, exists: s.exists, balance: formatUnitsAmount(s.balance, 18), dividends, pendingOperation: s.pendingAction };
@@ -16846,7 +16997,7 @@ var init_launchpad = __esm({
16846
16997
  const pair3 = findLaunchPair(quote);
16847
16998
  if (pair3 === null) throw new Error(`the pool of ${pool.token} trades against ${quote}, not a pair Ostra offers (USDG, ETH, OSTRA or a listed stock token); nothing was signed`);
16848
16999
  const referrer = a.referrer === void 0 ? void 0 : address2(a.referrer, "referrer");
16849
- const quoteIs0 = getAddress16(pool.key.currency0) === quote;
17000
+ const quoteIs0 = getAddress17(pool.key.currency0) === quote;
16850
17001
  const buying = a.side === "buy";
16851
17002
  const quoteVault = this.tokenVault(quote);
16852
17003
  const from = buying ? quoteVault : this.tokenVault(pool.token);
@@ -16877,7 +17028,7 @@ var init_launchpad = __esm({
16877
17028
  async #swapOutcome(txHash, vault) {
16878
17029
  const receipt = await this.#client.getTransactionReceipt({ hash: txHash });
16879
17030
  for (const log2 of receipt.logs) {
16880
- if (getAddress16(log2.address) !== vault) continue;
17031
+ if (getAddress17(log2.address) !== vault) continue;
16881
17032
  try {
16882
17033
  const e = decodeEventLog3({ abi: ostraVaultAbi, topics: log2.topics, data: log2.data });
16883
17034
  if (e.eventName === "Swapped") {
@@ -16969,7 +17120,7 @@ var init_launchpad = __esm({
16969
17120
  /** Claims the dividends the agent's token vault for `token` earned, into the agent's vault of the dividend token. */
16970
17121
  async claimDividends(tokenText) {
16971
17122
  const pool = await this.#pool(tokenText);
16972
- const dividendToken = getAddress16(pool.config.dividendToken);
17123
+ const dividendToken = getAddress17(pool.config.dividendToken);
16973
17124
  if (dividendToken === zeroAddress10) throw new Error(`the pool of ${pool.token} pays no dividends`);
16974
17125
  const v = this.tokenVault(pool.token);
16975
17126
  const s = await v.state();
@@ -17077,7 +17228,7 @@ var init_launchpad = __esm({
17077
17228
  creatorVault,
17078
17229
  startTick
17079
17230
  });
17080
- const token = getAddress16(await this.#client.readContract({ address: lp.devBuy, abi: ostraDevBuyAbi, functionName: "tokenAddressFromVault", args: [p] }));
17231
+ const token = getAddress17(await this.#client.readContract({ address: lp.devBuy, abi: ostraDevBuyAbi, functionName: "tokenAddressFromVault", args: [p] }));
17081
17232
  const tokenVault = await this.tokenVault(token).vaultAddress();
17082
17233
  let dev = NO_DEV_BUY;
17083
17234
  if (input.devBuy !== void 0) {
@@ -17085,7 +17236,7 @@ var init_launchpad = __esm({
17085
17236
  if (quoteIn === 0n) throw new RangeError("the dev buy amount must be greater than zero (leave devBuy out for none)");
17086
17237
  const cliff = Math.round((input.devBuy.cliffDays ?? DEV_BUY.MIN_CLIFF / DAY) * DAY);
17087
17238
  const duration = Math.round((input.devBuy.vestingDays ?? 0) * DAY);
17088
- const dividendToken = getAddress16(p.dividendToken);
17239
+ const dividendToken = getAddress17(p.dividendToken);
17089
17240
  dev = {
17090
17241
  quoteIn,
17091
17242
  beneficiary: tokenVault,
@@ -17123,14 +17274,14 @@ var init_launchpad = __esm({
17123
17274
  let bought = null;
17124
17275
  for (const log2 of receipt.logs) {
17125
17276
  try {
17126
- if (getAddress16(log2.address) === lp.launchpad) {
17277
+ if (getAddress17(log2.address) === lp.launchpad) {
17127
17278
  const e = decodeEventLog3({ abi: ostraLaunchpadAbi, topics: log2.topics, data: log2.data });
17128
17279
  if (e.eventName === "Launched") poolId2 = e.args.poolId;
17129
- } else if (getAddress16(log2.address) === lp.devBuy) {
17280
+ } else if (getAddress17(log2.address) === lp.devBuy) {
17130
17281
  const e = decodeEventLog3({ abi: ostraDevBuyAbi, topics: log2.topics, data: log2.data });
17131
17282
  if (e.eventName === "DevBought") {
17132
17283
  const g = e.args;
17133
- bought = { ...g, vesting: getAddress16(g.vesting) };
17284
+ bought = { ...g, vesting: getAddress17(g.vesting) };
17134
17285
  }
17135
17286
  }
17136
17287
  } catch {
@@ -17167,7 +17318,7 @@ var init_launchpad = __esm({
17167
17318
  if (pair3 === null) throw new Error(`the pool of ${pool.token} trades against ${this.#quoteOf(pool)}, not a pair Ostra offers; no creator vault of this agent owns it`);
17168
17319
  const { vault: creator, sender } = await this.pairCreator(pair3.symbol);
17169
17320
  const creatorVault = await creator.vaultAddress();
17170
- if (getAddress16(pool.config.creatorVault) !== creatorVault) throw new Error(`the pool of ${pool.token} belongs to the creator vault ${pool.config.creatorVault}, not this agent's ${pair3.symbol} creator vault ${creatorVault}`);
17321
+ if (getAddress17(pool.config.creatorVault) !== creatorVault) throw new Error(`the pool of ${pool.token} belongs to the creator vault ${pool.config.creatorVault}, not this agent's ${pair3.symbol} creator vault ${creatorVault}`);
17171
17322
  return { pool, pair: pair3, creator, sender };
17172
17323
  }
17173
17324
  /**
@@ -17220,7 +17371,7 @@ var init_launchpad = __esm({
17220
17371
  if (amountIn === 0n) throw new RangeError("amount must be greater than zero");
17221
17372
  const s = await creator.state();
17222
17373
  if (s.balance < amountIn) throw new Error(`the ${pair3.symbol} creator vault holds ${formatUnitsAmount(s.balance, pair3.decimals)}, less than ${a.amount}; fund it with fund_creator_vault`);
17223
- const quoteIs0 = getAddress16(pool.key.currency0) === pair3.address;
17374
+ const quoteIs0 = getAddress17(pool.key.currency0) === pair3.address;
17224
17375
  const q = await quoteVaultSwap(this.#client, this.#config.deployment, {
17225
17376
  vault: s.vault,
17226
17377
  relayer: await sender.payer(),
@@ -17306,7 +17457,7 @@ var init_launchpad = __esm({
17306
17457
  } else {
17307
17458
  const text2 = await this.#folder.read(this.#airdropName(pool.id, r.number));
17308
17459
  if (text2 === void 0) throw new Error(`no tree of round ${r.number} is kept here; give the amount and proof`);
17309
- const claim = JSON.parse(text2).claims.find((c) => getAddress16(c.account) === account);
17460
+ const claim = JSON.parse(text2).claims.find((c) => getAddress17(c.account) === account);
17310
17461
  if (claim === void 0) throw new Error(`${account} is not in round ${r.number}`);
17311
17462
  amount = BigInt(claim.amount);
17312
17463
  proof = claim.proof;
@@ -17341,7 +17492,7 @@ var init_launchpad = __esm({
17341
17492
  const text2 = await this.#folder.read(this.#launchName(token));
17342
17493
  const v = text2 === void 0 ? null : JSON.parse(text2).vesting ?? null;
17343
17494
  if (v === null) throw new Error(`this agent's records hold no dev buy vesting of ${token}; give its address`);
17344
- vesting = getAddress16(v);
17495
+ vesting = getAddress17(v);
17345
17496
  }
17346
17497
  const id = await this.#client.readContract({ address: lp.devBuy, abi: ostraDevBuyAbi, functionName: "vestingPool", args: [vesting] });
17347
17498
  if (BigInt(id) === 0n) throw new Error(`${vesting} is not an Ostra dev buy's vesting`);
@@ -17352,8 +17503,8 @@ var init_launchpad = __esm({
17352
17503
  const vesting = await this.#vesting(a.token, a.vesting);
17353
17504
  const read = (functionName) => this.#client.readContract({ address: vesting, abi: ostraVestingAbi, functionName });
17354
17505
  const [terms, schedule, releasable] = await Promise.all([read("terms"), read("schedule"), read("releasable")]);
17355
- const held = await tokenBalance(this.#client, getAddress16(terms.token), vesting);
17356
- return { vesting, beneficiary: getAddress16(terms.beneficiary), cliffEnd: nowIso(schedule[0]), end: nowIso(schedule[1]), held: formatUnitsAmount(held, 18), releasable: formatUnitsAmount(releasable, 18) };
17506
+ const held = await tokenBalance(this.#client, getAddress17(terms.token), vesting);
17507
+ return { vesting, beneficiary: getAddress17(terms.beneficiary), cliffEnd: nowIso(schedule[0]), end: nowIso(schedule[1]), held: formatUnitsAmount(held, 18), releasable: formatUnitsAmount(releasable, 18) };
17357
17508
  }
17358
17509
  /** Releases what the vesting has vested to its beneficiary (this agent's token vault). */
17359
17510
  async vestingRelease(a) {
@@ -17390,7 +17541,7 @@ var init_launchpad = __esm({
17390
17541
  await this.#folder.ensure();
17391
17542
  const text2 = await this.#folder.read("token-index.json");
17392
17543
  let index = text2 === void 0 ? { version: 1, launchpad: lp.launchpad, scannedTo: (BigInt(this.#config.deployment.fromBlock) - 1n).toString(), launches: [] } : JSON.parse(text2);
17393
- if (getAddress16(index.launchpad) !== getAddress16(lp.launchpad)) index = { version: 1, launchpad: lp.launchpad, scannedTo: (BigInt(this.#config.deployment.fromBlock) - 1n).toString(), launches: [] };
17544
+ if (getAddress17(index.launchpad) !== getAddress17(lp.launchpad)) index = { version: 1, launchpad: lp.launchpad, scannedTo: (BigInt(this.#config.deployment.fromBlock) - 1n).toString(), launches: [] };
17394
17545
  const latest = await this.#client.getBlockNumber();
17395
17546
  let from = BigInt(index.scannedTo) + 1n;
17396
17547
  if (from > latest) return index;
@@ -17399,7 +17550,7 @@ var init_launchpad = __esm({
17399
17550
  const logs = await this.#client.getLogs({ address: lp.launchpad, event: launchedEvent, fromBlock: from, toBlock: to });
17400
17551
  for (const l of logs) {
17401
17552
  if (l.args.token === void 0 || l.args.poolId === void 0 || l.args.creatorVault === void 0 || l.args.quote === void 0 || l.transactionHash === null || l.blockNumber === null) continue;
17402
- index.launches.push({ token: getAddress16(l.args.token), poolId: l.args.poolId, creatorVault: getAddress16(l.args.creatorVault), quote: getAddress16(l.args.quote), block: l.blockNumber.toString(), txHash: l.transactionHash });
17553
+ index.launches.push({ token: getAddress17(l.args.token), poolId: l.args.poolId, creatorVault: getAddress17(l.args.creatorVault), quote: getAddress17(l.args.quote), block: l.blockNumber.toString(), txHash: l.transactionHash });
17403
17554
  }
17404
17555
  index.scannedTo = to.toString();
17405
17556
  }
@@ -17499,7 +17650,7 @@ var init_launchpad = __esm({
17499
17650
  const receipt = await this.#client.getTransactionReceipt({ hash: r.txHash });
17500
17651
  let agentId;
17501
17652
  for (const log2 of receipt.logs) {
17502
- if (getAddress16(log2.address) !== vault) continue;
17653
+ if (getAddress17(log2.address) !== vault) continue;
17503
17654
  try {
17504
17655
  const e = decodeEventLog3({ abi: ostraVaultAbi, data: log2.data, topics: log2.topics });
17505
17656
  if (e.eventName === "AgentRegistered") agentId = e.args.agentId.toString();
@@ -17588,17 +17739,17 @@ var init_launchpad = __esm({
17588
17739
  });
17589
17740
 
17590
17741
  // ../core/src/pay.ts
17591
- import { getAddress as getAddress17, isAddress as isAddress10 } from "viem";
17742
+ import { getAddress as getAddress18, isAddress as isAddress10 } from "viem";
17592
17743
  import { x402Client as x402Client2, x402HTTPClient as x402HTTPClient2 } from "@x402/core/client";
17593
17744
  import { toClientEvmSigner as toClientEvmSigner2 } from "@x402/evm";
17594
17745
  import { BatchSettlementEvmScheme as BatchSettlementEvmScheme2 } from "@x402/evm/batch-settlement/client";
17595
17746
  function offerProblem(r, network, token) {
17596
17747
  if (r.scheme !== "batch-settlement") return `${r.scheme} (this agent pays batch-settlement)`;
17597
17748
  if (r.network !== network) return `on ${r.network} (this agent pays on ${network})`;
17598
- if (!isAddress10(r.asset, { strict: false }) || getAddress17(r.asset) !== token) return `in ${r.asset} (this agent pays in ${token})`;
17749
+ if (!isAddress10(r.asset, { strict: false }) || getAddress18(r.asset) !== token) return `in ${r.asset} (this agent pays in ${token})`;
17599
17750
  return null;
17600
17751
  }
17601
- var PAY_CHANNEL_DEPOSIT, PAY_MAX_BODY_CHARS, REQUEST_TIMEOUT_MS2, MIN_LIFE_LEFT_SECONDS, now2, PayService;
17752
+ var PAY_CHANNEL_DEPOSIT, PAY_MAX_BODY_CHARS, REQUEST_TIMEOUT_MS3, MIN_LIFE_LEFT_SECONDS, now2, PayService;
17602
17753
  var init_pay = __esm({
17603
17754
  "../core/src/pay.ts"() {
17604
17755
  "use strict";
@@ -17609,7 +17760,7 @@ var init_pay = __esm({
17609
17760
  init_channels();
17610
17761
  PAY_CHANNEL_DEPOSIT = 1000000n;
17611
17762
  PAY_MAX_BODY_CHARS = 65536;
17612
- REQUEST_TIMEOUT_MS2 = 12e4;
17763
+ REQUEST_TIMEOUT_MS3 = 12e4;
17613
17764
  MIN_LIFE_LEFT_SECONDS = 300;
17614
17765
  now2 = () => Math.floor(Date.now() / 1e3);
17615
17766
  PayService = class {
@@ -17635,23 +17786,23 @@ var init_pay = __esm({
17635
17786
  method: input.method ?? "GET",
17636
17787
  headers: { ...input.headers ?? {}, ...headers },
17637
17788
  ...input.body === void 0 ? {} : { body: input.body },
17638
- signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2),
17789
+ signal: AbortSignal.timeout(input.timeoutMs ?? REQUEST_TIMEOUT_MS3),
17639
17790
  redirect: "manual"
17640
17791
  });
17641
17792
  } catch (err) {
17642
17793
  throw new Error(`${input.url} cannot be reached: ${err.message}`);
17643
17794
  }
17644
17795
  }
17645
- async #answer(res, paid, record, note) {
17796
+ async #answer(res, paid, record, note, maxBodyChars = PAY_MAX_BODY_CHARS) {
17646
17797
  const text2 = await res.text();
17647
- const truncated = text2.length > PAY_MAX_BODY_CHARS;
17798
+ const truncated = text2.length > maxBodyChars;
17648
17799
  return {
17649
17800
  status: res.status,
17650
17801
  paid: paid === null ? null : formatTokenAmount(paid),
17651
17802
  channel: record === null ? null : record.channel,
17652
17803
  channelLeft: record === null ? null : formatTokenAmount(payCapacity(record)),
17653
17804
  contentType: res.headers.get("content-type"),
17654
- body: truncated ? text2.slice(0, PAY_MAX_BODY_CHARS) : text2,
17805
+ body: truncated ? text2.slice(0, maxBodyChars) : text2,
17655
17806
  truncated,
17656
17807
  ...note === void 0 ? {} : { note }
17657
17808
  };
@@ -17660,7 +17811,7 @@ var init_pay = __esm({
17660
17811
  async #channelFor(payee, receiver, withdrawDelay, price) {
17661
17812
  for (const r of await this.#channels.payRecords()) {
17662
17813
  if (r.pay === void 0 || r.closeRequested) continue;
17663
- if (getAddress17(r.payee) !== payee || getAddress17(r.config.receiver) !== receiver || r.gracePeriod !== withdrawDelay) continue;
17814
+ if (getAddress18(r.payee) !== payee || getAddress18(r.config.receiver) !== receiver || r.gracePeriod !== withdrawDelay) continue;
17664
17815
  if (r.pay.expiresAt < now2() + MIN_LIFE_LEFT_SECONDS || payCapacity(r) < price) continue;
17665
17816
  const ch = await readChannel(this.#client, this.#config.deployment.batchSettlement, r.channel);
17666
17817
  if (ch.pendingWithdrawal !== null || ch.balance < BigInt(r.pay.cumulative) + price) continue;
@@ -17671,10 +17822,10 @@ var init_pay = __esm({
17671
17822
  /** The stock x402 client paying from channel record `r` (the vault as payer, the channel's voucher key signing, never depositing). */
17672
17823
  #x402(r) {
17673
17824
  const voucherKey = this.#channels.voucherSigner(r);
17674
- if (voucherKey.address !== getAddress17(r.config.payerAuthorizer)) throw new Error(`the voucher key of channel ${r.channel} is not derived from this machine's master seed`);
17825
+ if (voucherKey.address !== getAddress18(r.config.payerAuthorizer)) throw new Error(`the voucher key of channel ${r.channel} is not derived from this machine's master seed`);
17675
17826
  const client = this.#client;
17676
17827
  const payer = {
17677
- address: getAddress17(r.config.payer),
17828
+ address: getAddress18(r.config.payer),
17678
17829
  signTypedData: () => Promise.reject(new Error("a vault never signs typed data")),
17679
17830
  readContract: (args) => client.readContract(args)
17680
17831
  };
@@ -17719,7 +17870,7 @@ var init_pay = __esm({
17719
17870
  if (url.protocol !== "https:" && url.protocol !== "http:") throw new RangeError("pay sends http(s) requests only");
17720
17871
  const maxPrice = parseTokenAmount(input.maxPrice);
17721
17872
  const first = await this.#fetch(input);
17722
- if (first.status !== 402) return this.#answer(first, null, null);
17873
+ if (first.status !== 402) return this.#answer(first, null, null, void 0, input.maxBodyChars);
17723
17874
  let firstBody = null;
17724
17875
  try {
17725
17876
  firstBody = JSON.parse(await first.clone().text());
@@ -17743,13 +17894,13 @@ var init_pay = __esm({
17743
17894
  if (price > maxPrice) throw new Error(`${input.url} asks ${formatTokenAmount(price)}, more than maxPrice ${input.maxPrice}; nothing was paid`);
17744
17895
  const extra = offer.extra ?? {};
17745
17896
  if (typeof extra.receiverAuthorizer !== "string" || !isAddress10(extra.receiverAuthorizer, { strict: false })) throw new Error("the offer names no receiverAuthorizer; nothing was paid");
17746
- const payee = getAddress17(extra.receiverAuthorizer);
17897
+ const payee = getAddress18(extra.receiverAuthorizer);
17747
17898
  const withdrawDelay = extra.withdrawDelay;
17748
17899
  if (typeof withdrawDelay !== "number" || !Number.isInteger(withdrawDelay) || withdrawDelay < 900 || withdrawDelay > BATCH_MAX_WITHDRAW_DELAY_SECONDS) {
17749
17900
  throw new Error(`the offer's withdrawDelay ${String(withdrawDelay)} is not 900..${BATCH_MAX_WITHDRAW_DELAY_SECONDS} s; nothing was paid`);
17750
17901
  }
17751
17902
  if (!isAddress10(offer.payTo, { strict: false })) throw new Error("the offer's payTo is not an address; nothing was paid");
17752
- const receiver = getAddress17(offer.payTo);
17903
+ const receiver = getAddress18(offer.payTo);
17753
17904
  const payeeVault = await readVault(this.#client, this.#config.deployment, payee);
17754
17905
  if (payeeVault === null || payeeVault.token !== token) throw new Error(`the seller's receiverAuthorizer ${payee} is not an Ostra vault in ${token}: this agent pays Ostra sellers from its vault; nothing was paid`);
17755
17906
  if (payee === await this.#vault.vaultAddress()) throw new Error("the seller is this agent's own vault");
@@ -17805,12 +17956,12 @@ var init_pay = __esm({
17805
17956
  break;
17806
17957
  }
17807
17958
  if (answer.status === 402) {
17808
- return this.#answer(answer, null, r, "the seller did not take the voucher; what the voucher signed stays recorded against the channel");
17959
+ return this.#answer(answer, null, r, "the seller did not take the voucher; what the voucher signed stays recorded against the channel", input.maxBodyChars);
17809
17960
  }
17810
17961
  const done = await this.#channels.updatePayRecord(r.salt, (rec) => {
17811
17962
  rec.pay.payments.push({ url: input.url, amount: paid.toString(), transaction: answer.headers.get("payment-response") ?? "", at: now2() });
17812
17963
  });
17813
- return this.#answer(answer, paid, done, opened ? `a channel to the seller was opened with a deposit of ${formatTokenAmount(BigInt(done.deposit))}; later payments to the seller use it` : void 0);
17964
+ return this.#answer(answer, paid, done, opened ? `a channel to the seller was opened with a deposit of ${formatTokenAmount(BigInt(done.deposit))}; later payments to the seller use it` : void 0, input.maxBodyChars);
17814
17965
  });
17815
17966
  }
17816
17967
  };
@@ -20686,7 +20837,7 @@ var init_abi2 = __esm({
20686
20837
  });
20687
20838
 
20688
20839
  // ../../ostra-swap/sdk/src/constants.ts
20689
- var LOG_WINDOW_BLOCKS2, USDG2, WETH2, HUBS, ETH, UNISWAP_V3_FACTORY, UNISWAP_V3_QUOTER_V2, V3_FEE_TIERS, UNISWAP_V4_POOL_MANAGER2, UNISWAP_V4_QUOTER, MULTICALL32, OSTRA_HOOK, PONS_HOOK, ROUTABLE_HOOKS, FEE_TIERS, COMMAND, V4_ACTION, CONTRACT_BALANCE, MSG_SENDER, ADDRESS_THIS, OPEN_DELTA, QUOTE_GAS_LIMIT, QUOTES_PER_CALL, QUOTE_GAS_LIMIT_RETRY, QUOTES_PER_RETRY_CALL, QUOTE_BATCH_OVERHEAD_GAS, V3_MIN_SQRT_PRICE_LIMIT, V3_MAX_SQRT_PRICE_LIMIT, DEFAULT_SLIPPAGE_BPS, MAX_SLIPPAGE_BPS, DEFAULT_ORDER_TTL_SECONDS;
20840
+ var LOG_WINDOW_BLOCKS2, USDG2, WETH2, HUBS, ETH, UNISWAP_V3_FACTORY, UNISWAP_V3_QUOTER_V2, V3_FEE_TIERS, UNISWAP_V4_POOL_MANAGER2, UNISWAP_V4_QUOTER, MULTICALL32, OSTRA_HOOK, PONS_HOOK2, ROUTABLE_HOOKS, FEE_TIERS, COMMAND, V4_ACTION, CONTRACT_BALANCE, MSG_SENDER, ADDRESS_THIS, OPEN_DELTA, QUOTE_GAS_LIMIT, QUOTES_PER_CALL, QUOTE_GAS_LIMIT_RETRY, QUOTES_PER_RETRY_CALL, QUOTE_BATCH_OVERHEAD_GAS, V3_MIN_SQRT_PRICE_LIMIT, V3_MAX_SQRT_PRICE_LIMIT, DEFAULT_SLIPPAGE_BPS, MAX_SLIPPAGE_BPS, DEFAULT_ORDER_TTL_SECONDS;
20690
20841
  var init_constants2 = __esm({
20691
20842
  "../../ostra-swap/sdk/src/constants.ts"() {
20692
20843
  "use strict";
@@ -20703,8 +20854,8 @@ var init_constants2 = __esm({
20703
20854
  UNISWAP_V4_QUOTER = "0x8Dc178eFB8111BB0973Dd9d722ebeFF267c98F94";
20704
20855
  MULTICALL32 = "0xcA11bde05977b3631167028862bE2a173976CA11";
20705
20856
  OSTRA_HOOK = "0x63A784afb8905452aDceC471a45E555F5caE68cC";
20706
- PONS_HOOK = "0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044";
20707
- ROUTABLE_HOOKS = ["0x0000000000000000000000000000000000000000", OSTRA_HOOK, PONS_HOOK];
20857
+ PONS_HOOK2 = "0xE5e702641Ea86F4ae6cC3cDaeD2B886f976Be044";
20858
+ ROUTABLE_HOOKS = ["0x0000000000000000000000000000000000000000", OSTRA_HOOK, PONS_HOOK2];
20708
20859
  FEE_TIERS = [
20709
20860
  { minLocked: 500000n * 10n ** 18n, bps: 0 },
20710
20861
  { minLocked: 250000n * 10n ** 18n, bps: 10 },
@@ -20827,13 +20978,13 @@ var init_uniswap = __esm({
20827
20978
  });
20828
20979
 
20829
20980
  // ../../ostra-swap/sdk/src/legs.ts
20830
- import { concatHex, encodeAbiParameters as encodeAbiParameters6, encodePacked as encodePacked4, getAddress as getAddress18, toHex as toHex2 } from "viem";
20981
+ import { concatHex, encodeAbiParameters as encodeAbiParameters7, encodePacked as encodePacked4, getAddress as getAddress19, toHex as toHex3 } from "viem";
20831
20982
  function legFor(pool, tokenIn, tokenOut, recipient = MSG_SENDER) {
20832
- const inAddr = getAddress18(tokenIn);
20833
- const outAddr = getAddress18(tokenOut);
20983
+ const inAddr = getAddress19(tokenIn);
20984
+ const outAddr = getAddress19(tokenOut);
20834
20985
  if (pool.kind === "v3") {
20835
20986
  const path = encodePacked4(["address", "uint24", "address"], [inAddr, pool.fee, outAddr]);
20836
- const input = encodeAbiParameters6(
20987
+ const input = encodeAbiParameters7(
20837
20988
  [{ type: "address" }, { type: "uint256" }, { type: "uint256" }, { type: "bytes" }, { type: "bool" }, { type: "uint256[]" }],
20838
20989
  [recipient, CONTRACT_BALANCE, 0n, path, false, []]
20839
20990
  );
@@ -20843,20 +20994,20 @@ function legFor(pool, tokenIn, tokenOut, recipient = MSG_SENDER) {
20843
20994
  const asCurrency = (t) => t === WETH2 && (k.currency0 === ETH || k.currency1 === ETH) ? ETH : t;
20844
20995
  const currencyIn = asCurrency(inAddr);
20845
20996
  const currencyOut = asCurrency(outAddr);
20846
- const zeroForOne = currencyIn === getAddress18(k.currency0);
20847
- if (!zeroForOne && currencyIn !== getAddress18(k.currency1)) throw new Error(`${tokenIn} is not in the pool ${pool.id}`);
20848
- if (currencyOut !== getAddress18(zeroForOne ? k.currency1 : k.currency0)) throw new Error(`${tokenOut} is not the other side of the pool ${pool.id}`);
20849
- const settle = encodeAbiParameters6([{ type: "address" }, { type: "uint256" }, { type: "bool" }], [currencyIn, CONTRACT_BALANCE, false]);
20850
- const swap = encodeAbiParameters6(
20997
+ const zeroForOne = currencyIn === getAddress19(k.currency0);
20998
+ if (!zeroForOne && currencyIn !== getAddress19(k.currency1)) throw new Error(`${tokenIn} is not in the pool ${pool.id}`);
20999
+ if (currencyOut !== getAddress19(zeroForOne ? k.currency1 : k.currency0)) throw new Error(`${tokenOut} is not the other side of the pool ${pool.id}`);
21000
+ const settle = encodeAbiParameters7([{ type: "address" }, { type: "uint256" }, { type: "bool" }], [currencyIn, CONTRACT_BALANCE, false]);
21001
+ const swap = encodeAbiParameters7(
20851
21002
  [exactInputSingleParam],
20852
21003
  [{ poolKey: k, zeroForOne, amountIn: OPEN_DELTA, amountOutMinimum: 0n, minHopPriceX36: 0n, hookData: "0x" }]
20853
21004
  );
20854
21005
  if (recipient === ADDRESS_THIS && currencyOut === ETH) throw new Error("a leg kept in the Universal Router pays an ERC-20, not native ETH");
20855
- const take = encodeAbiParameters6([{ type: "address" }, { type: "address" }, { type: "uint256" }], [currencyOut, recipient, OPEN_DELTA]);
21006
+ const take = encodeAbiParameters7([{ type: "address" }, { type: "address" }, { type: "uint256" }], [currencyOut, recipient, OPEN_DELTA]);
20856
21007
  const actions = concatHex([byte(V4_ACTION.SETTLE), byte(V4_ACTION.SWAP_EXACT_IN_SINGLE), byte(V4_ACTION.TAKE)]);
20857
- const v4Input = encodeAbiParameters6([{ type: "bytes" }, { type: "bytes[]" }], [actions, [settle, swap, take]]);
21008
+ const v4Input = encodeAbiParameters7([{ type: "bytes" }, { type: "bytes[]" }], [actions, [settle, swap, take]]);
20858
21009
  if (currencyIn === ETH) {
20859
- const unwrap = encodeAbiParameters6([{ type: "address" }, { type: "uint256" }], [ADDRESS_THIS, 0n]);
21010
+ const unwrap = encodeAbiParameters7([{ type: "address" }, { type: "uint256" }], [ADDRESS_THIS, 0n]);
20860
21011
  return { commands: concatHex([byte(COMMAND.UNWRAP_WETH), byte(COMMAND.V4_SWAP)]), inputs: [unwrap, v4Input] };
20861
21012
  }
20862
21013
  return { commands: byte(COMMAND.V4_SWAP), inputs: [v4Input] };
@@ -20869,15 +21020,15 @@ var init_legs = __esm({
20869
21020
  init_constants2();
20870
21021
  init_uniswap();
20871
21022
  NO_LEG = { commands: "0x", inputs: [] };
20872
- byte = (n) => toHex2(n, { size: 1 });
21023
+ byte = (n) => toHex3(n, { size: 1 });
20873
21024
  }
20874
21025
  });
20875
21026
 
20876
21027
  // ../../ostra-swap/sdk/src/pools.ts
20877
- import { encodeAbiParameters as encodeAbiParameters7, encodeFunctionData as encodeFunctionData9, decodeFunctionResult as decodeFunctionResult2, getAddress as getAddress19, hexToBigInt, keccak256 as keccak25611, toHex as toHex3, zeroAddress as zeroAddress11 } from "viem";
21028
+ import { encodeAbiParameters as encodeAbiParameters8, encodeFunctionData as encodeFunctionData9, decodeFunctionResult as decodeFunctionResult2, getAddress as getAddress20, hexToBigInt as hexToBigInt2, keccak256 as keccak25612, toHex as toHex4, zeroAddress as zeroAddress11 } from "viem";
20878
21029
  function stateSlot(id, offset) {
20879
- const base = hexToBigInt(keccak25611(encodeAbiParameters7([{ type: "bytes32" }, { type: "uint256" }], [id, POOLS_SLOT2])));
20880
- return toHex3(base + offset, { size: 32 });
21030
+ const base = hexToBigInt2(keccak25612(encodeAbiParameters8([{ type: "bytes32" }, { type: "uint256" }], [id, POOLS_SLOT3])));
21031
+ return toHex4(base + offset, { size: 32 });
20881
21032
  }
20882
21033
  async function initializeLogs(logsClient, c0, c1, from, to) {
20883
21034
  try {
@@ -20889,7 +21040,7 @@ async function initializeLogs(logsClient, c0, c1, from, to) {
20889
21040
  }
20890
21041
  }
20891
21042
  function hubCurrencies(hub) {
20892
- return getAddress19(hub) === WETH2 ? [WETH2, ETH] : [getAddress19(hub)];
21043
+ return getAddress20(hub) === WETH2 ? [WETH2, ETH] : [getAddress20(hub)];
20893
21044
  }
20894
21045
  async function aggregate(client, calls) {
20895
21046
  if (calls.length === 0) return [];
@@ -20899,8 +21050,8 @@ async function aggregate(client, calls) {
20899
21050
  return decodeFunctionResult2({ abi: multicall3Abi2, functionName: "aggregate3", data: ret });
20900
21051
  }
20901
21052
  async function hubPools(client, logsClient, index, token, hub) {
20902
- const t = getAddress19(token);
20903
- const h = getAddress19(hub);
21053
+ const t = getAddress20(token);
21054
+ const h = getAddress20(hub);
20904
21055
  if (t === h) return [];
20905
21056
  const out = [];
20906
21057
  const found = await aggregate(
@@ -20911,7 +21062,7 @@ async function hubPools(client, logsClient, index, token, hub) {
20911
21062
  found.forEach((r, i) => {
20912
21063
  if (!r.success) return;
20913
21064
  const address6 = decodeFunctionResult2({ abi: v3FactoryAbi, functionName: "getPool", data: r.returnData });
20914
- if (address6 !== zeroAddress11) v3.push({ address: getAddress19(address6), fee: V3_FEE_TIERS[i] });
21065
+ if (address6 !== zeroAddress11) v3.push({ address: getAddress20(address6), fee: V3_FEE_TIERS[i] });
20915
21066
  });
20916
21067
  const v3Liquidity = await aggregate(client, v3.map((p) => ({ target: p.address, callData: encodeFunctionData9({ abi: v3PoolAbi, functionName: "liquidity" }) })));
20917
21068
  v3.forEach((p, i) => {
@@ -20922,27 +21073,27 @@ async function hubPools(client, logsClient, index, token, hub) {
20922
21073
  });
20923
21074
  const records = [];
20924
21075
  for (const side of hubCurrencies(h)) {
20925
- for (const p of await index.v4PoolsOfPair(logsClient, t, side)) if (ROUTABLE_HOOKS.includes(getAddress19(p.key.hooks))) records.push(p);
21076
+ for (const p of await index.v4PoolsOfPair(logsClient, t, side)) if (ROUTABLE_HOOKS.includes(getAddress20(p.key.hooks))) records.push(p);
20926
21077
  }
20927
21078
  if (records.length > 0) {
20928
- const slots = records.map((p) => stateSlot(p.id, LIQUIDITY_OFFSET));
21079
+ const slots = records.map((p) => stateSlot(p.id, LIQUIDITY_OFFSET2));
20929
21080
  const values = await client.readContract({ address: UNISWAP_V4_POOL_MANAGER2, abi: poolManagerAbi, functionName: "extsload", args: [slots] });
20930
21081
  records.forEach((p, i) => {
20931
21082
  const v = values[i];
20932
- if (v !== void 0 && hexToBigInt(v) % (1n << 128n) > 0n) out.push({ kind: "v4", id: p.id, key: p.key });
21083
+ if (v !== void 0 && hexToBigInt2(v) % (1n << 128n) > 0n) out.push({ kind: "v4", id: p.id, key: p.key });
20933
21084
  });
20934
21085
  }
20935
21086
  return out;
20936
21087
  }
20937
- var POOLS_SLOT2, LIQUIDITY_OFFSET, PoolIndex;
21088
+ var POOLS_SLOT3, LIQUIDITY_OFFSET2, PoolIndex;
20938
21089
  var init_pools2 = __esm({
20939
21090
  "../../ostra-swap/sdk/src/pools.ts"() {
20940
21091
  "use strict";
20941
21092
  init_define_OSTRA_PACKAGED();
20942
21093
  init_constants2();
20943
21094
  init_uniswap();
20944
- POOLS_SLOT2 = 6n;
20945
- LIQUIDITY_OFFSET = 3n;
21095
+ POOLS_SLOT3 = 6n;
21096
+ LIQUIDITY_OFFSET2 = 3n;
20946
21097
  PoolIndex = class {
20947
21098
  #data;
20948
21099
  constructor(data) {
@@ -20958,7 +21109,7 @@ var init_pools2 = __esm({
20958
21109
  * that serves LOG_WINDOW_BLOCKS per request).
20959
21110
  */
20960
21111
  async v4PoolsOfPair(logsClient, a, b) {
20961
- const [c0, c1] = BigInt(getAddress19(a)) < BigInt(getAddress19(b)) ? [getAddress19(a), getAddress19(b)] : [getAddress19(b), getAddress19(a)];
21112
+ const [c0, c1] = BigInt(getAddress20(a)) < BigInt(getAddress20(b)) ? [getAddress20(a), getAddress20(b)] : [getAddress20(b), getAddress20(a)];
20962
21113
  const pairKey = `${c0}-${c1}`;
20963
21114
  const entry = this.#data.tokens[pairKey] ?? { searchedTo: "-1", pools: [] };
20964
21115
  const head = await logsClient.getBlockNumber();
@@ -20970,7 +21121,7 @@ var init_pools2 = __esm({
20970
21121
  const x = l.args;
20971
21122
  if (x.id === void 0 || x.fee === void 0 || x.tickSpacing === void 0 || x.hooks === void 0 || seen.has(x.id)) continue;
20972
21123
  seen.add(x.id);
20973
- entry.pools.push({ id: x.id, key: { currency0: c0, currency1: c1, fee: x.fee, tickSpacing: x.tickSpacing, hooks: getAddress19(x.hooks) } });
21124
+ entry.pools.push({ id: x.id, key: { currency0: c0, currency1: c1, fee: x.fee, tickSpacing: x.tickSpacing, hooks: getAddress20(x.hooks) } });
20974
21125
  }
20975
21126
  entry.searchedTo = to.toString();
20976
21127
  from = to + 1n;
@@ -20983,9 +21134,9 @@ var init_pools2 = __esm({
20983
21134
  });
20984
21135
 
20985
21136
  // ../../ostra-swap/sdk/src/route.ts
20986
- import { decodeAbiParameters as decodeAbiParameters3, decodeFunctionResult as decodeFunctionResult3, encodeDeployData as encodeDeployData2, encodeFunctionData as encodeFunctionData10, getAddress as getAddress20 } from "viem";
21137
+ import { decodeAbiParameters as decodeAbiParameters3, decodeFunctionResult as decodeFunctionResult3, encodeDeployData as encodeDeployData2, encodeFunctionData as encodeFunctionData10, getAddress as getAddress21 } from "viem";
20987
21138
  function routedToken(token) {
20988
- const t = getAddress20(token);
21139
+ const t = getAddress21(token);
20989
21140
  return t === ETH ? WETH2 : t;
20990
21141
  }
20991
21142
  function quoteCall(pool, tokenIn, tokenOut, amountIn) {
@@ -21083,8 +21234,8 @@ async function findRoute(r) {
21083
21234
  }
21084
21235
  if (best === null || expectedOut > best.expectedOut) {
21085
21236
  best = {
21086
- tokenIn: getAddress20(r.tokenIn),
21087
- tokenOut: getAddress20(r.tokenOut),
21237
+ tokenIn: getAddress21(r.tokenIn),
21238
+ tokenOut: getAddress21(r.tokenOut),
21088
21239
  amountIn: r.amountIn,
21089
21240
  hub,
21090
21241
  legIn,
@@ -21133,7 +21284,7 @@ var init_route = __esm({
21133
21284
  });
21134
21285
 
21135
21286
  // ../../ostra-swap/sdk/src/orders.ts
21136
- import { encodeAbiParameters as encodeAbiParameters8, encodeFunctionData as encodeFunctionData11, getAddress as getAddress21, getContractAddress as getContractAddress3, isAddress as isAddress11, keccak256 as keccak25612, toHex as toHex4 } from "viem";
21287
+ import { encodeAbiParameters as encodeAbiParameters9, encodeFunctionData as encodeFunctionData11, getAddress as getAddress22, getContractAddress as getContractAddress3, isAddress as isAddress11, keccak256 as keccak25613, toHex as toHex5 } from "viem";
21137
21288
  function parseSwapDeployment(json) {
21138
21289
  const r = json;
21139
21290
  if (r === null || typeof r !== "object") throw new Error("the deployment record is not a JSON object");
@@ -21142,22 +21293,22 @@ function parseSwapDeployment(json) {
21142
21293
  const addr2 = (name) => {
21143
21294
  const v = r[name];
21144
21295
  if (typeof v !== "string" || !isAddress11(v, { strict: false })) throw new Error(`the deployment record has no ${name} address`);
21145
- return getAddress21(v);
21296
+ return getAddress22(v);
21146
21297
  };
21147
21298
  return { chainId: r.chainId, fromBlock: r.fromBlock, router: addr2("router"), stake: addr2("stake"), buyback: addr2("buyback"), spendVerifier: addr2("spendVerifier"), privatePool: addr2("privatePool") };
21148
21299
  }
21149
21300
  function routeHash(hub, legIn, legOut) {
21150
- return keccak25612(encodeAbiParameters8([{ type: "address" }, legParam, legParam], [getAddress21(hub), legIn, legOut]));
21301
+ return keccak25613(encodeAbiParameters9([{ type: "address" }, legParam, legParam], [getAddress22(hub), legIn, legOut]));
21151
21302
  }
21152
21303
  function orderHash(order) {
21153
- return keccak25612(encodeAbiParameters8([orderParam], [order]));
21304
+ return keccak25613(encodeAbiParameters9([orderParam], [order]));
21154
21305
  }
21155
21306
  function escrowAddress(router, order) {
21156
- return getContractAddress3({ opcode: "CREATE2", from: getAddress21(router), salt: orderHash(order), bytecode: OSTRA_SWAP_ESCROW_CREATION_CODE });
21307
+ return getContractAddress3({ opcode: "CREATE2", from: getAddress22(router), salt: orderHash(order), bytecode: OSTRA_SWAP_ESCROW_CREATION_CODE });
21157
21308
  }
21158
21309
  function orderFor(route, vault, vaultToken, recipient, now3, salt, ttlSeconds = DEFAULT_ORDER_TTL_SECONDS) {
21159
21310
  if (route.tokenIn === ETH || route.tokenOut === ETH) throw new Error("a vault swaps ERC-20 tokens: WETH, not native ETH");
21160
- if (getAddress21(vaultToken) !== getAddress21(route.tokenIn)) throw new Error(`the vault holds ${vaultToken}, not the route's tokenIn ${route.tokenIn}`);
21311
+ if (getAddress22(vaultToken) !== getAddress22(route.tokenIn)) throw new Error(`the vault holds ${vaultToken}, not the route's tokenIn ${route.tokenIn}`);
21161
21312
  if (!/^0x[0-9a-fA-F]{64}$/.test(salt)) throw new Error("the salt is 32 bytes");
21162
21313
  const { legIn, legOut } = routeLegs(route);
21163
21314
  return {
@@ -21165,8 +21316,8 @@ function orderFor(route, vault, vaultToken, recipient, now3, salt, ttlSeconds =
21165
21316
  tokenOut: route.tokenOut,
21166
21317
  amountIn: route.amountIn,
21167
21318
  minOut: route.minOut,
21168
- recipient: getAddress21(recipient),
21169
- refundTo: getAddress21(vault),
21319
+ recipient: getAddress22(recipient),
21320
+ refundTo: getAddress22(vault),
21170
21321
  notBefore: 0n,
21171
21322
  deadline: now3 + BigInt(ttlSeconds),
21172
21323
  tranches: 0,
@@ -21178,7 +21329,7 @@ function orderFor(route, vault, vaultToken, recipient, now3, salt, ttlSeconds =
21178
21329
  };
21179
21330
  }
21180
21331
  function randomSalt2() {
21181
- return toHex4(crypto.getRandomValues(new Uint8Array(32)));
21332
+ return toHex5(crypto.getRandomValues(new Uint8Array(32)));
21182
21333
  }
21183
21334
  function executeEscrowData(order, route) {
21184
21335
  const { legIn, legOut } = routeLegs(route);
@@ -21226,7 +21377,7 @@ var init_orders = __esm({
21226
21377
  });
21227
21378
 
21228
21379
  // ../../ostra-swap/sdk/src/private.ts
21229
- import { encodeAbiParameters as encodeAbiParameters9, encodeFunctionData as encodeFunctionData12, getAbiItem, getAddress as getAddress22, getContractAddress as getContractAddress4, keccak256 as keccak25613, parseEventLogs, toHex as toHex5 } from "viem";
21380
+ import { encodeAbiParameters as encodeAbiParameters10, encodeFunctionData as encodeFunctionData12, getAbiItem, getAddress as getAddress23, getContractAddress as getContractAddress4, keccak256 as keccak25614, parseEventLogs, toHex as toHex6 } from "viem";
21230
21381
  function packDigest(elements) {
21231
21382
  if (elements.length !== 8) throw new Error("a digest has 8 field elements");
21232
21383
  let v = 0n;
@@ -21235,7 +21386,7 @@ function packDigest(elements) {
21235
21386
  if (x < 0n || x >= FIELD_P) throw new Error("a digest element is not below P");
21236
21387
  v |= x << BigInt(32 * i);
21237
21388
  });
21238
- return toHex5(v, { size: 32 });
21389
+ return toHex6(v, { size: 32 });
21239
21390
  }
21240
21391
  function unpackDigest(d) {
21241
21392
  if (!/^0x[0-9a-fA-F]{64}$/.test(d)) throw new Error("a digest is 32 bytes");
@@ -21252,7 +21403,7 @@ function digestOf(v, what) {
21252
21403
  }
21253
21404
  async function noteKeys(prover, sk, rho, asset, amount) {
21254
21405
  if (amount < 0n || amount >= MAX_AMOUNT) throw new Error("an amount is below 2^128");
21255
- const r = await prover("note", { sk: unpackDigest(sk), rho: unpackDigest(rho), asset: getAddress22(asset), amount: amount.toString() });
21406
+ const r = await prover("note", { sk: unpackDigest(sk), rho: unpackDigest(rho), asset: getAddress23(asset), amount: amount.toString() });
21256
21407
  return { tag: digestOf(r.tag, "tag"), commitment: digestOf(r.commitment, "commitment"), nullifier: digestOf(r.nullifier, "nullifier") };
21257
21408
  }
21258
21409
  async function tagOf(prover, sk, rho) {
@@ -21281,16 +21432,16 @@ async function notePath(prover, trees, note) {
21281
21432
  return { root, path: r.path };
21282
21433
  }
21283
21434
  function unshieldHash(chainId, pool, relayer, deadline, recipient) {
21284
- return keccak25613(
21285
- encodeAbiParameters9(
21435
+ return keccak25614(
21436
+ encodeAbiParameters10(
21286
21437
  [{ type: "bytes32" }, { type: "uint256" }, { type: "address" }, { type: "address" }, { type: "uint64" }, { type: "address" }],
21287
- [UNSHIELD_DOMAIN, BigInt(chainId), getAddress22(pool), getAddress22(relayer), deadline, getAddress22(recipient)]
21438
+ [UNSHIELD_DOMAIN, BigInt(chainId), getAddress23(pool), getAddress23(relayer), deadline, getAddress23(recipient)]
21288
21439
  )
21289
21440
  );
21290
21441
  }
21291
21442
  function swapHash(chainId, pool, relayer, deadline, t) {
21292
- return keccak25613(
21293
- encodeAbiParameters9(
21443
+ return keccak25614(
21444
+ encodeAbiParameters10(
21294
21445
  [
21295
21446
  { type: "bytes32" },
21296
21447
  { type: "uint256" },
@@ -21302,7 +21453,7 @@ function swapHash(chainId, pool, relayer, deadline, t) {
21302
21453
  { type: "bytes32" },
21303
21454
  { type: "bytes32" }
21304
21455
  ],
21305
- [SWAP_DOMAIN, BigInt(chainId), getAddress22(pool), getAddress22(relayer), deadline, getAddress22(t.tokenOut), t.minOut, t.outTag, routeHash(t.hub, t.legIn, t.legOut)]
21456
+ [SWAP_DOMAIN, BigInt(chainId), getAddress23(pool), getAddress23(relayer), deadline, getAddress23(t.tokenOut), t.minOut, t.outTag, routeHash(t.hub, t.legIn, t.legOut)]
21306
21457
  )
21307
21458
  );
21308
21459
  }
@@ -21312,7 +21463,7 @@ function publicValues(asset, v, fee, nullifier, root, changeCommitment, bindHash
21312
21463
  const words = (d) => unpackDigest(d).map((x) => BigInt(x));
21313
21464
  const h = BigInt(bindHash);
21314
21465
  return [
21315
- ...limbs(BigInt(getAddress22(asset)), 6, 27),
21466
+ ...limbs(BigInt(getAddress23(asset)), 6, 27),
21316
21467
  ...limbs(v, 5, 26),
21317
21468
  ...limbs(fee, 5, 26),
21318
21469
  ...words(nullifier),
@@ -21325,7 +21476,7 @@ async function prove(r, v, bindHash, recipient) {
21325
21476
  const n = r.note;
21326
21477
  if (r.changeRho !== void 0 && r.changeRho.toLowerCase() === n.rho.toLowerCase()) throw new Error("changeRho must be a fresh secret, not the note's rho");
21327
21478
  if (v < 0n || r.fee < 0n || v + r.fee > n.amount) throw new Error(`the note holds ${n.amount}, less than ${v} + ${r.fee}`);
21328
- if (r.fee !== 0n && getAddress22(r.relayer) === ZERO2) throw new Error("a fee needs a relayer");
21479
+ if (r.fee !== 0n && getAddress23(r.relayer) === ZERO2) throw new Error("a fee needs a relayer");
21329
21480
  if (r.deadline < 0n || r.deadline > MAX_UINT642) throw new Error("the deadline is uint64 unix seconds");
21330
21481
  const keys = await noteKeys(r.prover, r.sk, n.rho, n.asset, n.amount);
21331
21482
  if (keys.commitment.toLowerCase() !== n.commitment.toLowerCase()) throw new Error("the note is not this sk's (or its rho, token or amount is wrong)");
@@ -21333,7 +21484,7 @@ async function prove(r, v, bindHash, recipient) {
21333
21484
  const out = await r.prover("prove", {
21334
21485
  sk: unpackDigest(r.sk),
21335
21486
  rho: unpackDigest(n.rho),
21336
- asset: getAddress22(n.asset),
21487
+ asset: getAddress23(n.asset),
21337
21488
  amount: n.amount.toString(),
21338
21489
  index: n.index,
21339
21490
  path,
@@ -21346,7 +21497,7 @@ async function prove(r, v, bindHash, recipient) {
21346
21497
  if (typeof out.proof !== "string" || !/^0x[0-9a-f]*$/.test(out.proof) || !Array.isArray(out.public_values) || out.public_values.length !== 48) throw new Error("ostra-prove gave no proof");
21347
21498
  const pv = out.public_values.map((x) => BigInt(x));
21348
21499
  const changeCommitment = packDigest(pv.slice(32, 40));
21349
- const terms = { asset: getAddress22(n.asset), v, fee: r.fee, nullifier: keys.nullifier, root, changeCommitment, relayer: getAddress22(r.relayer), deadline: r.deadline };
21500
+ const terms = { asset: getAddress23(n.asset), v, fee: r.fee, nullifier: keys.nullifier, root, changeCommitment, relayer: getAddress23(r.relayer), deadline: r.deadline };
21350
21501
  const want = publicValues(terms.asset, v, r.fee, terms.nullifier, root, changeCommitment, bindHash);
21351
21502
  if (want.some((x, i) => x !== pv[i])) throw new Error("the proof's public values are not the spend's");
21352
21503
  const changeRho = digestOf(out.change_rho, "change_rho");
@@ -21356,40 +21507,40 @@ async function prove(r, v, bindHash, recipient) {
21356
21507
  return { terms, proof: out.proof, recipient, change: { rho: changeRho, amount: change, commitment: changeCommitment } };
21357
21508
  }
21358
21509
  async function proveUnshield(r) {
21359
- if (getAddress22(r.recipient) === ZERO2) throw new Error("an unshield needs a recipient");
21360
- return prove(r, r.v, unshieldHash(r.chainId, r.pool, r.relayer, r.deadline, r.recipient), getAddress22(r.recipient));
21510
+ if (getAddress23(r.recipient) === ZERO2) throw new Error("an unshield needs a recipient");
21511
+ return prove(r, r.v, unshieldHash(r.chainId, r.pool, r.relayer, r.deadline, r.recipient), getAddress23(r.recipient));
21361
21512
  }
21362
21513
  async function provePrivateSwap(r) {
21363
21514
  const route = r.route;
21364
21515
  if (route.feeBps !== PRIVATE_SWAP_FEE_BPS) throw new Error(`a private swap pays the base fee: find its route with feeBps ${PRIVATE_SWAP_FEE_BPS}`);
21365
21516
  if (route.tokenIn === ETH || route.tokenOut === ETH) throw new Error("notes hold ERC-20 tokens: WETH, not native ETH");
21366
- if (getAddress22(route.tokenIn) !== getAddress22(r.note.asset)) throw new Error(`the route swaps ${route.tokenIn}, the note holds ${r.note.asset}`);
21517
+ if (getAddress23(route.tokenIn) !== getAddress23(r.note.asset)) throw new Error(`the route swaps ${route.tokenIn}, the note holds ${r.note.asset}`);
21367
21518
  if (r.outRho.toLowerCase() === r.note.rho.toLowerCase()) throw new Error("outRho must be a fresh secret");
21368
21519
  const { legIn, legOut } = routeLegs(route);
21369
- const swap = { tokenOut: getAddress22(route.tokenOut), minOut: route.minOut, outTag: await tagOf(r.prover, r.sk, r.outRho), hub: getAddress22(route.hub), legIn, legOut };
21520
+ const swap = { tokenOut: getAddress23(route.tokenOut), minOut: route.minOut, outTag: await tagOf(r.prover, r.sk, r.outRho), hub: getAddress23(route.hub), legIn, legOut };
21370
21521
  if (r.changeRho !== void 0 && r.changeRho.toLowerCase() === r.outRho.toLowerCase()) throw new Error("the change and the output share a rho");
21371
21522
  const spend = await prove(r, route.amountIn, swapHash(r.chainId, r.pool, r.relayer, r.deadline, swap), null);
21372
21523
  if (spend.change.rho.toLowerCase() === r.outRho.toLowerCase()) throw new Error("the change and the output share a rho");
21373
21524
  return { spend, swap };
21374
21525
  }
21375
21526
  function shieldEscrowAddress(pool, token, tag) {
21376
- const salt = keccak25613(encodeAbiParameters9([{ type: "address" }, { type: "bytes32" }], [getAddress22(token), tag]));
21377
- return getContractAddress4({ opcode: "CREATE2", from: getAddress22(pool), salt, bytecode: OSTRA_SHIELD_ESCROW_CREATION_CODE });
21527
+ const salt = keccak25614(encodeAbiParameters10([{ type: "address" }, { type: "bytes32" }], [getAddress23(token), tag]));
21528
+ return getContractAddress4({ opcode: "CREATE2", from: getAddress23(pool), salt, bytecode: OSTRA_SHIELD_ESCROW_CREATION_CODE });
21378
21529
  }
21379
21530
  function shieldFromEscrowCall(pool, token, tag) {
21380
- return { to: getAddress22(pool), data: encodeFunctionData12({ abi: ostraPrivatePoolAbi, functionName: "shieldFromEscrow", args: [getAddress22(token), tag] }) };
21531
+ return { to: getAddress23(pool), data: encodeFunctionData12({ abi: ostraPrivatePoolAbi, functionName: "shieldFromEscrow", args: [getAddress23(token), tag] }) };
21381
21532
  }
21382
21533
  function unshieldCall(pool, spend, recipient) {
21383
- if (spend.recipient === null || spend.recipient !== getAddress22(recipient)) throw new Error("this spend was proved for another recipient (or is a swap)");
21384
- return { to: getAddress22(pool), data: encodeFunctionData12({ abi: ostraPrivatePoolAbi, functionName: "unshield", args: [spend.terms, getAddress22(recipient), spend.proof] }) };
21534
+ if (spend.recipient === null || spend.recipient !== getAddress23(recipient)) throw new Error("this spend was proved for another recipient (or is a swap)");
21535
+ return { to: getAddress23(pool), data: encodeFunctionData12({ abi: ostraPrivatePoolAbi, functionName: "unshield", args: [spend.terms, getAddress23(recipient), spend.proof] }) };
21385
21536
  }
21386
21537
  function privateSwapCall(pool, spend, swap) {
21387
21538
  if (spend.recipient !== null) throw new Error("this spend was proved for an unshield");
21388
- return { to: getAddress22(pool), data: encodeFunctionData12({ abi: ostraPrivatePoolAbi, functionName: "privateSwap", args: [spend.terms, swap, spend.proof] }) };
21539
+ return { to: getAddress23(pool), data: encodeFunctionData12({ abi: ostraPrivatePoolAbi, functionName: "privateSwap", args: [spend.terms, swap, spend.proof] }) };
21389
21540
  }
21390
21541
  function poolEvents(receipt, pool) {
21391
21542
  if (receipt.status !== "success") throw new Error("the transaction reverted");
21392
- return parseEventLogs({ abi: ostraPrivatePoolAbi, logs: receipt.logs.filter((l) => getAddress22(l.address) === getAddress22(pool)) });
21543
+ return parseEventLogs({ abi: ostraPrivatePoolAbi, logs: receipt.logs.filter((l) => getAddress23(l.address) === getAddress23(pool)) });
21393
21544
  }
21394
21545
  function placed(receipt, pool, commitment) {
21395
21546
  for (const e of poolEvents(receipt, pool)) {
@@ -21401,7 +21552,7 @@ async function shieldedNote(prover, sk, rho, receipt, pool) {
21401
21552
  const tag = (await tagOf(prover, sk, rho)).toLowerCase();
21402
21553
  for (const e of poolEvents(receipt, pool)) {
21403
21554
  if (e.eventName !== "Shielded" || e.args.tag.toLowerCase() !== tag) continue;
21404
- const asset = getAddress22(e.args.token);
21555
+ const asset = getAddress23(e.args.token);
21405
21556
  const keys = await noteKeys(prover, sk, rho, asset, e.args.amount);
21406
21557
  if (keys.commitment.toLowerCase() !== e.args.commitment.toLowerCase()) throw new Error("the shielded commitment is not this note's");
21407
21558
  return { asset, amount: e.args.amount, rho, commitment: e.args.commitment, ...placed(receipt, pool, e.args.commitment) };
@@ -21435,8 +21586,8 @@ var init_private = __esm({
21435
21586
  FIELD_P = 2130706433n;
21436
21587
  TREE_DEPTH = 20;
21437
21588
  PRIVATE_SWAP_FEE_BPS = 20;
21438
- UNSHIELD_DOMAIN = keccak25613(toHex5("OstraPrivatePool.unshield.v1"));
21439
- SWAP_DOMAIN = keccak25613(toHex5("OstraPrivatePool.privateSwap.v1"));
21589
+ UNSHIELD_DOMAIN = keccak25614(toHex6("OstraPrivatePool.unshield.v1"));
21590
+ SWAP_DOMAIN = keccak25614(toHex6("OstraPrivatePool.privateSwap.v1"));
21440
21591
  MAX_AMOUNT = 1n << 128n;
21441
21592
  MAX_UINT642 = (1n << 64n) - 1n;
21442
21593
  ZERO2 = "0x0000000000000000000000000000000000000000";
@@ -21449,9 +21600,9 @@ var init_private = __esm({
21449
21600
  constructor(pool, fromBlock, data) {
21450
21601
  if (data !== void 0) {
21451
21602
  if (data.version !== 1) throw new Error("unknown trees version");
21452
- if (getAddress22(data.pool) !== getAddress22(pool)) throw new Error("these trees are another pool's");
21603
+ if (getAddress23(data.pool) !== getAddress23(pool)) throw new Error("these trees are another pool's");
21453
21604
  }
21454
- this.#data = data ?? { version: 1, pool: getAddress22(pool), searchedTo: (fromBlock - 1n).toString(), trees: [] };
21605
+ this.#data = data ?? { version: 1, pool: getAddress23(pool), searchedTo: (fromBlock - 1n).toString(), trees: [] };
21455
21606
  }
21456
21607
  data() {
21457
21608
  return this.#data;
@@ -21542,7 +21693,7 @@ var init_private = __esm({
21542
21693
  });
21543
21694
 
21544
21695
  // ../../ostra-swap/sdk/src/reads.ts
21545
- import { getAddress as getAddress23 } from "viem";
21696
+ import { getAddress as getAddress24 } from "viem";
21546
21697
  var init_reads2 = __esm({
21547
21698
  "../../ostra-swap/sdk/src/reads.ts"() {
21548
21699
  "use strict";
@@ -21569,9 +21720,9 @@ var init_src2 = __esm({
21569
21720
  });
21570
21721
 
21571
21722
  // ../core/src/private-balance.ts
21572
- import { getAddress as getAddress24, parseAbiItem as parseAbiItem4 } from "viem";
21723
+ import { getAddress as getAddress25, parseAbiItem as parseAbiItem4 } from "viem";
21573
21724
  function privateTokens(config) {
21574
- return [config.deployment.token, WETH, ...LAUNCH_PAIRS.filter((p) => p.kind === "ostra" || p.kind === "stock").map((p) => getAddress24(p.address))];
21725
+ return [config.deployment.token, WETH, ...LAUNCH_PAIRS.filter((p) => p.kind === "ostra" || p.kind === "stock").map((p) => getAddress25(p.address))];
21575
21726
  }
21576
21727
  var PRIVATE_SWAP_DIR, PRIVATE_SHIELD_GAS, PRIVATE_SPEND_DEADLINE_SECONDS, MAX_SLIPPAGE_BPS2, PRIVATE_FEE_GAS, PRIVATE_FEE_MAX_FACTOR, SHIELD_SCAN_GAP, LOGS_CATCH_UP_TRIES, SHIELD_LOG_WAIT_MS, NOTES, TREES, NEXT_RHO, POOL_INDEX, PENDING_PREFIX, shieldedEvent, swappedEvent, unshieldedEvent, address3, PrivateBalanceService;
21577
21728
  var init_private_balance = __esm({
@@ -21605,7 +21756,7 @@ var init_private_balance = __esm({
21605
21756
  unshieldedEvent = parseAbiItem4("event Unshielded(bytes32 indexed nullifier, address indexed recipient, address indexed token, uint256 amount, uint256 fee, address relayer)");
21606
21757
  address3 = (text2, what) => {
21607
21758
  if (!/^0x[0-9a-fA-F]{40}$/.test(text2)) throw new RangeError(`${what} is not an address`);
21608
- return getAddress24(text2);
21759
+ return getAddress25(text2);
21609
21760
  };
21610
21761
  PrivateBalanceService = class {
21611
21762
  #p;
@@ -21615,7 +21766,7 @@ var init_private_balance = __esm({
21615
21766
  #tail = Promise.resolve();
21616
21767
  constructor(p) {
21617
21768
  this.#p = p;
21618
- this.#pool = getAddress24(p.swap.privatePool);
21769
+ this.#pool = getAddress25(p.swap.privatePool);
21619
21770
  }
21620
21771
  get pool() {
21621
21772
  return this.#pool;
@@ -21680,13 +21831,13 @@ var init_private_balance = __esm({
21680
21831
  for (const l of await this.#poolLogs(from, to)) {
21681
21832
  if (l.eventName === "Shielded") {
21682
21833
  const tag = l.args.tag.toLowerCase();
21683
- shielded.set(tag, [...shielded.get(tag) ?? [], { token: getAddress24(l.args.token), amount: l.args.amount, commitment: l.args.commitment }]);
21834
+ shielded.set(tag, [...shielded.get(tag) ?? [], { token: getAddress25(l.args.token), amount: l.args.amount, commitment: l.args.commitment }]);
21684
21835
  notes += 1;
21685
21836
  } else if (l.eventName === "Unshielded") {
21686
21837
  spends.set(l.args.nullifier.toLowerCase(), { kind: "unshield", v: l.args.amount, fee: l.args.fee });
21687
21838
  notes += 1;
21688
21839
  } else {
21689
- spends.set(l.args.nullifier.toLowerCase(), { kind: "swap", v: l.args.amountIn, fee: l.args.fee, tokenOut: getAddress24(l.args.tokenOut), amountOut: l.args.amountOut, outCommitment: l.args.outCommitment });
21840
+ spends.set(l.args.nullifier.toLowerCase(), { kind: "swap", v: l.args.amountIn, fee: l.args.fee, tokenOut: getAddress25(l.args.tokenOut), amountOut: l.args.amountOut, outCommitment: l.args.outCommitment });
21690
21841
  notes += 2;
21691
21842
  }
21692
21843
  }
@@ -21784,7 +21935,7 @@ var init_private_balance = __esm({
21784
21935
  const found = new Set(unspent.map((n) => n.commitment.toLowerCase()));
21785
21936
  const local = [];
21786
21937
  for (const n of await this.#notes()) {
21787
- if (found.has(n.commitment.toLowerCase()) || !tokens.has(getAddress24(n.asset)) || trees.find(n.commitment) === null) continue;
21938
+ if (found.has(n.commitment.toLowerCase()) || !tokens.has(getAddress25(n.asset)) || trees.find(n.commitment) === null) continue;
21788
21939
  const keys = await noteKeys(prover, sk, n.rho, n.asset, BigInt(n.amount));
21789
21940
  if (keys.commitment.toLowerCase() === n.commitment.toLowerCase() && !events.spends.has(keys.nullifier.toLowerCase())) local.push(n);
21790
21941
  }
@@ -21942,7 +22093,7 @@ var init_private_balance = __esm({
21942
22093
  const body = await this.#http("GET", `${url}/v1/private/price?token=${token}&kind=${kind}`);
21943
22094
  const b = body;
21944
22095
  if (typeof b.fee !== "string" || !/^[0-9]+$/.test(b.fee) || typeof b.relayer !== "string") throw new Error("the relayer's private price has no fee or relayer");
21945
- return { fee: BigInt(b.fee), relayer: getAddress24(b.relayer) };
22096
+ return { fee: BigInt(b.fee), relayer: getAddress25(b.relayer) };
21946
22097
  }
21947
22098
  async #http(method, url, body) {
21948
22099
  let res;
@@ -22195,7 +22346,7 @@ var init_seed_backup = __esm({
22195
22346
  });
22196
22347
 
22197
22348
  // ../core/src/sessions.ts
22198
- import { bytesToHex as bytesToHex12, getAddress as getAddress25, isAddress as isAddress12 } from "viem";
22349
+ import { bytesToHex as bytesToHex12, getAddress as getAddress26, isAddress as isAddress12 } from "viem";
22199
22350
  import { privateKeyToAccount as privateKeyToAccount3 } from "viem/accounts";
22200
22351
  var init_sessions = __esm({
22201
22352
  "../core/src/sessions.ts"() {
@@ -22207,19 +22358,19 @@ var init_sessions = __esm({
22207
22358
  });
22208
22359
 
22209
22360
  // ../core/src/shield.ts
22210
- import { bytesToHex as bytesToHex13, encodeFunctionData as encodeFunctionData13, getAddress as getAddress26, hexToBytes as hexToBytes8, parseSignature } from "viem";
22361
+ import { bytesToHex as bytesToHex13, encodeFunctionData as encodeFunctionData13, getAddress as getAddress27, hexToBytes as hexToBytes8, parseSignature } from "viem";
22211
22362
  function leafKeyIndex(attempt, j) {
22212
22363
  if (!Number.isInteger(attempt) || attempt < 0 || attempt >= MAX_LEAF_ATTEMPTS) throw new RangeError(`leaf set ${String(attempt)} is out of range`);
22213
22364
  if (!Number.isInteger(j) || j < 0 || j >= LEAF_KEYS_PER_ATTEMPT) throw new RangeError(`leaf ${String(j)} is out of range`);
22214
22365
  return attempt * LEAF_KEYS_PER_ATTEMPT + j;
22215
22366
  }
22216
22367
  function recordName(chainId, token, index) {
22217
- return `${chainId}-${getAddress26(token)}-${index}.json`;
22368
+ return `${chainId}-${getAddress27(token)}-${index}.json`;
22218
22369
  }
22219
22370
  function decodeApproveMessage(message) {
22220
22371
  if (message.length !== APPROVE_MESSAGE_LEN) throw new Error("not an approval message");
22221
22372
  const chainId = Number(BigInt(bytesToHex13(message.subarray(20, 52))));
22222
- const pool = getAddress26(bytesToHex13(message.subarray(52, 72)));
22373
+ const pool = getAddress27(bytesToHex13(message.subarray(52, 72)));
22223
22374
  const key = bytesToHex13(message.subarray(72, 104));
22224
22375
  const batchId = BigInt(bytesToHex13(message.subarray(104, 112)));
22225
22376
  const state = bytesToHex13(message.subarray(112, 144));
@@ -22294,7 +22445,7 @@ var init_shield = __esm({
22294
22445
  /** True when `record` belongs to this service's vault. */
22295
22446
  async #mine(record) {
22296
22447
  if (record.vault === void 0) return this.#vault.kind === "buyer";
22297
- return getAddress26(record.vault) === await this.#vault.vaultAddress();
22448
+ return getAddress27(record.vault) === await this.#vault.vaultAddress();
22298
22449
  }
22299
22450
  /** A new record under the first free deposit number (created exclusively: another vault's service may be creating one too). */
22300
22451
  async #createRecord(make) {
@@ -22455,8 +22606,8 @@ var init_shield = __esm({
22455
22606
  const { batchCount } = await readPool(this.#client, this.#pool());
22456
22607
  const health = await this.#aggregator("GET", "/v1/health");
22457
22608
  if (typeof health.aggregator !== "string") throw new Error("the aggregator's health names no aggregator account");
22458
- const aggregator = getAddress26(health.aggregator);
22459
- const accounts = /* @__PURE__ */ new Set([...(record.aggregators ?? []).map((a) => getAddress26(a)), aggregator]);
22609
+ const aggregator = getAddress27(health.aggregator);
22610
+ const accounts = /* @__PURE__ */ new Set([...(record.aggregators ?? []).map((a) => getAddress27(a)), aggregator]);
22460
22611
  if (accounts.size !== (record.aggregators ?? []).length) {
22461
22612
  record.aggregators = [...accounts];
22462
22613
  await this.#save(record);
@@ -22511,11 +22662,11 @@ var init_shield = __esm({
22511
22662
  const room = await this.#room(p.maxTotal);
22512
22663
  if (amount > room) throw new RangeError(`the pool has room for ${formatTokenAmount(room)} more, and a deposit of ${leaves} leaves is ${formatTokenAmount(amount)}; nothing was signed`);
22513
22664
  const terms = await this.#aggregator("GET", "/v1/terms");
22514
- if (terms.chainId !== this.#config.chainId || typeof terms.pool !== "string" || getAddress26(terms.pool) !== pool || typeof terms.token !== "string" || getAddress26(terms.token) !== this.#token()) {
22665
+ if (terms.chainId !== this.#config.chainId || typeof terms.pool !== "string" || getAddress27(terms.pool) !== pool || typeof terms.token !== "string" || getAddress27(terms.token) !== this.#token()) {
22515
22666
  throw new Error(`the aggregator serves pool ${String(terms.pool)} on chain ${String(terms.chainId)}, not ${pool} on ${this.#config.chainId}`);
22516
22667
  }
22517
22668
  if (typeof terms.aggregator !== "string") throw new Error("the aggregator's terms name no aggregator account");
22518
- const aggregatorAccount = getAddress26(terms.aggregator);
22669
+ const aggregatorAccount = getAddress27(terms.aggregator);
22519
22670
  const status = await this.#vault.status();
22520
22671
  if (!status.vaultExists) throw new Error("open the vault and fund it first (open_vault)");
22521
22672
  const vault = await this.#vault.vaultAddress();
@@ -22772,7 +22923,7 @@ var init_shield = __esm({
22772
22923
  leavesInPool.push({ batch: r.batch, leafIndex: i, key: leafKeyIndex(r.attempt ?? 0, j), amount: formatTokenAmount(LEAF_DENOMINATION), spent: b.status === "none" || leaf === void 0 || leaf.spent });
22773
22924
  });
22774
22925
  }
22775
- out.push({ index: r.index, vault: r.vault === void 0 ? null : getAddress26(r.vault), deposit: r.deposit, leaves: r.leaves, amount: formatTokenAmount(BigInt(r.amount)), status: r.status, batch: r.batch, leavesInPool });
22926
+ out.push({ index: r.index, vault: r.vault === void 0 ? null : getAddress27(r.vault), deposit: r.deposit, leaves: r.leaves, amount: formatTokenAmount(BigInt(r.amount)), status: r.status, batch: r.batch, leavesInPool });
22776
22927
  }
22777
22928
  return out;
22778
22929
  });
@@ -22790,7 +22941,7 @@ var init_storage = __esm({
22790
22941
  });
22791
22942
 
22792
22943
  // ../core/src/swap.ts
22793
- import { decodeEventLog as decodeEventLog4, getAddress as getAddress27 } from "viem";
22944
+ import { decodeEventLog as decodeEventLog4, getAddress as getAddress28 } from "viem";
22794
22945
  var SWAP_DIR, ESCROW_SWAP_GAS, DEFAULT_SWAP_SLIPPAGE_BPS, MAX_SWAP_SLIPPAGE_BPS, POOL_INDEX2, ORDER_PREFIX, address4, SwapService;
22795
22946
  var init_swap = __esm({
22796
22947
  "../core/src/swap.ts"() {
@@ -22810,7 +22961,7 @@ var init_swap = __esm({
22810
22961
  ORDER_PREFIX = "order-";
22811
22962
  address4 = (text2, what) => {
22812
22963
  if (!/^0x[0-9a-fA-F]{40}$/.test(text2)) throw new RangeError(`${what} is not an address`);
22813
- return getAddress27(text2);
22964
+ return getAddress28(text2);
22814
22965
  };
22815
22966
  SwapService = class {
22816
22967
  #p;
@@ -22834,7 +22985,7 @@ var init_swap = __esm({
22834
22985
  async checkToken(token) {
22835
22986
  if (token === ETH) throw new RangeError("an Ostra vault holds WETH, not native ETH: swap WETH");
22836
22987
  if (token === this.#p.config.deployment.token || token === WETH) return;
22837
- if (LAUNCH_PAIRS.some((p) => (p.kind === "ostra" || p.kind === "stock") && getAddress27(p.address) === token)) return;
22988
+ if (LAUNCH_PAIRS.some((p) => (p.kind === "ostra" || p.kind === "stock") && getAddress28(p.address) === token)) return;
22838
22989
  const lp = this.#p.config.deployment.launchpad;
22839
22990
  if (lp !== void 0) {
22840
22991
  const id = await this.#p.client.readContract({ address: lp.launchpad, abi: ostraLaunchpadAbi, functionName: "poolOf", args: [token] });
@@ -22934,7 +23085,7 @@ var init_swap = __esm({
22934
23085
  let swapped = null;
22935
23086
  let amountOut = 0n;
22936
23087
  for (const log2 of receipt.logs) {
22937
- if (getAddress27(log2.address) !== getAddress27(this.#p.swap.router)) continue;
23088
+ if (getAddress28(log2.address) !== getAddress28(this.#p.swap.router)) continue;
22938
23089
  try {
22939
23090
  const e = decodeEventLog4({ abi: ostraRouterAbi, topics: log2.topics, data: log2.data });
22940
23091
  if (e.eventName === "EscrowExecuted" && e.args.orderHash.toLowerCase() === hash.toLowerCase()) swapped = e.args.swapped;
@@ -22977,9 +23128,9 @@ var init_swap = __esm({
22977
23128
  });
22978
23129
 
22979
23130
  // ../core/src/unshield.ts
22980
- import { encodeFunctionData as encodeFunctionData14, getAddress as getAddress28 } from "viem";
23131
+ import { encodeFunctionData as encodeFunctionData14, getAddress as getAddress29 } from "viem";
22981
23132
  function recordName2(chainId, token, index) {
22982
- return `${chainId}-${getAddress28(token)}-${index}.json`;
23133
+ return `${chainId}-${getAddress29(token)}-${index}.json`;
22983
23134
  }
22984
23135
  function unshieldDelaySeconds(windowHours) {
22985
23136
  if (!Number.isFinite(windowHours) || windowHours < 0 || windowHours > UNSHIELD_MAX_WINDOW_HOURS) {
@@ -23052,7 +23203,7 @@ var init_unshield = __esm({
23052
23203
  }
23053
23204
  /** The private vaults created so far (their leaf spent), by index. */
23054
23205
  vaults() {
23055
- return this.#serial(async () => (await this.#records()).filter((r) => r.status === "spent").map((r) => ({ index: BigInt(r.index), vault: getAddress28(r.vault) })));
23206
+ return this.#serial(async () => (await this.#records()).filter((r) => r.status === "spent").map((r) => ({ index: BigInt(r.index), vault: getAddress29(r.vault) })));
23056
23207
  }
23057
23208
  /** The number of the private vault at `vault`, or throws when it is none of this agent's. */
23058
23209
  async indexOf(vault) {
@@ -23151,7 +23302,7 @@ var init_unshield = __esm({
23151
23302
  async #spend(r) {
23152
23303
  const ctx = await this.#context(BigInt(r.index));
23153
23304
  const vault = await ctx.vault.vaultAddress();
23154
- if (vault !== getAddress28(r.vault)) throw new Error(`private vault ${r.index} is ${vault}, not the recorded ${r.vault}`);
23305
+ if (vault !== getAddress29(r.vault)) throw new Error(`private vault ${r.index} is ${vault}, not the recorded ${r.vault}`);
23155
23306
  const pool = this.#config.deployment.pool;
23156
23307
  const batch = await readBatch(this.#client, pool, BigInt(r.batch));
23157
23308
  const leaf = batch.leaves[r.leafIndex];
@@ -23188,9 +23339,9 @@ var init_unshield = __esm({
23188
23339
  import {
23189
23340
  concatHex as concatHex2,
23190
23341
  decodeErrorResult as decodeErrorResult2,
23191
- encodeAbiParameters as encodeAbiParameters10,
23342
+ encodeAbiParameters as encodeAbiParameters11,
23192
23343
  encodeFunctionData as encodeFunctionData15,
23193
- getAddress as getAddress29,
23344
+ getAddress as getAddress30,
23194
23345
  maxUint256,
23195
23346
  parseAbi as parseAbi4,
23196
23347
  zeroAddress as zeroAddress12
@@ -23227,6 +23378,7 @@ var init_src3 = __esm({
23227
23378
  "../core/src/index.ts"() {
23228
23379
  "use strict";
23229
23380
  init_define_OSTRA_PACKAGED();
23381
+ init_ai();
23230
23382
  init_amount();
23231
23383
  init_chain2();
23232
23384
  init_channels();
@@ -23547,7 +23699,7 @@ var init_wasm_prover = __esm({
23547
23699
  // src/agent.ts
23548
23700
  import { readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
23549
23701
  import { join as join5 } from "node:path";
23550
- import { createPublicClient as createPublicClient2, getAddress as getAddress30, http as http2, isAddress as isAddress13 } from "viem";
23702
+ import { createPublicClient as createPublicClient2, getAddress as getAddress31, http as http2, isAddress as isAddress13 } from "viem";
23551
23703
  import { privateKeyToAccount as privateKeyToAccount5 } from "viem/accounts";
23552
23704
  function proverOf(c) {
23553
23705
  if (c === null) return null;
@@ -23607,6 +23759,8 @@ var init_agent = __esm({
23607
23759
  shield;
23608
23760
  creatorShield;
23609
23761
  unshield;
23762
+ /** Ostra AI's tasks paid from the vault (null without OSTRA_AI_URL). */
23763
+ ai;
23610
23764
  /** Ostra Swap from the agent's vaults, and its private notes (null without OSTRA_SWAP_DEPLOYMENT). */
23611
23765
  swap;
23612
23766
  privateBalance;
@@ -23629,6 +23783,7 @@ var init_agent = __esm({
23629
23783
  this.relayer?.attachBuyerVault(this.buyer);
23630
23784
  this.channels = new ChannelService(client, config, keys, this.buyer, this.sender);
23631
23785
  this.payments = new PayService(client, config, this.buyer, this.channels);
23786
+ this.ai = config.aiUrl === null ? null : new AiService(config, this.payments, this.buyer);
23632
23787
  this.seller = new VaultService(client, transport, config, keys, this.sender, "seller");
23633
23788
  this.creatorRelayer = config.relayerUrl === null ? null : new RelayerClient(client, config, p.creatorKeys, config.relayerUrl);
23634
23789
  const creatorSender = this.creatorRelayer ?? this.local;
@@ -23662,7 +23817,7 @@ var init_agent = __esm({
23662
23817
  }
23663
23818
  /** The agent's vault for `token`: the buyer vault for USDG, else its token vault (the launchpad's, when there is one). */
23664
23819
  vaultFor(token) {
23665
- const t = getAddress30(token);
23820
+ const t = getAddress31(token);
23666
23821
  if (t === this.config.deployment.token) return this.buyer;
23667
23822
  if (this.launchpad !== null) return this.launchpad.tokenVault(t);
23668
23823
  let v = this.#tokenVaults.get(t);
@@ -23701,7 +23856,7 @@ var init_agent = __esm({
23701
23856
  if (text2 === void 0) return;
23702
23857
  const r = JSON.parse(text2);
23703
23858
  if (r.chainId !== this.config.chainId || typeof r.crank !== "string" || !isAddress13(r.crank, { strict: false })) throw new Error(`${SELLER_RECORD} is not a seller record of chain ${this.config.chainId}`);
23704
- this.seller.setInitCrank(getAddress30(r.crank));
23859
+ this.seller.setInitCrank(getAddress31(r.crank));
23705
23860
  }
23706
23861
  /** True once accept_payments set the seller vault up. */
23707
23862
  async sellerReady() {
@@ -23721,7 +23876,7 @@ var init_agent = __esm({
23721
23876
  let crank;
23722
23877
  const known = await this.keys.folder.read(SELLER_RECORD);
23723
23878
  if (known !== void 0) {
23724
- crank = getAddress30(JSON.parse(known).crank);
23879
+ crank = getAddress31(JSON.parse(known).crank);
23725
23880
  } else {
23726
23881
  let res;
23727
23882
  try {
@@ -23731,7 +23886,7 @@ var init_agent = __esm({
23731
23886
  }
23732
23887
  const body = await res.json().catch(() => null);
23733
23888
  if (res.status !== 200 || typeof body?.crank !== "string" || !isAddress13(body.crank, { strict: false })) throw new Error(`the keeper answered ${res.status} without a crank`);
23734
- crank = getAddress30(body.crank);
23889
+ crank = getAddress31(body.crank);
23735
23890
  this.seller.setInitCrank(crank);
23736
23891
  await this.keys.folder.write(SELLER_RECORD, `${JSON.stringify({ chainId: this.config.chainId, token, crank, merchant })}
23737
23892
  `);
@@ -23877,7 +24032,7 @@ async function loadConfig(env = process.env) {
23877
24032
  keeperUrl: serviceUrl(env, "OSTRA_KEEPER_URL", services?.keeperUrl ?? null),
23878
24033
  relayerUrl: serviceUrl(env, "OSTRA_RELAYER_URL", services?.relayerUrl ?? null),
23879
24034
  aggregatorUrl: serviceUrl(env, "OSTRA_AGGREGATOR_URL", services?.aggregatorUrl ?? null),
23880
- aiUrl: null
24035
+ aiUrl: serviceUrl(env, "OSTRA_AI_URL", services?.aiUrl ?? null)
23881
24036
  };
23882
24037
  }
23883
24038
  var PROVER_WASM_FILES;
@@ -23895,8 +24050,21 @@ var init_config2 = __esm({
23895
24050
  });
23896
24051
 
23897
24052
  // src/tools.ts
23898
- import { readFile as readFile6, stat as stat4 } from "node:fs/promises";
24053
+ import { readFile as readFile6, stat as stat4, writeFile as writeFile3 } from "node:fs/promises";
24054
+ import { join as join7 } from "node:path";
23899
24055
  import { z } from "zod";
24056
+ function imageExt(b) {
24057
+ if (b.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) return "png";
24058
+ if (b[0] === 255 && b[1] === 216 && b[2] === 255) return "jpg";
24059
+ if (b.subarray(0, 4).toString("latin1") === "RIFF" && b.subarray(8, 12).toString("latin1") === "WEBP") return "webp";
24060
+ if (b.subarray(0, 4).toString("latin1") === "GIF8") return "gif";
24061
+ return "bin";
24062
+ }
24063
+ function videoExt(b) {
24064
+ if (b.subarray(4, 8).toString("latin1") === "ftyp") return "mp4";
24065
+ if (b.subarray(0, 4).equals(Buffer.from([26, 69, 223, 163]))) return "webm";
24066
+ return "bin";
24067
+ }
23900
24068
  async function run2(fn, rpcUrls2) {
23901
24069
  try {
23902
24070
  return { content: [{ type: "text", text: toJson(await fn()) }] };
@@ -23947,6 +24115,60 @@ function registerTools(server, agent) {
23947
24115
  { url: z.string().url(), method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]).default("GET"), headers: z.record(z.string(), z.string()).optional(), body: z.string().max(1e6).optional(), maxPrice: usdg, deposit: usdg.optional() },
23948
24116
  (a) => agent.payments.pay({ url: a.url, method: a.method, maxPrice: a.maxPrice, ...a.headers === void 0 ? {} : { headers: a.headers }, ...a.body === void 0 ? {} : { body: a.body }, ...a.deposit === void 0 ? {} : { deposit: a.deposit } })
23949
24117
  );
24118
+ const ai = () => {
24119
+ if (agent.ai === null) throw new Error("Ostra AI is not configured here (OSTRA_AI_URL)");
24120
+ return agent.ai;
24121
+ };
24122
+ const aiDir = join7(agent.config.home, AI_DIR);
24123
+ tool(
24124
+ "ostra_ai",
24125
+ "Runs an AI task on Ostra AI. text: request { messages, max_tokens, and optionally quality (best, balanced or cheapest; default best), privacy (no_training, zdr or standard; default no_training), temperature, top_p, seed, stop, tools, tool_choice, response_format, reasoning }. image: { prompt, and optionally n, quality, aspect_ratio, resolution, seed, background, output_format, image_quality, references }. video: { prompt, duration in seconds, and optionally quality, resolution (such as 480p; models priced per token need one), aspect_ratio, size, frame_images, references, generate_audio, seed }. A text task is read as a stream and answered whole, however long the model takes. No model is named: Ostra chooses one by its quality rating within maxPrice, and a task no model can do within it is refused with the reasons, nothing paid. Paid in USDG from the vault through an x402 channel to Ostra AI, opened when needed with `deposit` (default 1 USDG; its unused deposit comes back to the vault when the channel closes). maxPrice is the most the task may cost; what it did not cost stays as the vault's credit with Ostra AI and pays part of the next task (ostra_ai_credit). Images are saved as files in the agent's directory; a video task answers a job, followed with ostra_ai_job.",
24126
+ { task: z.enum(AI_TASK_KINDS), request: z.record(z.string(), z.unknown()), maxPrice: usdg, deposit: usdg.optional() },
24127
+ async (a) => {
24128
+ const r = await ai().task(a.task, a.request, a.maxPrice, a.deposit);
24129
+ const answer = r.answer;
24130
+ if (a.task !== "image" || answer === null || typeof answer !== "object" || !Array.isArray(answer.images)) return r;
24131
+ await ensurePrivateDir(aiDir);
24132
+ const id = typeof answer.task === "string" && /^[0-9a-f]{1,64}$/.test(answer.task) ? answer.task : String(Date.now());
24133
+ const images = [];
24134
+ for (const [i, img] of answer.images.entries()) {
24135
+ if (typeof img.b64_json !== "string") {
24136
+ images.push({ media_type: img.media_type ?? null, file: null, note: "the answer carried no image data" });
24137
+ continue;
24138
+ }
24139
+ const bytes = Buffer.from(img.b64_json, "base64");
24140
+ const file = join7(aiDir, `${id}-${i}.${imageExt(bytes)}`);
24141
+ await writeFile3(file, bytes, { mode: 384 });
24142
+ images.push({ media_type: img.media_type, file, bytes: bytes.length });
24143
+ }
24144
+ return { ...r, answer: { ...answer, images } };
24145
+ }
24146
+ );
24147
+ tool(
24148
+ "ostra_ai_job",
24149
+ "A video job of ostra_ai: its status until it is final (completed, failed, cancelled or expired; the first final read settles its cost and credits the rest to the vault). With download (default true), a completed job's video is saved as a file in the agent's directory. Free: no payment.",
24150
+ { job: z.string().regex(/^[0-9a-f]{32}$/, "the job ostra_ai answered: 32 hex characters"), download: z.boolean().default(true) },
24151
+ async (a) => {
24152
+ const s = await ai().job(a.job);
24153
+ const answer = s.answer;
24154
+ if (s.status !== 200 || answer === null || typeof answer !== "object") return s;
24155
+ const final = typeof answer.status === "string" && FINAL_JOB.includes(answer.status);
24156
+ if (!a.download || answer.status !== "completed") return { ...answer, final };
24157
+ const res = await fetch(ai().contentUrl(a.job), { signal: AbortSignal.timeout(6e5) });
24158
+ const size = Number(res.headers.get("content-length") ?? "0");
24159
+ if (!res.ok || size > MAX_VIDEO_BYTES) return { ...answer, final, file: null, note: `the video could not be read (${res.status}${size > MAX_VIDEO_BYTES ? `, ${size} bytes` : ""}); ask again` };
24160
+ const bytes = Buffer.from(await res.arrayBuffer());
24161
+ if (bytes.length > MAX_VIDEO_BYTES) return { ...answer, final, file: null, note: `the video is larger than ${MAX_VIDEO_BYTES} bytes` };
24162
+ await ensurePrivateDir(aiDir);
24163
+ const file = join7(aiDir, `${a.job}.${videoExt(bytes)}`);
24164
+ await writeFile3(file, bytes, { mode: 384 });
24165
+ return { ...answer, final, file, bytes: bytes.length };
24166
+ }
24167
+ );
24168
+ tool("ostra_ai_credit", "The vault's credit with Ostra AI: what earlier tasks were paid and did not cost, used first by the next task (USDG).", {}, async () => {
24169
+ const c = await ai().credit();
24170
+ return { payer: c.payer, credit: typeof c.credit === "string" && /^[0-9]+$/.test(c.credit) ? formatTokenAmount(BigInt(c.credit)) : c.credit };
24171
+ });
23950
24172
  tool("accept_payments", "Sets up the seller side: the seller vault with the Ostra keeper's crank (it claims vouchers), and the merchant key for the seller server (merchant/).", {}, () => agent.acceptPayments());
23951
24173
  tool("seller_balance", "The seller vault: balance, nonce, crank.", {}, async () => {
23952
24174
  if (!await agent.sellerReady()) throw new Error("this agent has no seller vault yet; call accept_payments first");
@@ -24060,7 +24282,7 @@ function registerTools(server, agent) {
24060
24282
  );
24061
24283
  tool(
24062
24284
  "launch",
24063
- "Launches a token on the Ostra launchpad (1 billion supply) paired with USDG (default), ETH, OSTRA or a listed stock token (pairs), from the agent's creator vault of that pair, optionally with a dev buy in the pair's token paid by that creator vault in the same transaction and vesting to the agent's token vault. The market cap is in US dollars, set in the pair's token at its price now (Chainlink for ETH and stocks; OSTRA at Chainlink ETH/USD times its bonding curve's price). The relayer fronts the 0.0002 ETH launch fee and charges it in USDG. The launch is simulated first; nothing is signed if it would fail. `options` sets LaunchParams fields (taxes, buckets, anti-snipe, limits, graduation, circuit breaker) beyond Ostra's defaults.",
24285
+ "Launches a token on the Ostra launchpad (1 billion supply) paired with USDG (default), ETH, OSTRA or a listed stock token (pairs), from the agent's creator vault of that pair, optionally with a dev buy in the pair's token paid by that creator vault in the same transaction and vesting to the agent's token vault. The market cap is in US dollars, set in the pair's token at its price now (Chainlink for ETH and stocks; OSTRA at Chainlink ETH/USD times its price in the pool it graduated to). The relayer fronts the 0.0002 ETH launch fee and charges it in USDG. The launch is simulated first; nothing is signed if it would fail. `options` sets LaunchParams fields (taxes, buckets, anti-snipe, limits, graduation, circuit breaker) beyond Ostra's defaults.",
24064
24286
  {
24065
24287
  name: z.string().min(1).max(64),
24066
24288
  symbol: z.string().regex(/^[A-Za-z0-9]{1,11}$/),
@@ -24172,13 +24394,14 @@ function launchOptions(raw) {
24172
24394
  }
24173
24395
  return out;
24174
24396
  }
24175
- var toJson, address5, usdg, units, pair2, slippage2, bytes323, swapToken, tokenAddress, uri, publicFields, BIGINT_FIELDS, ALLOWED_OPTIONS;
24397
+ var toJson, address5, usdg, units, pair2, slippage2, bytes323, swapToken, tokenAddress, uri, publicFields, AI_DIR, MAX_VIDEO_BYTES, FINAL_JOB, BIGINT_FIELDS, ALLOWED_OPTIONS;
24176
24398
  var init_tools = __esm({
24177
24399
  "src/tools.ts"() {
24178
24400
  "use strict";
24179
24401
  init_define_OSTRA_PACKAGED();
24180
24402
  init_src3();
24181
24403
  init_src();
24404
+ init_disk();
24182
24405
  toJson = (value) => JSON.stringify(value, (_k, v) => typeof v === "bigint" ? v.toString() : v, 2);
24183
24406
  address5 = z.string().regex(/^0x[0-9a-fA-F]{40}$/, "an address: 0x and 40 hex characters");
24184
24407
  usdg = z.string().regex(/^(0|[1-9][0-9]*)(\.[0-9]{1,6})?$/, "a USDG amount: a plain decimal with at most 6 decimals");
@@ -24203,6 +24426,9 @@ var init_tools = __esm({
24203
24426
  x: z.string().url().max(200).optional().describe("the X (Twitter) profile link"),
24204
24427
  telegram: z.string().url().max(200).optional()
24205
24428
  };
24429
+ AI_DIR = "ai";
24430
+ MAX_VIDEO_BYTES = 512 * 1024 * 1024;
24431
+ FINAL_JOB = ["completed", "failed", "cancelled", "expired"];
24206
24432
  BIGINT_FIELDS = /* @__PURE__ */ new Set(["minDividendBalance", "maxBuy", "maxWallet", "graduationThreshold"]);
24207
24433
  ALLOWED_OPTIONS = /* @__PURE__ */ new Set([
24208
24434
  "tiers",