UNPKG

@kamino-finance/klend-sdk

Version:

Typescript SDK for interacting with the Kamino Lending (klend) protocol

227 lines 7.12 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HashablePublicKey = exports.PubkeyHashMap = exports.PublicKeyMap = exports.PublicKeySet = exports.COMPUTE_BUDGET_PROGRAM_ID = exports.NULL_PUBKEY = void 0; exports.isNotNullPubkey = isNotNullPubkey; const web3_js_1 = require("@solana/web3.js"); const bn_js_1 = __importDefault(require("bn.js")); exports.NULL_PUBKEY = new web3_js_1.PublicKey('nu11111111111111111111111111111111111111111'); exports.COMPUTE_BUDGET_PROGRAM_ID = new web3_js_1.PublicKey('ComputeBudget111111111111111111111111111111'); /** * Helper function to check if a configured pubkey is null or default. * @param pubkey * @returns {boolean} */ function isNotNullPubkey(pubkey) { return pubkey && !pubkey.equals(exports.NULL_PUBKEY) && !pubkey.equals(web3_js_1.PublicKey.default); } /** * Custom set implementation for PublicKey * Calling toString() on a PublicKey is pretty slow and pubkeys do not support `SameValueZero` comparison, so we use a custom set implementation where keys are compared with `PublicKey.equals(PublicKey)` */ class PublicKeySet { items = []; constructor(items) { items.forEach((item) => this.add(item)); } add(item) { if (!this.contains(item)) { this.items.push(item); } } contains(item) { return this.items.some((existingItem) => this.equals(existingItem, item)); } equals(item1, item2) { return item1.equals(item2); } isEmpty() { return this.items.length === 0; } toArray() { return this.items.slice(); // Return a copy of the array to prevent external modifications } } exports.PublicKeySet = PublicKeySet; /** * Custom map implementation for PublicKey, backed by a list for o(n) lookup speed * Calling toString() on a PublicKey is pretty slow and pubkeys do not support `SameValueZero` comparison, so we use a custom map implementation where keys are compared with `PublicKey.equals(PublicKey)` */ class PublicKeyMap { record = []; set(key, value) { const index = this.findIndex(key); if (index !== -1) { // Update existing entry this.record[index].value = value; } else { // Add new entry this.record.push({ key, value }); } } get(key) { const index = this.findIndex(key); return index !== -1 ? this.record[index].value : undefined; } has(key) { return this.findIndex(key) !== -1; } delete(key) { const index = this.findIndex(key); if (index !== -1) { this.record.splice(index, 1); } } findIndex(key) { return this.record.findIndex((entry) => entry.key.equals(key)); } clear() { this.record = []; } forEach(callback) { this.record.forEach((entry) => { callback(entry.value, entry.key); }); } keys() { return this.record.map((entry) => entry.key); } values() { return this.record.map((entry) => entry.value); } entries() { return this.record.map((entry) => [entry.key, entry.value]); } isEmpty() { return this.record.length === 0; } } exports.PublicKeyMap = PublicKeyMap; /** * Custom map implementation for PublicKey, backed by a hashmap for o(1) lookup speed * Calling toString() on a PublicKey is pretty slow and pubkeys do not support `SameValueZero` comparison, so we use a custom map implementation where keys are compared with `PublicKey.equals(PublicKey)`, and a hash is derived from the final 32 bits of the public key */ class PubkeyHashMap { buckets; size; constructor(entries) { this.buckets = new Map(); this.size = 0; if (entries) { for (const [key, value] of entries) { this.set(key, value); } } } *[Symbol.iterator]() { for (const [, bucket] of this.buckets) { for (const { key, value } of bucket) { yield [key, value]; } } } [Symbol.toStringTag] = 'PubkeyHashMap'; set(key, value) { const hash = new HashablePublicKey(key).hashCode(); const bucket = this.buckets.get(hash); if (!bucket) { this.buckets.set(hash, [{ key, value }]); this.size++; } else { const entry = bucket.find((entry) => entry.key.equals(key)); if (entry) { entry.value = value; } else { bucket.push({ key, value }); this.size++; } } return this; } get(key) { const hash = new HashablePublicKey(key).hashCode(); const bucket = this.buckets.get(hash); if (!bucket) { return undefined; } const entry = bucket.find((entry) => entry.key.equals(key)); return entry ? entry.value : undefined; } has(key) { const hash = new HashablePublicKey(key).hashCode(); const bucket = this.buckets.get(hash); if (!bucket) { return false; } const entry = bucket.find((entry) => entry.key.equals(key)); return !!entry; } delete(key) { const hash = new HashablePublicKey(key).hashCode(); const bucket = this.buckets.get(hash); if (!bucket) { return false; } const index = bucket.findIndex((entry) => entry.key.equals(key)); if (index === -1) { return false; } bucket.splice(index, 1); if (bucket.length === 0) { this.buckets.delete(hash); } this.size--; return true; } clear() { this.buckets = new Map(); this.size = 0; } isEmpty() { return this.size === 0; } forEach(callbackfn, thisArg) { this.buckets.forEach((bucket) => { bucket.forEach((entry) => { callbackfn(entry.value, entry.key, this); }, thisArg); }, thisArg); } *keys() { for (const [key] of this) { yield key; } } *values() { for (const [, value] of this) { yield value; } } entries() { return this[Symbol.iterator](); } } exports.PubkeyHashMap = PubkeyHashMap; class HashablePublicKey extends web3_js_1.PublicKey { // We only use the last 32 bits of the public key for hashing static MASK = new bn_js_1.default(1).shln(32).subn(1); constructor(value) { super(value); } hashCode() { let hash = 13; hash = hash * 7 + this.getBN().clone().iuand(HashablePublicKey.MASK).toNumber(); return hash; } getBN() { //@ts-ignore return this._bn; } } exports.HashablePublicKey = HashablePublicKey; //# sourceMappingURL=pubkey.js.map