@arcium-hq/reader
Version:
Reader SDK for fetching onchain data for Arcium network programs
303 lines (295 loc) • 11.4 kB
JavaScript
;
var client = require('@arcium-hq/client');
var anchor = require('@coral-xyz/anchor');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var anchor__namespace = /*#__PURE__*/_interopNamespaceDefault(anchor);
const ARCIUM_PROGRAM_ID_STRING = 'BKck65TgoKRokMjQM3datB9oRwJ8rAj2jxPXvHXUvcL6';
/**
* Discriminator for the ArxNode account type. Used to filter and identify ArxNode accounts on-chain.
*/
const ARX_NODE_ACC_DISCRIMINATOR = [2, 207, 122, 223, 93, 97, 231, 199];
/**
* Discriminator for the Cluster account type. Used to filter and identify Cluster accounts on-chain.
*/
const CLUSTER_ACC_DISCRIMINATOR = [236, 225, 118, 228, 173, 106, 18, 60];
/**
* Discriminator for the MXE account type. Used to filter and identify MXE accounts on-chain.
*/
const MXE_ACC_DISCRIMINATOR = [103, 26, 85, 250, 179, 159, 17, 117];
/**
* The public key of the deployed Arcium program on Solana.
*/
const ARCIUM_PROGRAM_ID = new anchor__namespace.web3.PublicKey(ARCIUM_PROGRAM_ID_STRING);
/**
* Anchor coder for encoding and decoding Arcium program instructions.
*/
new anchor__namespace.BorshInstructionCoder(client.ARCIUM_IDL);
/**
* Anchor event parser for parsing Arcium program events from transaction logs.
*/
const ARCIUM_EVENT_CODER = new anchor__namespace.EventParser(ARCIUM_PROGRAM_ID, new anchor__namespace.BorshCoder(client.ARCIUM_IDL));
/**
* Returns all MXE account addresses.
* @param conn - The Solana connection object.
* @returns Array of MXE account public keys.
*/
async function getMXEAccAddresses(conn) {
return getArciumAccPubkeys(conn, MXE_ACC_DISCRIMINATOR);
}
/**
* Returns all Cluster account addresses.
* @param conn - The Solana connection object.
* @returns Array of Cluster account public keys.
*/
async function getClusterAccAddresses(conn) {
return getArciumAccPubkeys(conn, CLUSTER_ACC_DISCRIMINATOR);
}
/**
* Returns all ArxNode account addresses.
* @param conn - The Solana connection object.
* @returns Array of ArxNode account public keys.
*/
async function getArxNodeAccAddresses(conn) {
return getArciumAccPubkeys(conn, ARX_NODE_ACC_DISCRIMINATOR);
}
/**
* Fetches and parses a given MXE account.
* @param arciumProgram - The Anchor program instance.
* @param address - The public key of the MXE account.
* @param commitment - (Optional) RPC commitment level.
* @returns The MXEAccount object.
*/
async function getMXEAccInfo(arciumProgram, address, commitment) {
return arciumProgram.account.mxeAccount.fetch(address, commitment);
}
/**
* Fetches and parses a given Cluster account.
* @param arciumProgram - The Anchor program instance.
* @param address - The public key of the Cluster account.
* @param commitment - (Optional) RPC commitment level.
* @returns The ClusterAccount object.
*/
async function getClusterAccInfo(arciumProgram, address, commitment) {
return arciumProgram.account.cluster.fetch(address, commitment);
}
/**
* Fetches and parses a given ArxNode account.
* @param arciumProgram - The Anchor program instance.
* @param address - The public key of the ArxNode account.
* @param commitment - (Optional) RPC commitment level.
* @returns The ArxNodeAccount object.
*/
async function getArxNodeAccInfo(arciumProgram, address, commitment) {
return arciumProgram.account.arxNode.fetch(address, commitment);
}
/**
* Fetches and parses a given ComputationDefinition account.
* @param arciumProgram - The Anchor program instance.
* @param address - The public key of the ComputationDefinition account.
* @param commitment - (Optional) RPC commitment level.
* @returns The ComputationDefinitionAccount object.
*/
async function getCompDefAccInfo(arciumProgram, address, commitment) {
return arciumProgram.account.computationDefinitionAccount.fetch(address, commitment);
}
/**
* Returns all computation references in the mempool for a given account.
* Only non-stake computations are included.
* @param arciumProgram - The Anchor program instance.
* @param address - The public key of the mempool account.
* @returns Array of ComputationReference objects.
*/
async function getComputationsInMempool(arciumProgram, address) {
const mempool = await client.getMempoolAccData(arciumProgram.provider, address);
const startIndex = mempool.inner.computations.startIndex;
const length = mempool.inner.computations.length;
const elems = mempool.inner.computations.elems;
function isValid(validBits, idx) {
const byte = idx >>> 3;
const bit = idx & 7;
if (byte >= validBits.length) {
// This should never happen, so we'll want to know about it
throw new Error(`isValid: byte ${byte} >= validBits.length ${validBits.length}`);
}
return (validBits[byte] & (1 << bit)) !== 0;
}
// Handle circular buffer wraparound
const refs = [];
for (let i = 0; i < length; i++) {
const idx = (startIndex + i) % elems.length;
// Only save non-stake computations
if (isValid(mempool.inner.computations.validBits, idx)) {
refs.push(...elems[idx].entries);
}
}
return refs
.flat()
.filter((ref) => !isNullRef(ref));
}
/**
* Fetches and parses a given Computation account.
* @param arciumProgram - The Anchor program instance.
* @param address - The public key of the Computation account.
* @param commitment - (Optional) RPC commitment level.
* @returns The Computation object.
*/
async function getComputationAccInfo(arciumProgram, address, commitment) {
return arciumProgram.account.computationAccount.fetch(address, commitment);
}
async function getArciumAccPubkeys(conn, discriminator) {
const accs = await conn.getProgramAccounts(ARCIUM_PROGRAM_ID, {
dataSlice: { offset: 0, length: 0 },
filters: [
{
memcmp: {
offset: 0,
encoding: 'base64',
bytes: Buffer.from(discriminator).toString('base64'),
},
},
],
});
return accs.map((acc) => acc.pubkey);
}
function isNullRef(ref) {
const bigZero = new anchor__namespace.BN(0);
return (ref.computationDefinitionOffset === 0
&& ref.computationOffset === bigZero
&& ref.priorityFee === bigZero);
}
const ArciumEventNames = [
'QueueComputationEvent',
'InitComputationEvent',
'CallbackComputationEvent',
'FinalizeComputationEvent',
];
/**
* Subscribes to computation-related events for a given MXE program ID.
* @param conn - The Solana connection object.
* @param mxeProgramId - The public key of the MXE program.
* @param callback - Callback function to handle each computation event and its name.
* @returns The subscription ID for the logs listener.
*/
async function subscribeComputations(conn, mxeProgramId, callback) {
return conn.onLogs(mxeProgramId, (logs) => {
const events = getComputationEventsFromLogs(logs.logs);
for (const event of events) {
callback(event.event, event.name);
}
});
}
/**
* Unsubscribes from computation-related events using the subscription ID.
* @param conn - The Solana connection object.
* @param subscriptionId - The subscription ID returned by subscribeComputations.
*/
async function unsubscribeComputations(conn, subscriptionId) {
conn.removeOnLogsListener(subscriptionId);
}
/**
* Gets the computation offset from a transaction.
* @param tx - The transaction to get the computation offset from.
* @returns The computation offset if one is found, otherwise undefined.
* @throws Error if multiple computation offsets are found in the transaction.
*/
function getComputationOffset(tx) {
const events = getComputationEventsFromLogs(tx.meta?.logMessages ?? []);
if (events.length === 0) {
return undefined;
}
const computationOffsets = events.map((e) => e.event.computationOffset);
const computationOffset = computationOffsets[0];
if (computationOffsets.some((offset) => !offset.eq(computationOffset))) {
throw new Error(`Multiple computation offsets found in computation: ${JSON.stringify(computationOffsets)}`);
}
return computationOffset;
}
/**
* Get the events related to arcium computations from a transaction's logs
* @param logs - The logs to get the events from
* @returns The events in the logs.
*/
function getComputationEventsFromLogs(logs) {
return Array.from(ARCIUM_EVENT_CODER.parseLogs(logs))
.filter((e) => ArciumEventNames.includes(e.name))
.map((e) => {
const eventData = {
computationOffset: e.data.computation_offset,
...e.data,
};
if (e.data.mxe_program_id) {
eventData.mxeProgramId = e.data.mxe_program_id;
}
return {
event: eventData,
name: e.name,
};
});
}
Object.defineProperty(exports, "getArciumProgramReadonly", {
enumerable: true,
get: function () { return client.getArciumProgramReadonly; }
});
Object.defineProperty(exports, "getArxNodeAccAddress", {
enumerable: true,
get: function () { return client.getArxNodeAccAddress; }
});
Object.defineProperty(exports, "getClockAccAddress", {
enumerable: true,
get: function () { return client.getClockAccAddress; }
});
Object.defineProperty(exports, "getClusterAccAddress", {
enumerable: true,
get: function () { return client.getClusterAccAddress; }
});
Object.defineProperty(exports, "getCompDefAccAddress", {
enumerable: true,
get: function () { return client.getCompDefAccAddress; }
});
Object.defineProperty(exports, "getComputationAccAddress", {
enumerable: true,
get: function () { return client.getComputationAccAddress; }
});
Object.defineProperty(exports, "getExecutingPoolAccAddress", {
enumerable: true,
get: function () { return client.getExecutingPoolAccAddress; }
});
Object.defineProperty(exports, "getMXEAccAddress", {
enumerable: true,
get: function () { return client.getMXEAccAddress; }
});
Object.defineProperty(exports, "getMempoolAccAddress", {
enumerable: true,
get: function () { return client.getMempoolAccAddress; }
});
Object.defineProperty(exports, "getStakingPoolAccAddress", {
enumerable: true,
get: function () { return client.getStakingPoolAccAddress; }
});
exports.getArxNodeAccAddresses = getArxNodeAccAddresses;
exports.getArxNodeAccInfo = getArxNodeAccInfo;
exports.getClusterAccAddresses = getClusterAccAddresses;
exports.getClusterAccInfo = getClusterAccInfo;
exports.getCompDefAccInfo = getCompDefAccInfo;
exports.getComputationAccInfo = getComputationAccInfo;
exports.getComputationOffset = getComputationOffset;
exports.getComputationsInMempool = getComputationsInMempool;
exports.getMXEAccAddresses = getMXEAccAddresses;
exports.getMXEAccInfo = getMXEAccInfo;
exports.subscribeComputations = subscribeComputations;
exports.unsubscribeComputations = unsubscribeComputations;