@j0nnyboi/amman
Version:
A modern mandatory toolbelt to help test solana SDK libraries and apps on a locally running validator.
177 lines • 7.77 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleAccountCommand = void 0;
const amman_client_1 = require("@j0nnyboi/amman-client");
const web3_js_1 = require("@safecoin/web3.js");
const ansi_colors_1 = require("ansi-colors");
const assert_1 = require("assert");
// @ts-ignore no types available, but it's a simpler function
const buffer_hexdump_1 = __importDefault(require("buffer-hexdump"));
const format_1 = __importDefault(require("date-fns/format"));
const formatDistance_1 = __importDefault(require("date-fns/formatDistance"));
const text_table_1 = __importDefault(require("text-table"));
const state_1 = require("../../accounts/state");
const utils_1 = require("../utils");
async function handleAccountCommand(acc, includeTxs, save) {
if (acc == null)
return renderAllKnownAccounts(includeTxs);
const amman = (0, utils_1.cliAmmanInstance)();
const addresses = await (0, utils_1.resolveAccountAddresses)(amman, acc);
if (addresses.length === 0) {
throw new Error(`Account ${acc} could not be resolved to an address`);
}
if (save && addresses.length > 1) {
throw new Error(`Account ${acc} could not be resolved to exactly address and thus cannot be saved`);
}
const connection = new web3_js_1.Connection(amman_client_1.LOCALHOST, 'confirmed');
const rendereds = [];
let savedAccountPath;
for (const address of addresses) {
const pubkey = new web3_js_1.PublicKey(address);
const accountInfo = await connection.getAccountInfo(pubkey);
(0, assert_1.strict)(accountInfo != null, 'Account info should not be null');
if (save) {
savedAccountPath = await amman.ammanClient.requestSaveAccount(addresses[0]);
}
const len = accountInfo.data.length;
const sol = accountInfo.lamports / web3_js_1.LAMPORTS_PER_SAFE;
const accountStates = await tryResolveAccountStates(pubkey);
const rawData = accountStates == null || accountStates.length === 0
? `\n${(0, buffer_hexdump_1.default)(accountInfo.data)}`
: (0, ansi_colors_1.dim)(' (raw data omitted)');
const rendered = `
${(0, ansi_colors_1.bold)('Public Key')}: ${address}
${(0, ansi_colors_1.bold)('Balance ')}: ${sol} SOL
${(0, ansi_colors_1.bold)('Owner ')}: ${accountInfo.owner}
${(0, ansi_colors_1.bold)('Executable')}: ${accountInfo.executable}
${(0, ansi_colors_1.bold)('Rent Epoch')}: ${accountInfo.rentEpoch}
Length: ${len} (0x${len.toString(16)}) bytes${rawData}
${accountStates}
`;
rendereds.push(rendered);
}
let rendered = rendereds.join('\n==================================================================\n');
if (rendereds.length > 1) {
rendered +=
`\n${(0, ansi_colors_1.bold)('NOTE')}: found ${rendereds.length}` +
` accounts labeled '${acc}' and printed all of them above`;
}
amman.disconnect();
return { connection, rendered, savedAccountPath };
}
exports.handleAccountCommand = handleAccountCommand;
async function renderAllKnownAccounts(includeTxs) {
const amman = (0, utils_1.cliAmmanInstance)();
const accounts = await amman.addr.getRemoteLabelAddresses();
if (Object.keys(accounts).length === 0) {
const rendered = 'No labeled accounts found';
return { connection: undefined, rendered };
}
const rows = [];
for (const [address, label] of Object.entries(accounts)) {
if (!includeTxs && address.length > 44)
continue;
rows.push([label, (0, ansi_colors_1.dim)(address)]);
}
const rendered = (0, text_table_1.default)(rows);
amman.disconnect();
return { connection: undefined, rendered };
}
async function tryResolveAccountStates(pubkey) {
var _a, _b;
const amman = (0, utils_1.cliAmmanInstance)();
const states = await amman.ammanClient.fetchAccountStates(pubkey.toBase58());
if (states == null)
return;
let statesStr = '';
for (let i = 0; i < states.length; i++) {
const state = states[i];
const rows = [];
const printable = (0, state_1.printableAccount)(state.account);
for (const [key, value] of Object.entries(printable)) {
rows.push([key, (0, ansi_colors_1.dim)(value !== null && value !== void 0 ? value : 'null')]);
}
const tdelta = (0, formatDistance_1.default)(state.timestamp, Date.now(), {
includeSeconds: true,
addSuffix: true,
});
const ts = (0, format_1.default)(state.timestamp, 'HH:mm:ss:SSS');
const time = (0, ansi_colors_1.dim)(`${tdelta} at ${ts} in slot ${state.slot}`);
const diffRows = (_b = (_a = state.accountDiff) === null || _a === void 0 ? void 0 : _a.map((x) => {
if (x.kind === 'E') {
return [x.path, x.lhs, x.rhs];
}
else if (x.kind === 'N') {
return [x.path, '+', x.rhs];
}
else if (x.kind === 'D') {
return [x.path, '-', x.lhs];
}
else {
return [x.path, 'item at idx changed', x.index.toString()];
}
}).map(([p, c, v]) => {
const sp = p == null
? ''
: Array.isArray(p)
? p.join('.')
: typeof p === 'string'
? p
: JSON.stringify(p, null, 2);
const sc = typeof c === 'string' ? c : JSON.stringify(c);
const sv = typeof v === 'string' ? v : JSON.stringify(v);
return [sp, (0, ansi_colors_1.dim)(sc), (0, ansi_colors_1.dim)(sv)];
})) !== null && _b !== void 0 ? _b : [];
const diffRendered = diffRows.length > 0 ? (0, text_table_1.default)(diffRows) : undefined;
const n = (i + 1).toString().padStart(2, '0');
statesStr +=
`\n${(0, ansi_colors_1.bold)('Account State')} ${n} ${time}` +
`\n${(0, ansi_colors_1.bold)('----------------')}` +
`\n${(0, text_table_1.default)(rows)}\n`;
if (diffRendered != null) {
// prettier-ignore
statesStr +=
`\n${(0, ansi_colors_1.bold)('Diffs')}` +
`\n${(0, ansi_colors_1.bold)('-----')}` +
`\n${diffRendered}\n`;
}
if (state.rendered != null) {
// prettier-ignore
statesStr +=
`\n${(0, ansi_colors_1.bold)('Rendered')}` +
`\n${(0, ansi_colors_1.bold)('--------')}`;
if (state.renderedDiff != null && state.renderedDiff.length > 0) {
statesStr += `\n${renderDiff(state.renderedDiff)}`;
}
else {
statesStr += `\n${state.rendered}`;
}
}
}
return statesStr;
}
function renderDiff(renderedDiff) {
if (renderedDiff == null || renderedDiff.length === 0)
return;
const before = renderedDiff
.map((x) => {
if (x.added)
return '';
const fn = x.removed ? ansi_colors_1.blueBright : undefined;
return fn == null ? x.value : fn(x.value);
})
.join('');
const after = renderedDiff
.map((x) => {
if (x.removed)
return '';
const fn = x.added ? ansi_colors_1.green : undefined;
return fn == null ? x.value : fn(x.value);
})
.join('');
return `\n${(0, ansi_colors_1.dim)('# Before')}\n${before}\n${(0, ansi_colors_1.dim)('# After')}\n${after}`;
}
//# sourceMappingURL=account.js.map