@ostraagent/mcp 0.1.12 → 0.1.13
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/README.md +1 -1
- package/dist/ostra-mcp.js +114 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ Keep the file and the passphrase off the machine. On a new machine, run `npx -y
|
|
|
46
46
|
- **Ostra AI:** `ostra_ai` (a text, image or video task; Ostra chooses the model by its quality rating within `maxPrice`, paid in USDG from a channel of the vault, and what a task did not cost stays as the vault's credit), `ostra_ai_job` (a video job, saved as a file once completed), `ostra_ai_credit`
|
|
47
47
|
- **Selling services:** `accept_payments`, `seller_balance`, `seller_withdraw`
|
|
48
48
|
- **Recovery:** `recovery_status`, `set_guardian`, `set_recovery_policy`, `cancel_recovery`, `support_recovery`, `request_recovery`
|
|
49
|
-
- **Withdrawal lock:** `vault_lock` (status; set a withdrawal address on another device, a delay of 36 hours to 14 days and a daily limit: anything else the vault sends counts against the limit, and every loosening waits the delay; off; cancel what waits), `vault_link` (the linked vault a Borro loan is paid to), `
|
|
49
|
+
- **Withdrawal lock:** `vault_lock` (status, with the hashes the vault approves for EIP-1271, also of any other Ostra vault for a guardian; set a withdrawal address on another device, a delay of 36 hours to 14 days and a daily limit: anything else the vault sends counts against the limit, and every loosening waits the delay; off; cancel what waits), `vault_link` (the linked vault a Borro loan is paid to), `vault_revoke_hash` (withdraws an EIP-1271 approval of the vault or of a Borro stock's vault; no tool approves a hash it is given, since USDG takes the vault's EIP-1271 answer as a permit or a transfer authorization of its funds: the vault approves only digests the server builds itself), `guard_vault` (as a guardian of another locked vault: cancel its waiting changes, revoke an approval, sweep it to its withdrawal address, bring its Borro shares or collateral back)
|
|
50
50
|
- **Strategies:** `strategy_plan` (a conservative plan, USDG into a cash vault that passes every check, and, when the agent holds SPY, QQQ or NVDA, a balanced one: the stock as collateral on Borro, USDG borrowed into the cash vault; each with its steps, gas, 30-day earnings net of gas, risks and when it stops; every step earns over 3x its gas in 30 days or is left out), `strategy_apply` (runs a plan step by step, each checked and sized again right before it is signed), `strategy_check` (each run's check of the cash vaults and the carries; urgent exits and repayments run at once), `strategy_report` (what the strategies earn). Only for an agent registered in ERC-8004 (`publish_profile`); `strategy_check` and its exits run for every vault
|
|
51
51
|
- **Trading capital:** `trading` (USDG set aside for the agent's own trades, with Ostra's limits, which an agent may only tighten: a position at most 25% of the capital and no larger than a buy that moves the price 1%; buys stop for the day after a 5% loss that day and for the week after 10% that week)
|
|
52
52
|
- **OstraBreaker:** `breaker` (status, or arm: OstraBreaker as a guardian of the USDG vault, watching each cash vault; when a limit is crossed on chain, Ostra's breaker keeper sends the trip and the position comes back to the vault). `vault_lock set` arms it first by itself
|
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.
|
|
21
|
+
define_OSTRA_PACKAGED_default = { version: "0.1.13", deployment: { version: 1, chainId: 4663, fromBlock: "91991509", token: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168", batchSettlement: "0x4020074e9dF2ce1deE5A9C1b5c3f541D02a10003", vaultImplementation: "0xec0ca4A1393D91c42cA809F7F9dd82Bd597E8E58", vaultBeacon: "0xE9F525B9EaeE48d13AEd28fE146F48f2832a18a0", vaultFactory: "0x043a15c514CFE2c797d33520bFF91a5DCdbf2979", poolImplementation: "0xC04d4a222dC1C966640B977608bE29949b0648ec", poolBeacon: "0x30669Ca534921038a531BBE27116d85bB7406fFF", pool: "0x6ea80F2462e5Fd783B0Ec3B2c7BaC96795980CD6", splitFactory: "0xAAf54A483B2c7c2c5ecFc1eDED5ed1619C1bA882", beaconOwner: "0x55533a51d9bd9b06F2D179d919BB31995EF96E5e", registry: "0xcE6Cc1f93744f4090DA1444Bb8590d9206157506", vaultModule: "0x55A89fF907f5F5756470e2ec5Dc5E4E1C54Da770", launchpad: { hook: "0x63A784afb8905452aDceC471a45E555F5caE68cC", fees: "0x8e79671DC9729476614C78aFcf2345D4c1963801", launchpad: "0xfC57162C0e3f9773F97fEa8d276e957d7c43A6C5", creatorSplit: "0x987994dE6A1d5303B9e3F50977cB0321BA4D033B", dispatcher: "0x44Bb65164b2855f8E80B142d5Fb9bDb72E869986", locker: "0xb593812363bAd70Ee381c7B54c4FC82b0BA3A4A7", devBuy: "0x0e1Fd799E136dcfEcad5695B07Ac5DAc5B2fF4bc", vesting: "0xadD9C1995910457312c156E7D8120D1b447E179a", airdrop: "0xBC798D956aF4c2B104FFC6106d5322294Bc103bb", owner: "0x6569E27A95a6A3E92A311B4Cc6600fed56aA50A2" }, breaker: "0x2E33244dE6A64007204f763e9ef81FC33F1a8e01" }, 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
|
|
|
@@ -15453,7 +15453,7 @@ var init_morpho = __esm({
|
|
|
15453
15453
|
});
|
|
15454
15454
|
|
|
15455
15455
|
// ../sdk/src/borro.ts
|
|
15456
|
-
import { getAddress as getAddress5, parseAbi as parseAbi2, zeroAddress as zeroAddress4 } from "viem";
|
|
15456
|
+
import { getAbiItem, getAddress as getAddress5, parseAbi as parseAbi2, zeroAddress as zeroAddress4 } from "viem";
|
|
15457
15457
|
function borroStocks() {
|
|
15458
15458
|
return BORRO_STOCKS.map((s) => {
|
|
15459
15459
|
const market2 = { loanToken: USDG, collateralToken: s.vault, oracle: s.oracle, irm: BORRO_IRM, lltv: s.lltv };
|
|
@@ -15474,6 +15474,26 @@ function halfLltvMaxDebt(collateral, price, lltv) {
|
|
|
15474
15474
|
const value = collateral * price / 10n ** 36n;
|
|
15475
15475
|
return value * lltv * VAULT_MAX_LTV_OF_LLTV_BPS / (10n ** 18n * 10000n);
|
|
15476
15476
|
}
|
|
15477
|
+
async function readHashApprovals(client, logsClient, vault, fromBlock) {
|
|
15478
|
+
const version = Number(await client.readContract({ address: vault, abi: ostraVaultAbi, functionName: "VERSION" }));
|
|
15479
|
+
if (version < VAULT_V3) return [];
|
|
15480
|
+
const event = getAbiItem({ abi: ostraVaultModuleAbi, name: "HashApproved" });
|
|
15481
|
+
const logs = await getLogsChunked(logsClient, { address: vault, event, fromBlock, toBlock: await logsClient.getBlockNumber({ cacheTime: 0 }) });
|
|
15482
|
+
const head = await blockTime(client);
|
|
15483
|
+
const hashes = [];
|
|
15484
|
+
for (const l of logs) {
|
|
15485
|
+
const h = l.args.hash.toLowerCase();
|
|
15486
|
+
if (!hashes.includes(h)) hashes.push(h);
|
|
15487
|
+
}
|
|
15488
|
+
const out = [];
|
|
15489
|
+
for (const hash of hashes) {
|
|
15490
|
+
const validFrom = BigInt(
|
|
15491
|
+
await client.readContract({ address: vault, abi: ostraVaultAbi, functionName: "hashValidFrom", args: [hash], blockNumber: head.blockNumber })
|
|
15492
|
+
);
|
|
15493
|
+
if (validFrom !== 0n) out.push({ hash, validFrom, valid: head.timestamp >= validFrom });
|
|
15494
|
+
}
|
|
15495
|
+
return out;
|
|
15496
|
+
}
|
|
15477
15497
|
async function readVaultGuard(client, vault) {
|
|
15478
15498
|
const version = Number(await client.readContract({ address: vault, abi: ostraVaultAbi, functionName: "VERSION" }));
|
|
15479
15499
|
const off = { withdrawal: zeroAddress4, delay: 0, dailyLimit: 0n };
|
|
@@ -19180,7 +19200,7 @@ var init_relayer = __esm({
|
|
|
19180
19200
|
init_messages();
|
|
19181
19201
|
init_external_abi();
|
|
19182
19202
|
RELAYER_MARGIN_BPS = 1000n;
|
|
19183
|
-
RELAYER_QUOTE_TOLERANCE_BPS =
|
|
19203
|
+
RELAYER_QUOTE_TOLERANCE_BPS = 1000n;
|
|
19184
19204
|
ETH_USD_DEVIATION_BPS = 50n;
|
|
19185
19205
|
ETH_USD_MAX_AGE_SECONDS = 90000n;
|
|
19186
19206
|
MAX_RELAY_CALLS = 8;
|
|
@@ -22391,6 +22411,26 @@ var init_borro2 = __esm({
|
|
|
22391
22411
|
const at = await this.#address(vault, what.toUpperCase());
|
|
22392
22412
|
return { vault: at, ...await readVaultGuard(this.#p.client, at) };
|
|
22393
22413
|
}
|
|
22414
|
+
/**
|
|
22415
|
+
* The lock's status (guard) with the hashes the vault approves for EIP-1271 now (sdk readHashApprovals): of the vault
|
|
22416
|
+
* of `what`, or, given `otherText`, of any Ostra vault (a guardian watching the vault it guards). Read only.
|
|
22417
|
+
*/
|
|
22418
|
+
async lockStatus(what, otherText) {
|
|
22419
|
+
let at;
|
|
22420
|
+
if (otherText === void 0) {
|
|
22421
|
+
const { vault } = this.#vaultOf(what);
|
|
22422
|
+
at = await this.#address(vault, what.toUpperCase());
|
|
22423
|
+
} else {
|
|
22424
|
+
if (!isAddress8(otherText, { strict: false })) throw new RangeError(`${otherText} is not an address`);
|
|
22425
|
+
at = getAddress19(otherText);
|
|
22426
|
+
if (await readVault(this.#p.client, this.#p.config.deployment, at) === null) throw new Error(`${at} is not an Ostra vault`);
|
|
22427
|
+
}
|
|
22428
|
+
const [g, approvals] = await Promise.all([
|
|
22429
|
+
readVaultGuard(this.#p.client, at),
|
|
22430
|
+
readHashApprovals(this.#p.client, this.#p.logsClient ?? this.#p.client, at, BigInt(this.#p.config.deployment.fromBlock))
|
|
22431
|
+
]);
|
|
22432
|
+
return { vault: at, ...g, approvals };
|
|
22433
|
+
}
|
|
22394
22434
|
/**
|
|
22395
22435
|
* Turns the withdrawal lock of the vault of `what` on (a withdrawal address, a delay, a daily limit in the vault's
|
|
22396
22436
|
* token) or changes it; `withdrawal` "off" turns it off (that waits the delay). The withdrawal address must keep
|
|
@@ -22474,11 +22514,27 @@ var init_borro2 = __esm({
|
|
|
22474
22514
|
const names = ["cancel", "revoke", "sweep", "redeem", "withdraw collateral"];
|
|
22475
22515
|
return this.#spend(this.#p.buyer, VAULT_ACTION.GUARD, guardParams(target, call), `guard (${names[call.op] ?? call.op}) of ${target}`);
|
|
22476
22516
|
}
|
|
22477
|
-
/**
|
|
22517
|
+
/**
|
|
22518
|
+
* Approves (or withdraws) `hash` for EIP-1271 on the buyer vault: under the lock an approval waits its delay. For this
|
|
22519
|
+
* package's own digests only (Raeto's login message, OstraBreaker's limits), which it builds and checks itself: an
|
|
22520
|
+
* approved hash makes the vault answer isValidSignature for it, and USDG takes such an answer for a permit and for a
|
|
22521
|
+
* transfer authorization, so a hash from anywhere else could hand the vault's funds out. No tool approves a hash it is
|
|
22522
|
+
* given (withdrawApproval only withdraws).
|
|
22523
|
+
*/
|
|
22478
22524
|
async approveHash(hash, approved) {
|
|
22479
22525
|
if (!/^0x[0-9a-fA-F]{64}$/.test(hash) || /^0x0{64}$/.test(hash)) throw new RangeError("the hash is 32 bytes of 0x hex, not zero");
|
|
22480
22526
|
return this.#spend(this.#p.buyer, VAULT_ACTION.APPROVE_HASH, approveHashParams({ hash, approved }), approved ? "EIP-1271 approval" : "EIP-1271 approval withdrawal");
|
|
22481
22527
|
}
|
|
22528
|
+
/**
|
|
22529
|
+
* Withdraws the EIP-1271 approval of `hash` by the vault of `what` ("USDG", the buyer vault, or a Borro stock's
|
|
22530
|
+
* vault): lands when there is none (nothing to do). Withdrawing is at once, under the lock too.
|
|
22531
|
+
*/
|
|
22532
|
+
async withdrawApproval(what, hash) {
|
|
22533
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(hash) || /^0x0{64}$/.test(hash)) throw new RangeError("the hash is 32 bytes of 0x hex, not zero");
|
|
22534
|
+
const { vault } = this.#vaultOf(what);
|
|
22535
|
+
await this.#address(vault, what.toUpperCase());
|
|
22536
|
+
return this.#spend(vault, VAULT_ACTION.APPROVE_HASH, approveHashParams({ hash, approved: false }), `EIP-1271 approval withdrawal (${what.toUpperCase()} vault)`);
|
|
22537
|
+
}
|
|
22482
22538
|
};
|
|
22483
22539
|
}
|
|
22484
22540
|
});
|
|
@@ -23749,7 +23805,7 @@ function simulatedGas(gasUsed) {
|
|
|
23749
23805
|
const g = gasUsed * 5n / 4n + SPEND_GAS_HEADROOM2;
|
|
23750
23806
|
return g > VAULT_SPEND_GAS ? g : VAULT_SPEND_GAS;
|
|
23751
23807
|
}
|
|
23752
|
-
var LAUNCHPAD_DIR, CREATE_VAULT_GAS2, LAUNCH_GAS_HEADROOM, PAIRS_READ_CONCURRENCY, SPEND_GAS_HEADROOM2, DAY, TOKEN_LIST_MAX, METADATA_MAX_BYTES, launchedEvent, POOL_SETTING_NAMES, WOTS_GAS_SPREAD, STAND_IN_URI, LaunchpadService;
|
|
23808
|
+
var LAUNCHPAD_DIR, CREATE_VAULT_GAS2, LAUNCH_GAS_HEADROOM, PAIRS_READ_CONCURRENCY, SPEND_GAS_HEADROOM2, DAY, LOGS_CATCH_UP_SECONDS, TOKEN_LIST_MAX, METADATA_MAX_BYTES, launchedEvent, POOL_SETTING_NAMES, WOTS_GAS_SPREAD, STAND_IN_URI, LaunchpadService;
|
|
23753
23809
|
var init_launchpad = __esm({
|
|
23754
23810
|
"../core/src/launchpad.ts"() {
|
|
23755
23811
|
"use strict";
|
|
@@ -23770,6 +23826,7 @@ var init_launchpad = __esm({
|
|
|
23770
23826
|
PAIRS_READ_CONCURRENCY = 6;
|
|
23771
23827
|
SPEND_GAS_HEADROOM2 = 100000n;
|
|
23772
23828
|
DAY = 86400;
|
|
23829
|
+
LOGS_CATCH_UP_SECONDS = 30;
|
|
23773
23830
|
TOKEN_LIST_MAX = 50;
|
|
23774
23831
|
METADATA_MAX_BYTES = 65536;
|
|
23775
23832
|
launchedEvent = parseAbiItem5("event Launched(bytes32 indexed poolId, address indexed token, address indexed creatorVault, address quote)");
|
|
@@ -24601,13 +24658,20 @@ var init_launchpad = __esm({
|
|
|
24601
24658
|
* is never registered twice. An identity someone else registered and sent to the creator vault (an ERC-721 transfer
|
|
24602
24659
|
* the vault accepts) is no registration of this agent: with no Registered event of the vault, this is null. A
|
|
24603
24660
|
* registration sent again just now is read from its receipt instead (#recordFromReceipt), not from logs that may lag.
|
|
24661
|
+
* The vault's identities are counted at the chain's head and the events read up to that same block, after the logs
|
|
24662
|
+
* RPC has reached it: a registration the count holds is never missed because the logs RPC was behind (which would
|
|
24663
|
+
* register the agent twice); when the logs RPC does not reach that block soon, this throws before anything is signed.
|
|
24604
24664
|
*/
|
|
24605
24665
|
async #recoverAgentRecord() {
|
|
24606
24666
|
const vault = getAddress24(await this.#creator.vaultAddress());
|
|
24607
|
-
const
|
|
24667
|
+
const head = await this.#client.getBlockNumber({ cacheTime: 0 });
|
|
24668
|
+
const owned = await this.#client.readContract({ address: ERC8004_IDENTITY_REGISTRY, abi: identityRegistryAbi, functionName: "balanceOf", args: [vault], blockNumber: head });
|
|
24608
24669
|
if (owned === 0n) return null;
|
|
24609
|
-
|
|
24610
|
-
|
|
24670
|
+
for (let waited = 0; await this.#logsClient.getBlockNumber({ cacheTime: 0 }) < head; waited++) {
|
|
24671
|
+
if (waited >= LOGS_CATCH_UP_SECONDS) throw new Error(`the logs RPC has not reached block ${head} of the chain RPC after ${LOGS_CATCH_UP_SECONDS} seconds, so the creator vault's ERC-8004 registration cannot be read yet: call again shortly; nothing was signed`);
|
|
24672
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
24673
|
+
}
|
|
24674
|
+
const logs = await getLogsChunked(this.#logsClient, { address: ERC8004_IDENTITY_REGISTRY, event: agentRegisteredEvent, args: { owner: vault }, fromBlock: BigInt(this.#config.deployment.fromBlock), toBlock: head });
|
|
24611
24675
|
for (const log2 of logs) {
|
|
24612
24676
|
const { agentId, agentURI } = log2.args;
|
|
24613
24677
|
const who = await readAgentIdentity(this.#client, agentId);
|
|
@@ -24620,7 +24684,9 @@ var init_launchpad = __esm({
|
|
|
24620
24684
|
}
|
|
24621
24685
|
/**
|
|
24622
24686
|
* The registration transaction `txHash` of the creator vault, read from its receipt (the vault's AgentRegistered
|
|
24623
|
-
* event) and written to agent.json; null when it registered nothing.
|
|
24687
|
+
* event) and written to agent.json; null when it registered nothing. The file it registered with is the Identity
|
|
24688
|
+
* Registry's Registered event's agentURI in that receipt (a registration signed by an earlier call carries that
|
|
24689
|
+
* call's file); `uri` only when the receipt has no such event.
|
|
24624
24690
|
*/
|
|
24625
24691
|
async #recordFromReceipt(txHash, uri2) {
|
|
24626
24692
|
const vault = getAddress24(await this.#creator.vaultAddress());
|
|
@@ -24635,7 +24701,17 @@ var init_launchpad = __esm({
|
|
|
24635
24701
|
}
|
|
24636
24702
|
}
|
|
24637
24703
|
if (agentId === void 0) return null;
|
|
24638
|
-
|
|
24704
|
+
let registered;
|
|
24705
|
+
for (const log2 of receipt.logs) {
|
|
24706
|
+
if (getAddress24(log2.address) !== getAddress24(ERC8004_IDENTITY_REGISTRY)) continue;
|
|
24707
|
+
try {
|
|
24708
|
+
const e = decodeEventLog3({ abi: [agentRegisteredEvent], data: log2.data, topics: log2.topics });
|
|
24709
|
+
const a = e.args;
|
|
24710
|
+
if (a.agentId.toString() === agentId && getAddress24(a.owner) === vault) registered = a.agentURI;
|
|
24711
|
+
} catch {
|
|
24712
|
+
}
|
|
24713
|
+
}
|
|
24714
|
+
const record = { agentId, uri: registered ?? uri2, txHash, at: Math.floor(Date.now() / 1e3) };
|
|
24639
24715
|
await this.#folder.write("agent.json", JSON.stringify(record, null, 2));
|
|
24640
24716
|
return record;
|
|
24641
24717
|
}
|
|
@@ -24707,10 +24783,11 @@ var init_launchpad = __esm({
|
|
|
24707
24783
|
const first = await this.#publishProfileFile(null);
|
|
24708
24784
|
const unnumbered = { uri: first.uri, profile: first.profile };
|
|
24709
24785
|
if (first.profile.status !== "sent") {
|
|
24710
|
-
const resent = first.profile.
|
|
24711
|
-
const landed = resent
|
|
24712
|
-
if (landed
|
|
24713
|
-
|
|
24786
|
+
const resent = first.profile.resent;
|
|
24787
|
+
const landed = resent.operation === "vault_spend" && resent.action === VAULT_ACTION.REGISTER_AGENT ? await this.#recordFromReceipt(resent.txHash, first.uri) : null;
|
|
24788
|
+
if (landed !== null) return { agentId: landed.agentId, registration: null, unnumbered, ...await this.#publishProfileFile(landed) };
|
|
24789
|
+
const after = await this.#agentRecord() ?? await this.#recoverAgentRecord();
|
|
24790
|
+
if (after !== null) return { agentId: after.agentId, registration: null, unnumbered, ...await this.#publishProfileFile(after) };
|
|
24714
24791
|
}
|
|
24715
24792
|
const registration = await this.registerAgent(first.uri);
|
|
24716
24793
|
const record = await this.#agentRecord();
|
|
@@ -26000,7 +26077,7 @@ var init_raeto = __esm({
|
|
|
26000
26077
|
await this.#keepApprovals((await this.#keptApprovals()).filter((h) => h !== hash));
|
|
26001
26078
|
return { done: true, note };
|
|
26002
26079
|
}
|
|
26003
|
-
return { done: false, note: `${note}; the approval may still read or land: call raeto login again to withdraw it, or
|
|
26080
|
+
return { done: false, note: `${note}; the approval may still read or land: call raeto login again to withdraw it, or vault_revoke_hash ${hash}` };
|
|
26004
26081
|
}
|
|
26005
26082
|
/**
|
|
26006
26083
|
* Signs the vault in to Raeto as an agent (see the file comment): its own Raeto account and API key, kept here. With a
|
|
@@ -29590,7 +29667,7 @@ var init_orders = __esm({
|
|
|
29590
29667
|
});
|
|
29591
29668
|
|
|
29592
29669
|
// ../../../../../../srv/apps/ostra-swap/sdk/src/private.ts
|
|
29593
|
-
import { encodeAbiParameters as encodeAbiParameters13, encodeFunctionData as encodeFunctionData15, getAbiItem, getAddress as getAddress32, getContractAddress as getContractAddress5, keccak256 as keccak25619, parseEventLogs, toHex as toHex8 } from "viem";
|
|
29670
|
+
import { encodeAbiParameters as encodeAbiParameters13, encodeFunctionData as encodeFunctionData15, getAbiItem as getAbiItem2, getAddress as getAddress32, getContractAddress as getContractAddress5, keccak256 as keccak25619, parseEventLogs, toHex as toHex8 } from "viem";
|
|
29594
29671
|
function packDigest(elements) {
|
|
29595
29672
|
if (elements.length !== 8) throw new Error("a digest has 8 field elements");
|
|
29596
29673
|
let v = 0n;
|
|
@@ -29804,7 +29881,7 @@ var init_private = __esm({
|
|
|
29804
29881
|
MAX_AMOUNT = 1n << 128n;
|
|
29805
29882
|
MAX_UINT642 = (1n << 64n) - 1n;
|
|
29806
29883
|
ZERO2 = "0x0000000000000000000000000000000000000000";
|
|
29807
|
-
noteAddedEvent =
|
|
29884
|
+
noteAddedEvent = getAbiItem2({ abi: ostraPrivatePoolAbi, name: "NoteAdded" });
|
|
29808
29885
|
PoolTrees = class {
|
|
29809
29886
|
#data;
|
|
29810
29887
|
/** The sync running now: syncs run one at a time (each one's rollback assumes no other changes the trees). */
|
|
@@ -32464,7 +32541,7 @@ var init_strategy2 = __esm({
|
|
|
32464
32541
|
});
|
|
32465
32542
|
|
|
32466
32543
|
// ../core/src/swap.ts
|
|
32467
|
-
import { decodeErrorResult as decodeErrorResult2, decodeEventLog as decodeEventLog4, getAbiItem as
|
|
32544
|
+
import { decodeErrorResult as decodeErrorResult2, decodeEventLog as decodeEventLog4, getAbiItem as getAbiItem3, getAddress as getAddress38 } from "viem";
|
|
32468
32545
|
function refusalOf(reason, outDecimals) {
|
|
32469
32546
|
if (reason === "0x") return "the swap reverted without a reason (out of gas, or a revert with no data)";
|
|
32470
32547
|
try {
|
|
@@ -33081,7 +33158,7 @@ var init_swap = __esm({
|
|
|
33081
33158
|
*/
|
|
33082
33159
|
async orderResult(order, fromBlock, escrow) {
|
|
33083
33160
|
const toBlock = await this.#p.logsClient.getBlockNumber({ cacheTime: 0 });
|
|
33084
|
-
const logs = await getLogsChunked(this.#p.logsClient, { address: this.#p.swap.router, event:
|
|
33161
|
+
const logs = await getLogsChunked(this.#p.logsClient, { address: this.#p.swap.router, event: getAbiItem3({ abi: ostraRouterAbi, name: "EscrowExecuted" }), args: { orderHash: order }, fromBlock, toBlock });
|
|
33085
33162
|
let spent = 0n;
|
|
33086
33163
|
let received = 0n;
|
|
33087
33164
|
let moved = false;
|
|
@@ -33152,7 +33229,7 @@ var init_swap = __esm({
|
|
|
33152
33229
|
let hash = tx;
|
|
33153
33230
|
if (hash === null && r.fromBlock !== void 0) {
|
|
33154
33231
|
const toBlock = await this.#p.logsClient.getBlockNumber({ cacheTime: 0 });
|
|
33155
|
-
const logs = await getLogsChunked(this.#p.logsClient, { address: this.#p.swap.router, event:
|
|
33232
|
+
const logs = await getLogsChunked(this.#p.logsClient, { address: this.#p.swap.router, event: getAbiItem3({ abi: ostraRouterAbi, name: "EscrowExecuted" }), args: { orderHash: r.hash }, fromBlock: BigInt(r.fromBlock), toBlock });
|
|
33156
33233
|
const moved = logs.find((l) => l.args.received !== 0n);
|
|
33157
33234
|
hash = moved === void 0 ? null : moved.transactionHash;
|
|
33158
33235
|
}
|
|
@@ -34310,7 +34387,15 @@ var init_agent = __esm({
|
|
|
34310
34387
|
this.shield = new ShieldService(client, config, keys, this.buyer, this.sender);
|
|
34311
34388
|
this.creatorShield = new ShieldService(client, config, keys, this.creator, creatorSender);
|
|
34312
34389
|
this.unshield = new UnshieldService(client, config, keys, this.shield, (index) => this.privateVault(index));
|
|
34313
|
-
this.borro = new BorroService({
|
|
34390
|
+
this.borro = new BorroService({
|
|
34391
|
+
client,
|
|
34392
|
+
config,
|
|
34393
|
+
buyer: this.buyer,
|
|
34394
|
+
tokenVault: (token) => this.vaultFor(token),
|
|
34395
|
+
sender: this.sender,
|
|
34396
|
+
ownVaults: () => this.ownVaults(),
|
|
34397
|
+
logsClient: createPublicClient2({ chain: robinhoodChain, transport: http2(config.logsRpcUrl, { retryCount: 6, retryDelay: 2e3 }) })
|
|
34398
|
+
});
|
|
34314
34399
|
this.breaker = new BreakerService({ client, config, buyer: this.buyer, borro: this.borro, sender: this.sender, folder: keys.folder.folder("breaker") });
|
|
34315
34400
|
this.raeto = config.raetoUrl === null ? null : new RaetoService({ client, buyer: this.buyer, borro: this.borro, folder: keys.folder.folder("raeto"), apiUrl: config.raetoUrl });
|
|
34316
34401
|
if (config.swap === null) {
|
|
@@ -35021,10 +35106,11 @@ function registerTools(server, agent) {
|
|
|
35021
35106
|
);
|
|
35022
35107
|
tool(
|
|
35023
35108
|
"vault_lock",
|
|
35024
|
-
"The withdrawal lock of the vault (USDG) or of the agent's vault of a Borro stock. status: the lock, the daily limit left, the linked vault and the
|
|
35109
|
+
"The withdrawal lock of the vault (USDG) or of the agent's vault of a Borro stock. status: the lock, the daily limit left, the linked vault, the changes waiting, and the hashes the vault approves for EIP-1271 (approvals: each hash, from when it counts and whether that time has come; a hash can be a permit or a transfer authorization of the vault's funds; under the lock no flow of this server approves anything, so every hash listed then came from elsewhere and should go; without the lock the list also holds this server's own approvals, such as Ostrapad's, which look alike: vault_revoke_hash withdraws one, a guardian of a locked vault revokes it with guard_vault); with vault, the same for any Ostra vault (a guardian watching the vault it guards). set: turns the lock on or changes it (withdrawal: a wallet whose key is not on this device, or another seed's Ostra vault in the same token that is locked already; never one of this agent's vaults; delaySeconds 129600 to 1209600; dailyLimit in the vault's token): turning it on and tightening are at once, loosening waits the delay. off: turns it off after the delay. cancel: drops the changes still waiting.",
|
|
35025
35110
|
{
|
|
35026
35111
|
action: z.enum(["status", "set", "off", "cancel"]),
|
|
35027
35112
|
asset: borroAsset.optional().describe("USDG (default) or a Borro stock's ticker"),
|
|
35113
|
+
vault: address5.optional().describe("status only: another Ostra vault to read"),
|
|
35028
35114
|
withdrawal: address5.optional(),
|
|
35029
35115
|
delaySeconds: z.number().int().min(129600).max(1209600).optional(),
|
|
35030
35116
|
dailyLimit: units.optional(),
|
|
@@ -35032,7 +35118,8 @@ function registerTools(server, agent) {
|
|
|
35032
35118
|
},
|
|
35033
35119
|
async (a) => {
|
|
35034
35120
|
const asset = a.asset ?? "USDG";
|
|
35035
|
-
if (a.action
|
|
35121
|
+
if (a.vault !== void 0 && a.action !== "status") throw new RangeError("vault is for status only: set, off and cancel act on this agent's own vaults");
|
|
35122
|
+
if (a.action === "status") return agent.borro.lockStatus(asset, a.vault);
|
|
35036
35123
|
if (a.action === "cancel") return agent.borro.cancelPending(asset);
|
|
35037
35124
|
if (a.action === "off") return agent.borro.setLock(asset, "off", 0, "0");
|
|
35038
35125
|
if (a.withdrawal === void 0 || a.delaySeconds === void 0 || a.dailyLimit === void 0) throw new RangeError("set takes withdrawal, delaySeconds and dailyLimit");
|
|
@@ -35056,10 +35143,10 @@ function registerTools(server, agent) {
|
|
|
35056
35143
|
(a) => agent.borro.setLink(a.asset ?? "USDG", a.vault)
|
|
35057
35144
|
);
|
|
35058
35145
|
tool(
|
|
35059
|
-
"
|
|
35060
|
-
"
|
|
35061
|
-
{ hash: bytes323,
|
|
35062
|
-
(a) => agent.borro.
|
|
35146
|
+
"vault_revoke_hash",
|
|
35147
|
+
"Withdraws the EIP-1271 approval of a 32-byte hash by the vault (USDG) or by the agent's vault of a Borro stock (vault_lock status lists them); at once, under the lock too; lands as done when there is none. No tool approves a hash it is given: USDG takes the vault's EIP-1271 answer as a permit or a transfer authorization of its funds, so the vault only approves digests this server builds and checks itself (Raeto's login message, OstraBreaker's limits, Ostrapad's actions).",
|
|
35148
|
+
{ hash: bytes323, asset: borroAsset.optional().describe("USDG (default) or a Borro stock's ticker") },
|
|
35149
|
+
(a) => agent.borro.withdrawApproval(a.asset ?? "USDG", a.hash)
|
|
35063
35150
|
);
|
|
35064
35151
|
tool(
|
|
35065
35152
|
"guard_vault",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ostraagent/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Ostra Agent's MCP server (stdio): the post-quantum privacy vault for AI agents. One vault to pay, earn, work and hire on Ostrapad, and stay private on Robinhood Chain, with no ETH (the Ostra relayer sends its transactions, paid in USDG).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|