@overcast-xyz/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +272 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +200 -0
- package/dist/client.d.ts +12 -0
- package/dist/client.js +18 -0
- package/dist/commands/accept.d.ts +11 -0
- package/dist/commands/accept.js +112 -0
- package/dist/commands/assets.d.ts +9 -0
- package/dist/commands/assets.js +80 -0
- package/dist/commands/balance.d.ts +9 -0
- package/dist/commands/balance.js +74 -0
- package/dist/commands/deposit.d.ts +7 -0
- package/dist/commands/deposit.js +67 -0
- package/dist/commands/exercise.d.ts +14 -0
- package/dist/commands/exercise.js +88 -0
- package/dist/commands/key.d.ts +15 -0
- package/dist/commands/key.js +98 -0
- package/dist/commands/mm-webhook.d.ts +36 -0
- package/dist/commands/mm-webhook.js +152 -0
- package/dist/commands/mm.d.ts +37 -0
- package/dist/commands/mm.js +345 -0
- package/dist/commands/offer.d.ts +29 -0
- package/dist/commands/offer.js +149 -0
- package/dist/commands/option.d.ts +28 -0
- package/dist/commands/option.js +138 -0
- package/dist/commands/quote-webhook.d.ts +36 -0
- package/dist/commands/quote-webhook.js +152 -0
- package/dist/commands/quote.d.ts +37 -0
- package/dist/commands/quote.js +345 -0
- package/dist/commands/redeem.d.ts +14 -0
- package/dist/commands/redeem.js +88 -0
- package/dist/commands/rfq-view.d.ts +25 -0
- package/dist/commands/rfq-view.js +172 -0
- package/dist/commands/rfq.d.ts +4 -0
- package/dist/commands/rfq.js +280 -0
- package/dist/commands/shared.d.ts +81 -0
- package/dist/commands/shared.js +296 -0
- package/dist/commands/withdraw.d.ts +7 -0
- package/dist/commands/withdraw.js +67 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.js +58 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +50 -0
- package/package.json +38 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.optionShow = optionShow;
|
|
40
|
+
exports.optionList = optionList;
|
|
41
|
+
const p = __importStar(require("@clack/prompts"));
|
|
42
|
+
const picocolors_1 = __importDefault(require("picocolors"));
|
|
43
|
+
const client_1 = require("../client");
|
|
44
|
+
const config_1 = require("../config");
|
|
45
|
+
const shared_1 = require("./shared");
|
|
46
|
+
/**
|
|
47
|
+
* `overcast option show` — resolve a market option from its
|
|
48
|
+
* `(collateralOffer, settlementOffer)` id pair and print its terms alongside
|
|
49
|
+
* the live claim state: the outstanding exercise / redeem claim supplies and,
|
|
50
|
+
* when a wallet is supplied, that wallet's own holdings of each.
|
|
51
|
+
*/
|
|
52
|
+
async function optionShow(opts) {
|
|
53
|
+
const config = (0, config_1.resolveConfig)(opts, { keypairOptional: true });
|
|
54
|
+
const app = await (0, client_1.createClient)(config);
|
|
55
|
+
const registry = await (0, shared_1.loadRegistry)(app.api);
|
|
56
|
+
// The "yours" rows / role need a wallet; without one we still show supplies.
|
|
57
|
+
const wallet = config.privateKey ? app.publicKey : null;
|
|
58
|
+
p.intro(picocolors_1.default.cyan("Overcast option"));
|
|
59
|
+
const option = await (0, shared_1.resolveOption)(app.chain, opts);
|
|
60
|
+
const spinner = p.spinner();
|
|
61
|
+
spinner.start("Reading claim state");
|
|
62
|
+
let exerciseSupply;
|
|
63
|
+
let redeemSupply;
|
|
64
|
+
let myExercise = null;
|
|
65
|
+
let myRedeem = null;
|
|
66
|
+
try {
|
|
67
|
+
[exerciseSupply, redeemSupply, myExercise, myRedeem] = await Promise.all([
|
|
68
|
+
app.chain.exerciseClaimsSupply(option),
|
|
69
|
+
app.chain.redeemClaimsSupply(option),
|
|
70
|
+
wallet ? app.chain.exerciseClaims(option, wallet) : Promise.resolve(null),
|
|
71
|
+
wallet ? app.chain.redeemClaims(option, wallet) : Promise.resolve(null),
|
|
72
|
+
]);
|
|
73
|
+
spinner.stop("Claim state read.");
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
spinner.stop(picocolors_1.default.red(`Read failed: ${err.message}`));
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
p.note((0, shared_1.describeOptionDetails)(option.details, registry), `Option ${(0, shared_1.short)(option.id)}`);
|
|
80
|
+
// Flag the wallet's role (when known) so the "yours" rows are unambiguous.
|
|
81
|
+
const role = wallet === option.taker
|
|
82
|
+
? picocolors_1.default.dim(" (you are the taker)")
|
|
83
|
+
: wallet === option.maker
|
|
84
|
+
? picocolors_1.default.dim(" (you are the maker)")
|
|
85
|
+
: "";
|
|
86
|
+
// Only append "· yours N" when a wallet was supplied to read it.
|
|
87
|
+
const yours = (mine) => mine === null ? "" : ` · yours ${picocolors_1.default.bold(mine.toString())}`;
|
|
88
|
+
p.note([
|
|
89
|
+
`Maker ${(0, shared_1.short)(option.maker)}`,
|
|
90
|
+
`Taker ${(0, shared_1.short)(option.taker)}${role}`,
|
|
91
|
+
"",
|
|
92
|
+
`Exercise claims outstanding ${picocolors_1.default.bold(exerciseSupply.toString())}${yours(myExercise)}`,
|
|
93
|
+
`Redeem claims outstanding ${picocolors_1.default.bold(redeemSupply.toString())}${yours(myRedeem)}`,
|
|
94
|
+
].join("\n"), "Claims");
|
|
95
|
+
p.outro(picocolors_1.default.green("Done."));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* `overcast option list` — browse the backend's curated market options via the
|
|
99
|
+
* off-chain {@link OvercastView}. Read-only: no wallet required. Filters map
|
|
100
|
+
* straight onto the view's {@link OptionFilter}; results are newest-first.
|
|
101
|
+
*/
|
|
102
|
+
async function optionList(opts) {
|
|
103
|
+
const config = (0, config_1.resolveConfig)(opts, { keypairOptional: true });
|
|
104
|
+
const app = await (0, client_1.createClient)(config);
|
|
105
|
+
const filter = {
|
|
106
|
+
maker: (0, shared_1.optionalAddress)("--maker", opts.maker),
|
|
107
|
+
taker: (0, shared_1.optionalAddress)("--taker", opts.taker),
|
|
108
|
+
asset: (0, shared_1.optionalAddress)("--asset", opts.asset),
|
|
109
|
+
};
|
|
110
|
+
const limit = (0, shared_1.parseLimit)(opts.limit);
|
|
111
|
+
p.intro(picocolors_1.default.cyan("Overcast options"));
|
|
112
|
+
const spinner = p.spinner();
|
|
113
|
+
spinner.start("Loading options");
|
|
114
|
+
try {
|
|
115
|
+
const page = await app.api.listOptions({
|
|
116
|
+
filter,
|
|
117
|
+
page: limit ? { limit } : undefined,
|
|
118
|
+
});
|
|
119
|
+
spinner.stop(`${page.items.length} option(s)`);
|
|
120
|
+
if (page.items.length === 0) {
|
|
121
|
+
p.outro(picocolors_1.default.yellow("No options match."));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
for (const option of page.items) {
|
|
125
|
+
// Options are identified by their (collateral, settlement) offer pair —
|
|
126
|
+
// there is no single option id — so both are shown for `option show`.
|
|
127
|
+
p.log.message([
|
|
128
|
+
(0, shared_1.summarizeCuratedDetails)(option.details),
|
|
129
|
+
picocolors_1.default.dim(`offers ${(0, shared_1.short)(option.collateralOffer)} / ${(0, shared_1.short)(option.settlementOffer)} · maker ${(0, shared_1.short)(option.maker)} · taker ${(0, shared_1.short)(option.taker)}`),
|
|
130
|
+
].join("\n"));
|
|
131
|
+
}
|
|
132
|
+
p.outro(picocolors_1.default.green(`${page.total ?? page.items.length} total.`));
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
spinner.stop(picocolors_1.default.red(`List failed: ${err.message}`));
|
|
136
|
+
throw err;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { QuoteAcceptedPayload, QuoteNewPayload } from "@overcast-xyz/core";
|
|
2
|
+
import type { QuotePricer } from "./quote";
|
|
3
|
+
/** Connection settings for the quoter's webhook endpoint. */
|
|
4
|
+
export interface WebhookConfig {
|
|
5
|
+
/** The developer's local endpoint; every event is POSTed here. */
|
|
6
|
+
url: string;
|
|
7
|
+
/** Per-request timeout. RFQs are time-boxed, so a slow endpoint is skipped. */
|
|
8
|
+
timeoutMs: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The lifecycle events we forward to the webhook. `newRfq` is the only
|
|
12
|
+
* *actionable* one today (its reply drives a quote); the rest are fire-and-forget
|
|
13
|
+
* notifications, giving the endpoint full lifecycle visibility.
|
|
14
|
+
*/
|
|
15
|
+
export type WebhookEventType = "newRfq" | "newQuote" | "quoteAccepted" | "rfqCancelled" | "rfqExpired" | "error";
|
|
16
|
+
/**
|
|
17
|
+
* A {@link QuotePricer} that delegates pricing to the configured webhook: it
|
|
18
|
+
* POSTs the `newRfq` envelope and maps the reply to a {@link Premium}, or `null`
|
|
19
|
+
* to skip (on an explicit skip, a non-2xx, a timeout, or a malformed reply — the
|
|
20
|
+
* same "skip rather than quote on bad data" philosophy the built-in pricer uses).
|
|
21
|
+
*
|
|
22
|
+
* The CLI stays authoritative on the option terms — the endpoint only supplies
|
|
23
|
+
* the premium, which `completeOptionDetails` folds into the RFQ's legs — so a
|
|
24
|
+
* misbehaving endpoint can't tamper with the rest of the option.
|
|
25
|
+
*/
|
|
26
|
+
export declare function webhookPricer(cfg: WebhookConfig, maker: string): QuotePricer;
|
|
27
|
+
/**
|
|
28
|
+
* Fire-and-forget notify the webhook of a non-actionable lifecycle event. Errors
|
|
29
|
+
* are swallowed (logged) so a flaky endpoint never breaks the socket handlers.
|
|
30
|
+
*/
|
|
31
|
+
export declare function postEvent(cfg: WebhookConfig, type: Exclude<WebhookEventType, "newRfq">, data: QuoteNewPayload | QuoteAcceptedPayload | {
|
|
32
|
+
rfqId: string;
|
|
33
|
+
} | {
|
|
34
|
+
code: string;
|
|
35
|
+
message: string;
|
|
36
|
+
}, maker: string): void;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.webhookPricer = webhookPricer;
|
|
37
|
+
exports.postEvent = postEvent;
|
|
38
|
+
const p = __importStar(require("@clack/prompts"));
|
|
39
|
+
const core_1 = require("@overcast-xyz/core");
|
|
40
|
+
/**
|
|
41
|
+
* A {@link QuotePricer} that delegates pricing to the configured webhook: it
|
|
42
|
+
* POSTs the `newRfq` envelope and maps the reply to a {@link Premium}, or `null`
|
|
43
|
+
* to skip (on an explicit skip, a non-2xx, a timeout, or a malformed reply — the
|
|
44
|
+
* same "skip rather than quote on bad data" philosophy the built-in pricer uses).
|
|
45
|
+
*
|
|
46
|
+
* The CLI stays authoritative on the option terms — the endpoint only supplies
|
|
47
|
+
* the premium, which `completeOptionDetails` folds into the RFQ's legs — so a
|
|
48
|
+
* misbehaving endpoint can't tamper with the rest of the option.
|
|
49
|
+
*/
|
|
50
|
+
function webhookPricer(cfg, maker) {
|
|
51
|
+
return async (rfq) => {
|
|
52
|
+
const res = await post(cfg, "newRfq", rfq, maker);
|
|
53
|
+
if (!res)
|
|
54
|
+
return null; // network error / timeout / non-2xx — already logged
|
|
55
|
+
if (res.status === 204)
|
|
56
|
+
return null; // no content → skip
|
|
57
|
+
let decision;
|
|
58
|
+
try {
|
|
59
|
+
decision = (await res.json());
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
warn(`webhook returned a non-JSON reply for RFQ ${short(rfq.rfqId)}`);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (decision.action !== "quote") {
|
|
66
|
+
if (decision.action === "skip" && decision.reason) {
|
|
67
|
+
warn(`webhook skipped RFQ ${short(rfq.rfqId)}: ${decision.reason}`);
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const { premiumAsset, premiumAmount } = decision.premium ?? {};
|
|
72
|
+
if (!premiumAsset || premiumAmount == null) {
|
|
73
|
+
warn(`webhook quote for RFQ ${short(rfq.rfqId)} is missing premium fields`);
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
return { premiumAsset, premiumAmount: (0, core_1.amountFromWire)(premiumAmount) };
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
warn(`webhook quote for RFQ ${short(rfq.rfqId)} has a malformed premiumAmount "${premiumAmount}"`);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Fire-and-forget notify the webhook of a non-actionable lifecycle event. Errors
|
|
87
|
+
* are swallowed (logged) so a flaky endpoint never breaks the socket handlers.
|
|
88
|
+
*/
|
|
89
|
+
function postEvent(cfg, type, data, maker) {
|
|
90
|
+
void post(cfg, type, data, maker);
|
|
91
|
+
}
|
|
92
|
+
/* -------------------------------------------------------------------------- */
|
|
93
|
+
/* transport */
|
|
94
|
+
/* -------------------------------------------------------------------------- */
|
|
95
|
+
/**
|
|
96
|
+
* POST an event envelope to the webhook, returning the {@link Response} on a 2xx
|
|
97
|
+
* or `null` on any failure (network error, timeout, or non-2xx status), logging
|
|
98
|
+
* the reason. Uses `AbortController` so a slow endpoint can't stall the quoter.
|
|
99
|
+
*/
|
|
100
|
+
async function post(cfg, type, data, maker) {
|
|
101
|
+
const envelope = {
|
|
102
|
+
type,
|
|
103
|
+
timestamp: Date.now(),
|
|
104
|
+
maker,
|
|
105
|
+
data,
|
|
106
|
+
};
|
|
107
|
+
const body = JSON.stringify(envelope);
|
|
108
|
+
const headers = {
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
"X-Overcast-Event": type,
|
|
111
|
+
"X-Overcast-Timestamp": String(envelope.timestamp),
|
|
112
|
+
};
|
|
113
|
+
const controller = new AbortController();
|
|
114
|
+
const timer = setTimeout(() => controller.abort(), cfg.timeoutMs);
|
|
115
|
+
try {
|
|
116
|
+
const res = await fetch(cfg.url, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers,
|
|
119
|
+
body,
|
|
120
|
+
signal: controller.signal,
|
|
121
|
+
});
|
|
122
|
+
if (!res.ok) {
|
|
123
|
+
warn(`webhook returned HTTP ${res.status} for ${type}`);
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
return res;
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
const reason = err?.name === "AbortError"
|
|
130
|
+
? `timed out after ${cfg.timeoutMs}ms`
|
|
131
|
+
: err.message;
|
|
132
|
+
warn(`webhook POST (${type}) failed: ${reason}`);
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/* -------------------------------------------------------------------------- */
|
|
140
|
+
/* logging */
|
|
141
|
+
/* -------------------------------------------------------------------------- */
|
|
142
|
+
//
|
|
143
|
+
// The `import type` from `./quote` is erased at runtime, so logging through the
|
|
144
|
+
// same `@clack/prompts` channel the quote command uses introduces no import cycle
|
|
145
|
+
// and keeps webhook warnings visually consistent with the rest of the quote output.
|
|
146
|
+
function warn(message) {
|
|
147
|
+
p.log.warn(message);
|
|
148
|
+
}
|
|
149
|
+
/** Shorten a base58 id for log lines. */
|
|
150
|
+
function short(id) {
|
|
151
|
+
return id.length <= 12 ? id : `${id.slice(0, 6)}…${id.slice(-4)}`;
|
|
152
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { NewRfqPayload } from "@overcast-xyz/core";
|
|
2
|
+
import { GlobalFlags } from "../config";
|
|
3
|
+
/** An RFQ quoter's priced premium for an RFQ: asset address + native amount. */
|
|
4
|
+
export interface Premium {
|
|
5
|
+
premiumAsset: string;
|
|
6
|
+
premiumAmount: bigint;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Prices an incoming RFQ. Returns the premium to quote, or `null` to skip the
|
|
10
|
+
* RFQ. May be async so pricers can consult external data (e.g. a spot oracle).
|
|
11
|
+
*/
|
|
12
|
+
export type QuotePricer = (rfq: NewRfqPayload) => Promise<Premium | null>;
|
|
13
|
+
export interface QuoteOptions extends GlobalFlags {
|
|
14
|
+
/** Quoter edge added on top of the Black-Scholes fair value (fraction). */
|
|
15
|
+
spread?: string;
|
|
16
|
+
/** Annualized implied volatility, e.g. `0.8` for 80%. */
|
|
17
|
+
vol?: string;
|
|
18
|
+
/** Annualized risk-free rate, e.g. `0.05` for 5%. */
|
|
19
|
+
rate?: string;
|
|
20
|
+
/** Endpoint each RFQ event is POSTed to; its reply drives the quote. */
|
|
21
|
+
webhookUrl?: string;
|
|
22
|
+
/** Per-event webhook timeout, in milliseconds. */
|
|
23
|
+
webhookTimeout?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* `overcast quote` — run an RFQ quoter that auto-quotes every incoming RFQ
|
|
27
|
+
* using a Black-Scholes price.
|
|
28
|
+
*
|
|
29
|
+
* A cash-secured put and a covered call are the same instrument — an option to
|
|
30
|
+
* swap `settlementAmount` of one asset for `collateralAmount` of the other —
|
|
31
|
+
* differing only in which leg is collateral. We identify the stablecoin (cash)
|
|
32
|
+
* leg and the volatile (underlying) leg, then price:
|
|
33
|
+
* - settlement is cash → collateral is the underlying → **covered call**
|
|
34
|
+
* - collateral is cash → settlement is the underlying → **cash-secured put**
|
|
35
|
+
* See {@link blackScholesPricer}.
|
|
36
|
+
*/
|
|
37
|
+
export declare function runQuoter(opts: QuoteOptions): Promise<void>;
|