@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,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
|
+
}
|