@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.
Files changed (44) hide show
  1. package/README.md +272 -0
  2. package/dist/bin.d.ts +2 -0
  3. package/dist/bin.js +200 -0
  4. package/dist/client.d.ts +12 -0
  5. package/dist/client.js +18 -0
  6. package/dist/commands/accept.d.ts +11 -0
  7. package/dist/commands/accept.js +112 -0
  8. package/dist/commands/assets.d.ts +9 -0
  9. package/dist/commands/assets.js +80 -0
  10. package/dist/commands/balance.d.ts +9 -0
  11. package/dist/commands/balance.js +74 -0
  12. package/dist/commands/deposit.d.ts +7 -0
  13. package/dist/commands/deposit.js +67 -0
  14. package/dist/commands/exercise.d.ts +14 -0
  15. package/dist/commands/exercise.js +88 -0
  16. package/dist/commands/key.d.ts +15 -0
  17. package/dist/commands/key.js +98 -0
  18. package/dist/commands/mm-webhook.d.ts +36 -0
  19. package/dist/commands/mm-webhook.js +152 -0
  20. package/dist/commands/mm.d.ts +37 -0
  21. package/dist/commands/mm.js +345 -0
  22. package/dist/commands/offer.d.ts +29 -0
  23. package/dist/commands/offer.js +149 -0
  24. package/dist/commands/option.d.ts +28 -0
  25. package/dist/commands/option.js +138 -0
  26. package/dist/commands/quote-webhook.d.ts +36 -0
  27. package/dist/commands/quote-webhook.js +152 -0
  28. package/dist/commands/quote.d.ts +37 -0
  29. package/dist/commands/quote.js +345 -0
  30. package/dist/commands/redeem.d.ts +14 -0
  31. package/dist/commands/redeem.js +88 -0
  32. package/dist/commands/rfq-view.d.ts +25 -0
  33. package/dist/commands/rfq-view.js +172 -0
  34. package/dist/commands/rfq.d.ts +4 -0
  35. package/dist/commands/rfq.js +280 -0
  36. package/dist/commands/shared.d.ts +81 -0
  37. package/dist/commands/shared.js +296 -0
  38. package/dist/commands/withdraw.d.ts +7 -0
  39. package/dist/commands/withdraw.js +67 -0
  40. package/dist/config.d.ts +53 -0
  41. package/dist/config.js +58 -0
  42. package/dist/index.d.ts +18 -0
  43. package/dist/index.js +50 -0
  44. package/package.json +38 -0
@@ -0,0 +1,80 @@
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.assetsList = assetsList;
40
+ const p = __importStar(require("@clack/prompts"));
41
+ const picocolors_1 = __importDefault(require("picocolors"));
42
+ const client_1 = require("../client");
43
+ const config_1 = require("../config");
44
+ const shared_1 = require("./shared");
45
+ /**
46
+ * `overcast assets` — list the backend's asset allowlist via the off-chain
47
+ * {@link OvercastView}. This is the set of assets the protocol will accept on an
48
+ * RFQ / quote / offer, and the metadata every amount elsewhere is formatted
49
+ * against. Read-only: no wallet required.
50
+ */
51
+ async function assetsList(opts) {
52
+ const config = (0, config_1.resolveConfig)(opts, { keypairOptional: true });
53
+ const app = await (0, client_1.createClient)(config);
54
+ p.intro(picocolors_1.default.cyan("Overcast assets"));
55
+ const spinner = p.spinner();
56
+ spinner.start("Loading asset allowlist");
57
+ try {
58
+ const assets = await app.api.listAssets();
59
+ spinner.stop(`${assets.length} asset(s)`);
60
+ if (assets.length === 0) {
61
+ p.outro(picocolors_1.default.yellow("Backend has no supported assets."));
62
+ return;
63
+ }
64
+ p.note(assets
65
+ .map((a) => {
66
+ const symbol = picocolors_1.default.bold((a.symbol ?? "?").padEnd(6));
67
+ const name = a.name ? ` ${a.name}` : "";
68
+ const price = a.lastKnownPriceUsd != null
69
+ ? picocolors_1.default.dim(` ~$${a.lastKnownPriceUsd}`)
70
+ : "";
71
+ return `${symbol} ${(0, shared_1.short)(a.address)}${name}${picocolors_1.default.dim(` · ${a.decimals ?? 0}dp`)}${price}`;
72
+ })
73
+ .join("\n"), "Allowlist");
74
+ p.outro(picocolors_1.default.green("Done."));
75
+ }
76
+ catch (err) {
77
+ spinner.stop(picocolors_1.default.red(`Load failed: ${err.message}`));
78
+ throw err;
79
+ }
80
+ }
@@ -0,0 +1,9 @@
1
+ import { GlobalFlags } from "../config";
2
+ export interface BalanceOptions extends GlobalFlags {
3
+ /** Asset mint to check; prompts from the allowlist when omitted. */
4
+ mint?: string;
5
+ /** Vault owner to inspect; defaults to the wallet. */
6
+ user?: string;
7
+ }
8
+ /** `overcast balance` — show a user's protocol escrow vault balance for an asset. */
9
+ export declare function balance(opts: BalanceOptions): Promise<void>;
@@ -0,0 +1,74 @@
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.balance = balance;
40
+ const p = __importStar(require("@clack/prompts"));
41
+ const core_1 = require("@overcast-xyz/core");
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
+ /** `overcast balance` — show a user's protocol escrow vault balance for an asset. */
47
+ async function balance(opts) {
48
+ const config = (0, config_1.resolveConfig)(opts, { keypairOptional: true });
49
+ if (opts.user && (0, shared_1.validateAddress)(opts.user)) {
50
+ throw new Error(`invalid --user address: ${opts.user}`);
51
+ }
52
+ // Whose vault to read: an explicit --user, else the wallet's own — but only
53
+ // when a keypair was supplied. Resolve this up front so a misuse fails fast,
54
+ // before any network round-trip.
55
+ if (!opts.user && !config.privateKey) {
56
+ throw new Error("pass --user <address>, or a --keypair to read your own vault");
57
+ }
58
+ const app = await (0, client_1.createClient)(config);
59
+ const registry = await (0, shared_1.loadRegistry)(app.api);
60
+ const user = opts.user ?? app.publicKey;
61
+ const asset = opts.mint
62
+ ? registry.getOrDefault(opts.mint)
63
+ : await (0, shared_1.pickAsset)(registry, "Asset to check");
64
+ const spinner = p.spinner();
65
+ spinner.start(`Reading vault balance for ${asset.symbol ?? asset.address}`);
66
+ try {
67
+ const amount = await app.chain.balance(user, asset);
68
+ spinner.stop(`${picocolors_1.default.bold((0, core_1.formatAssetAmount)(amount, asset))} ${picocolors_1.default.dim(`(vault of ${user})`)}`);
69
+ }
70
+ catch (err) {
71
+ spinner.stop(picocolors_1.default.red(`Balance lookup failed: ${err.message}`));
72
+ throw err;
73
+ }
74
+ }
@@ -0,0 +1,7 @@
1
+ import { GlobalFlags } from "../config";
2
+ export interface DepositOptions extends GlobalFlags {
3
+ mint?: string;
4
+ amount?: string;
5
+ }
6
+ /** `overcast deposit` — credit the wallet's protocol escrow vault. */
7
+ export declare function deposit(opts: DepositOptions): Promise<void>;
@@ -0,0 +1,67 @@
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.deposit = deposit;
40
+ const p = __importStar(require("@clack/prompts"));
41
+ const picocolors_1 = __importDefault(require("picocolors"));
42
+ const client_1 = require("../client");
43
+ const config_1 = require("../config");
44
+ const shared_1 = require("./shared");
45
+ /** `overcast deposit` — credit the wallet's protocol escrow vault. */
46
+ async function deposit(opts) {
47
+ const config = (0, config_1.resolveConfig)(opts);
48
+ const app = await (0, client_1.createClient)(config);
49
+ const mint = opts.mint ?? (await (0, shared_1.promptMint)("Mint to deposit"));
50
+ const amount = opts.amount
51
+ ? BigInt(opts.amount)
52
+ : await (0, shared_1.promptAmount)("Amount to deposit (native units)");
53
+ const spinner = p.spinner();
54
+ spinner.start(`Depositing ${amount} of ${mint}`);
55
+ try {
56
+ const { hash } = await app.chain.deposit({
57
+ depositor: app.publicKey,
58
+ mint,
59
+ amount,
60
+ });
61
+ spinner.stop(picocolors_1.default.green(`Deposited. tx ${picocolors_1.default.bold(hash)}`));
62
+ }
63
+ catch (err) {
64
+ spinner.stop(picocolors_1.default.red(`Deposit failed: ${err.message}`));
65
+ throw err;
66
+ }
67
+ }
@@ -0,0 +1,14 @@
1
+ import { GlobalFlags } from "../config";
2
+ export interface ExerciseOptions extends GlobalFlags {
3
+ collateralOffer?: string;
4
+ settlementOffer?: string;
5
+ /** Native-unit amount of exercise claims to burn. */
6
+ amount?: string;
7
+ }
8
+ /**
9
+ * `overcast exercise` — exercise (burn exercise-claims of) an option the wallet
10
+ * holds, swapping settlement for the underlying collateral. The wallet must be
11
+ * the option's taker; we surface the wallet's claim balance and the terms
12
+ * before submitting.
13
+ */
14
+ export declare function exercise(opts: ExerciseOptions): Promise<void>;
@@ -0,0 +1,88 @@
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.exercise = exercise;
40
+ const p = __importStar(require("@clack/prompts"));
41
+ const picocolors_1 = __importDefault(require("picocolors"));
42
+ const client_1 = require("../client");
43
+ const config_1 = require("../config");
44
+ const shared_1 = require("./shared");
45
+ /**
46
+ * `overcast exercise` — exercise (burn exercise-claims of) an option the wallet
47
+ * holds, swapping settlement for the underlying collateral. The wallet must be
48
+ * the option's taker; we surface the wallet's claim balance and the terms
49
+ * before submitting.
50
+ */
51
+ async function exercise(opts) {
52
+ const config = (0, config_1.resolveConfig)(opts);
53
+ const app = await (0, client_1.createClient)(config);
54
+ const registry = await (0, shared_1.loadRegistry)(app.api);
55
+ p.intro(picocolors_1.default.cyan("Overcast exercise"));
56
+ const option = await (0, shared_1.resolveOption)(app.chain, opts);
57
+ if (app.publicKey !== option.taker) {
58
+ p.log.warn(`This wallet is not the option taker (${(0, shared_1.short)(option.taker)}); the exercise will fail.`);
59
+ }
60
+ const claims = await app.chain.exerciseClaims(option, app.publicKey);
61
+ p.note([
62
+ (0, shared_1.describeOptionDetails)(option.details, registry),
63
+ "",
64
+ `Your exercise claims ${picocolors_1.default.bold(claims.toString())}`,
65
+ ].join("\n"), `Option ${(0, shared_1.short)(option.id)}`);
66
+ if (claims === 0n && opts.amount == null) {
67
+ p.outro(picocolors_1.default.yellow("You hold no exercise claims for this option."));
68
+ return;
69
+ }
70
+ const amount = opts.amount != null
71
+ ? BigInt(opts.amount)
72
+ : await (0, shared_1.promptAmountUpTo)("Amount to exercise", claims);
73
+ if (!(await (0, shared_1.confirm)(`Exercise ${amount} claim(s)?`))) {
74
+ p.outro(picocolors_1.default.yellow("Cancelled."));
75
+ return;
76
+ }
77
+ const spinner = p.spinner();
78
+ spinner.start(`Exercising ${amount} claim(s)`);
79
+ try {
80
+ const { hash } = await app.chain.exerciseOption(option, amount);
81
+ spinner.stop(picocolors_1.default.green(`Exercised. tx ${picocolors_1.default.bold(hash)}`));
82
+ p.outro(picocolors_1.default.green("Done."));
83
+ }
84
+ catch (err) {
85
+ spinner.stop(picocolors_1.default.red(`Exercise failed: ${err.message}`));
86
+ throw err;
87
+ }
88
+ }
@@ -0,0 +1,15 @@
1
+ import { GlobalFlags } from "../config";
2
+ export interface KeyOptions extends GlobalFlags {
3
+ key?: string;
4
+ }
5
+ /**
6
+ * `overcast key add` — authorize a key to sign operations on your wallet's
7
+ * behalf. Registers a signing-key record owned by your wallet so an operator can
8
+ * later submit your delegable calls with an operation signed by `key`.
9
+ */
10
+ export declare function keyAdd(opts: KeyOptions): Promise<void>;
11
+ /**
12
+ * `overcast key remove` — revoke a previously authorized signing key, closing
13
+ * its record (rent refunded). Operations signed with `key` are rejected after.
14
+ */
15
+ export declare function keyRemove(opts: KeyOptions): Promise<void>;
@@ -0,0 +1,98 @@
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.keyAdd = keyAdd;
40
+ exports.keyRemove = keyRemove;
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
+ * Resolve the signing key from the `--key` flag (or a positional arg surfaced as
48
+ * `opts.key`), prompting with base58 validation when absent. Throws on a
49
+ * malformed flag value so a typo fails fast instead of hitting the chain.
50
+ */
51
+ async function resolveKey(opts, message) {
52
+ if (opts.key) {
53
+ const trimmed = opts.key.trim();
54
+ if ((0, shared_1.validateAddress)(trimmed))
55
+ throw new Error(`invalid key: ${opts.key}`);
56
+ return trimmed;
57
+ }
58
+ return (0, shared_1.promptId)(message);
59
+ }
60
+ /**
61
+ * `overcast key add` — authorize a key to sign operations on your wallet's
62
+ * behalf. Registers a signing-key record owned by your wallet so an operator can
63
+ * later submit your delegable calls with an operation signed by `key`.
64
+ */
65
+ async function keyAdd(opts) {
66
+ const config = (0, config_1.resolveConfig)(opts);
67
+ const app = await (0, client_1.createClient)(config);
68
+ const key = await resolveKey(opts, "Public key to authorize");
69
+ const spinner = p.spinner();
70
+ spinner.start(`Authorizing ${key}`);
71
+ try {
72
+ const { hash } = await app.chain.addAuthorizedKey(key);
73
+ spinner.stop(picocolors_1.default.green(`Authorized. tx ${picocolors_1.default.bold(hash)}`));
74
+ }
75
+ catch (err) {
76
+ spinner.stop(picocolors_1.default.red(`Authorize failed: ${err.message}`));
77
+ throw err;
78
+ }
79
+ }
80
+ /**
81
+ * `overcast key remove` — revoke a previously authorized signing key, closing
82
+ * its record (rent refunded). Operations signed with `key` are rejected after.
83
+ */
84
+ async function keyRemove(opts) {
85
+ const config = (0, config_1.resolveConfig)(opts);
86
+ const app = await (0, client_1.createClient)(config);
87
+ const key = await resolveKey(opts, "Public key to revoke");
88
+ const spinner = p.spinner();
89
+ spinner.start(`Revoking ${key}`);
90
+ try {
91
+ const { hash } = await app.chain.removeAuthorizedKey(key);
92
+ spinner.stop(picocolors_1.default.green(`Revoked. tx ${picocolors_1.default.bold(hash)}`));
93
+ }
94
+ catch (err) {
95
+ spinner.stop(picocolors_1.default.red(`Revoke failed: ${err.message}`));
96
+ throw err;
97
+ }
98
+ }
@@ -0,0 +1,36 @@
1
+ import type { QuoteAcceptedPayload, QuoteNewPayload } from "@overcast/core";
2
+ import type { QuotePricer } from "./mm";
3
+ /** Connection settings for the market maker'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/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 MM.
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 `./mm` is erased at runtime, so logging through the same
144
+ // `@clack/prompts` channel the MM command uses introduces no import cycle and
145
+ // keeps webhook warnings visually consistent with the rest of the MM 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
+ }