@honeycomb-protocol/solita
Version:
Generates SDK API from solana contract IDL.
200 lines (199 loc) • 7.07 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.genericsToTokens = exports.getOrCreate = exports.anchorDiscriminatorType = exports.anchorDiscriminatorField = exports.instructionDiscriminator = exports.SIGHASH_GLOBAL_NAMESPACE = exports.accountDiscriminator = exports.ACCOUNT_DISCRIMINATOR_SIZE = exports.UnreachableCaseError = exports.prependGeneratedWarning = exports.removeFileIfExists = exports.withoutTsExtension = exports.canAccessSync = exports.canAccess = exports.prepareTargetDir = void 0;
const camelcase_1 = __importDefault(require("camelcase"));
const constants_1 = require("constants");
const fs_1 = require("fs");
const js_sha256_1 = require("js-sha256");
const path_1 = __importDefault(require("path"));
const snake_case_1 = require("snake-case");
__exportStar(require("./logs"), exports);
// -----------------
// FileSystem
// -----------------
/**
* Ensures that the given directory exists by creating it recursively when necessary.
* It also removes all existing files from the directory (non-recursively).
*
* @throws Error if the path already exists and is not a directory
* @category utils
* @private
*/
async function prepareTargetDir(dir) {
await ensureDir(dir);
await cleanDir(dir);
}
exports.prepareTargetDir = prepareTargetDir;
async function ensureDir(dir) {
if (!(await canAccess(dir))) {
await fs_1.promises.mkdir(dir, { recursive: true });
return;
}
// dir already exists, make sure it isn't a file
const stat = await fs_1.promises.stat(dir);
if (!stat.isDirectory()) {
throw new Error(`'${dir}' is not a directory`);
}
}
async function cleanDir(dir) {
const files = await fs_1.promises.readdir(dir);
const unlinks = files.map((filename) => fs_1.promises.unlink(path_1.default.join(dir.toString(), filename)));
return Promise.all(unlinks);
}
async function canAccess(p, mode = constants_1.R_OK | constants_1.W_OK) {
try {
await fs_1.promises.access(p, mode);
return true;
}
catch (_) {
return false;
}
}
exports.canAccess = canAccess;
/**
* Ensures that a file or directory is accessible to the current user.
* @private
*/
function canAccessSync(p, mode = constants_1.R_OK | constants_1.W_OK) {
try {
(0, fs_1.accessSync)(p, mode);
return true;
}
catch (_) {
return false;
}
}
exports.canAccessSync = canAccessSync;
function withoutTsExtension(p) {
return p.replace(/\.ts$/, '');
}
exports.withoutTsExtension = withoutTsExtension;
async function removeFileIfExists(file) {
try {
await fs_1.promises.access(file);
}
catch (_) {
return false;
}
await fs_1.promises.rm(file);
return true;
}
exports.removeFileIfExists = removeFileIfExists;
function prependGeneratedWarning(code) {
return `
/**
* This code was GENERATED using the solita package.
* Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality.
*
* See: https://github.com/metaplex-foundation/solita
*/
${code}
`.trim();
}
exports.prependGeneratedWarning = prependGeneratedWarning;
class UnreachableCaseError extends Error {
constructor(value) {
super(`Unreachable case: ${value}`);
}
}
exports.UnreachableCaseError = UnreachableCaseError;
// -----------------
// Discriminators
// -----------------
/**
* Number of bytes of the account discriminator.
*/
exports.ACCOUNT_DISCRIMINATOR_SIZE = 8;
/**
* Calculates and returns a unique 8 byte discriminator prepended to all
* accounts.
*
* @param name The name of the account to calculate the discriminator.
*/
function accountDiscriminator(name) {
return Buffer.from(js_sha256_1.sha256.digest(`account:${(0, camelcase_1.default)(name, { pascalCase: true })}`)).slice(0, exports.ACCOUNT_DISCRIMINATOR_SIZE);
}
exports.accountDiscriminator = accountDiscriminator;
/**
* Namespace for global instruction function signatures (i.e. functions
* that aren't namespaced by the state or any of its trait implementations).
*/
exports.SIGHASH_GLOBAL_NAMESPACE = 'global';
/**
* Calculates and returns a unique 8 byte discriminator prepended to all instruction data.
*
* @param name The name of the instruction to calculate the discriminator.
*/
function instructionDiscriminator(name) {
return sighash(exports.SIGHASH_GLOBAL_NAMESPACE, name);
}
exports.instructionDiscriminator = instructionDiscriminator;
function sighash(nameSpace, ixName) {
let name = (0, snake_case_1.snakeCase)(ixName);
let preimage = `${nameSpace}:${name}`;
return Buffer.from(js_sha256_1.sha256.digest(preimage)).slice(0, 8);
}
function anchorDiscriminatorField(name) {
const ty = { array: ['u8', 8] };
return { name, type: ty };
}
exports.anchorDiscriminatorField = anchorDiscriminatorField;
function anchorDiscriminatorType(typeMapper, context) {
const ty = { array: ['u8', 8] };
return typeMapper.map(ty, context);
}
exports.anchorDiscriminatorType = anchorDiscriminatorType;
// -----------------
// Maps
// -----------------
function getOrCreate(map, key, initial) {
const current = map.get(key);
if (current != null)
return current;
map.set(key, initial);
return initial;
}
exports.getOrCreate = getOrCreate;
function genericsToTokens(typeName, _generics) {
const generics = _generics.length
? `<${_generics.map((g) => g.name).join(', ')}>`
: '';
const genericsDefaults = _generics.length
? `<${_generics.map((a) => `${a.name} = any`).join(', ')}>`
: '';
const enumRecordName = `${typeName}Record${generics}`;
const typeNameWithGenerics = `${typeName}${generics}`;
return {
typeNameWithGenerics,
enumRecordName,
genericsDefaults,
generics,
renderBeetExport: (beetVarName) => 'export const ' +
(generics.length
? `${beetVarName}Factory = ${generics}(
${_generics
.map((a) => `${a.name}: beet.FixableBeet<${a.name}> | beet.FixedSizeBeet<${a.name}>`)
.join(',\n ')}
) =>`
: `${beetVarName} = `),
};
}
exports.genericsToTokens = genericsToTokens;
//# sourceMappingURL=index.js.map