@exodus/solana-web3.js
Version:
Solana Javascript API
1,602 lines (1,336 loc) • 190 kB
JavaScript
import { Buffer as Buffer$1 } from 'buffer';
import nacl from 'tweetnacl';
import BN from 'bn.js';
import bs58 from 'bs58';
import { sha256 } from 'sha.js';
import { serialize, deserialize, deserializeUnchecked } from 'borsh';
import * as BufferLayout from '@solana/buffer-layout';
import { blob } from '@solana/buffer-layout';
import { type, string, optional, assert as assert$1 } from 'superstruct';
import jsSha3 from '@exodus/js-sha3';
import hmac from 'create-hmac';
/**
* A 64 byte secret key, the first 32 bytes of which is the
* private scalar and the last 32 bytes is the public key.
* Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
*/
//export const generatePrivateKey = ed25519.utils.randomPrivateKey;
const generatePrivateKey = () => nacl.sign.keyPair().secretKey.slice(0, 32);
const generateKeypair = () => nacl.sign.keyPair(); // export const getPublicKey = ed25519.sync.getPublicKey;
const getPublicKey$1 = s => nacl.sign.keyPair.fromSeed(s).publicKey; // export function isOnCurve(publicKey: Uint8Array): boolean { // TODO
// try {
// ed25519.Point.fromHex(publicKey, true /* strict */);
// return true;
// } catch {
// return false;
// }
// }
const sign = (message, secretKey) => nacl.sign.detached(message, secretKey); //export const verify = ed25519.sync.verify;
function verify(signature, message, publicKey) {
return nacl.sign.detached.verify(message, signature, publicKey);
} // @ts-ignore
let naclLowLevel = nacl.lowlevel; // Check that a pubkey is on the curve.
// This function and its dependents were sourced from:
// https://github.com/dchest/tweetnacl-js/blob/f1ec050ceae0861f34280e62498b1d3ed9c350c6/nacl.js#L792
function isOnCurve(p) {
var r = [naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf(), naclLowLevel.gf()];
var t = naclLowLevel.gf(),
chk = naclLowLevel.gf(),
num = naclLowLevel.gf(),
den = naclLowLevel.gf(),
den2 = naclLowLevel.gf(),
den4 = naclLowLevel.gf(),
den6 = naclLowLevel.gf();
naclLowLevel.set25519(r[2], gf1);
naclLowLevel.unpack25519(r[1], p);
naclLowLevel.S(num, r[1]);
naclLowLevel.M(den, num, naclLowLevel.D);
naclLowLevel.Z(num, num, r[2]);
naclLowLevel.A(den, r[2], den);
naclLowLevel.S(den2, den);
naclLowLevel.S(den4, den2);
naclLowLevel.M(den6, den4, den2);
naclLowLevel.M(t, den6, num);
naclLowLevel.M(t, t, den);
naclLowLevel.pow2523(t, t);
naclLowLevel.M(t, t, num);
naclLowLevel.M(t, t, den);
naclLowLevel.M(t, t, den);
naclLowLevel.M(r[0], t, den);
naclLowLevel.S(chk, r[0]);
naclLowLevel.M(chk, chk, den);
if (neq25519(chk, num)) naclLowLevel.M(r[0], r[0], I);
naclLowLevel.S(chk, r[0]);
naclLowLevel.M(chk, chk, den);
if (neq25519(chk, num)) return false;
return true;
}
let gf1 = naclLowLevel.gf([1]);
let I = naclLowLevel.gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
function neq25519(a, b) {
var c = new Uint8Array(32),
d = new Uint8Array(32);
naclLowLevel.pack25519(c, a);
naclLowLevel.pack25519(d, b);
return naclLowLevel.crypto_verify_32(c, 0, d, 0);
}
const toBuffer = arr => {
if (Buffer$1.isBuffer(arr)) {
return arr;
} else if (arr instanceof Uint8Array) {
return Buffer$1.from(arr.buffer, arr.byteOffset, arr.byteLength);
} else {
return Buffer$1.from(arr);
}
};
class Struct {
constructor(properties) {
Object.assign(this, properties);
}
encode() {
return Buffer$1.from(serialize(SOLANA_SCHEMA, this));
}
static decode(data) {
return deserialize(SOLANA_SCHEMA, this, data);
}
static decodeUnchecked(data) {
return deserializeUnchecked(SOLANA_SCHEMA, this, data);
}
} // Class representing a Rust-compatible enum, since enums are only strings or
// numbers in pure JS
class Enum extends Struct {
constructor(properties) {
super(properties);
this.enum = '';
if (Object.keys(properties).length !== 1) {
throw new Error('Enum can only take single value');
}
Object.keys(properties).map(key => {
this.enum = key;
});
}
}
const SOLANA_SCHEMA = new Map();
/**
* Maximum length of derived pubkey seed
*/
const MAX_SEED_LENGTH = 32;
/**
* Size of public key in bytes
*/
const PUBLIC_KEY_LENGTH = 32;
/**
* Value to be converted into public key
*/
function isPublicKeyData(value) {
return value._bn !== undefined;
} // local counter used by PublicKey.unique()
let uniquePublicKeyCounter = 1;
/**
* A public key
*/
class PublicKey extends Struct {
/** @internal */
/**
* Create a new PublicKey object
* @param value ed25519 public key as buffer or base-58 encoded string
*/
constructor(value) {
super({});
this._bn = void 0;
if (isPublicKeyData(value)) {
this._bn = value._bn;
} else {
if (typeof value === 'string') {
// assume base 58 encoding by default
const decoded = bs58.decode(value);
if (decoded.length != PUBLIC_KEY_LENGTH) {
throw new Error(`Invalid public key input`);
}
this._bn = new BN(decoded);
} else {
this._bn = new BN(value);
}
if (this._bn.byteLength() > 32) {
throw new Error(`Invalid public key input`);
}
}
}
/**
* Returns a unique PublicKey for tests and benchmarks using acounter
*/
static unique() {
const key = new PublicKey(uniquePublicKeyCounter);
uniquePublicKeyCounter += 1;
return new PublicKey(key.toBuffer());
}
/**
* Default public key value. (All zeros)
*/
/**
* Checks if two publicKeys are equal
*/
equals(publicKey) {
return this._bn.eq(publicKey._bn);
}
/**
* Return the base-58 representation of the public key
*/
toBase58() {
return bs58.encode(this.toBytes());
}
toJSON() {
return this.toBase58();
}
/**
* Return the byte array representation of the public key
*/
toBytes() {
return this.toBuffer();
}
/**
* Return the Buffer representation of the public key
*/
toBuffer() {
const b = this._bn.toArrayLike(Buffer$1);
if (b.length === PUBLIC_KEY_LENGTH) {
return b;
}
const zeroPad = Buffer$1.alloc(32);
b.copy(zeroPad, 32 - b.length);
return zeroPad;
}
/**
* Return the base-58 representation of the public key
*/
toString() {
return this.toBase58();
}
/**
* Derive a public key from another key, a seed, and a program ID.
* The program ID will also serve as the owner of the public key, giving
* it permission to write data to the account.
*/
/* eslint-disable require-await */
static async createWithSeed(fromPublicKey, seed, programId) {
const buffer = Buffer$1.concat([fromPublicKey.toBuffer(), Buffer$1.from(seed), programId.toBuffer()]);
const publicKeyBytes = new Uint8Array(new sha256().update(buffer).digest());
return new PublicKey(publicKeyBytes);
}
/**
* Derive a program address from seeds and a program ID.
*/
/* eslint-disable require-await */
static createProgramAddressSync(seeds, programId) {
let buffer = Buffer$1.alloc(0);
seeds.forEach(function (seed) {
if (seed.length > MAX_SEED_LENGTH) {
throw new TypeError(`Max seed length exceeded`);
}
buffer = Buffer$1.concat([buffer, toBuffer(seed)]);
});
buffer = Buffer$1.concat([buffer, programId.toBuffer(), Buffer$1.from('ProgramDerivedAddress')]);
const publicKeyBytes = new Uint8Array(new sha256().update(buffer).digest());
if (isOnCurve(publicKeyBytes)) {
throw new Error(`Invalid seeds, address must fall off the curve`);
}
return new PublicKey(publicKeyBytes);
}
/**
* Async version of createProgramAddressSync
* For backwards compatibility
*/
/* eslint-disable require-await */
static async createProgramAddress(seeds, programId) {
return this.createProgramAddressSync(seeds, programId);
}
/**
* Find a valid program address
*
* Valid program addresses must fall off the ed25519 curve. This function
* iterates a nonce until it finds one that when combined with the seeds
* results in a valid program address.
*/
static findProgramAddressSync(seeds, programId) {
let nonce = 255;
let address;
while (nonce != 0) {
try {
const seedsWithNonce = seeds.concat(Buffer$1.from([nonce]));
address = this.createProgramAddressSync(seedsWithNonce, programId);
} catch (err) {
if (err instanceof TypeError) {
throw err;
}
nonce--;
continue;
}
return [address, nonce];
}
throw new Error(`Unable to find a viable program address nonce`);
}
/**
* Async version of findProgramAddressSync
* For backwards compatibility
*/
static async findProgramAddress(seeds, programId) {
return this.findProgramAddressSync(seeds, programId);
}
/**
* Check that a pubkey is on the ed25519 curve.
*/
static isOnCurve(pubkeyData) {
const pubkey = new PublicKey(pubkeyData);
return isOnCurve(pubkey.toBytes());
}
}
PublicKey.default = new PublicKey('11111111111111111111111111111111');
SOLANA_SCHEMA.set(PublicKey, {
kind: 'struct',
fields: [['_bn', 'u256']]
});
/**
* An account key pair (public and secret keys).
*
* @deprecated since v1.10.0, please use {@link Keypair} instead.
*/
class Account {
/** @internal */
/** @internal */
/**
* Create a new Account object
*
* If the secretKey parameter is not provided a new key pair is randomly
* created for the account
*
* @param secretKey Secret key for the account
*/
constructor(secretKey) {
this._publicKey = void 0;
this._secretKey = void 0;
if (secretKey) {
const secretKeyBuffer = toBuffer(secretKey);
if (secretKey.length !== 64) {
throw new Error('bad secret key size');
}
this._publicKey = secretKeyBuffer.slice(32, 64);
this._secretKey = secretKeyBuffer.slice(0, 32);
} else {
this._secretKey = toBuffer(generatePrivateKey());
this._publicKey = toBuffer(getPublicKey$1(this._secretKey));
}
}
/**
* The public key for this account
*/
get publicKey() {
return new PublicKey(this._publicKey);
}
/**
* The **unencrypted** secret key for this account. The first 32 bytes
* is the private scalar and the last 32 bytes is the public key.
* Read more: https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/
*/
get secretKey() {
return Buffer$1.concat([this._secretKey, this._publicKey], 64);
}
}
const BPF_LOADER_DEPRECATED_PROGRAM_ID = new PublicKey('BPFLoader1111111111111111111111111111111111');
const MINIMUM_SLOT_PER_EPOCH = 32; // Returns the number of trailing zeros in the binary representation of self.
function trailingZeros(n) {
let trailingZeros = 0;
while (n > 1) {
n /= 2;
trailingZeros++;
}
return trailingZeros;
} // Returns the smallest power of two greater than or equal to n
function nextPowerOfTwo(n) {
if (n === 0) return 1;
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n |= n >> 32;
return n + 1;
}
/**
* Epoch schedule
* (see https://docs.solana.com/terminology#epoch)
* Can be retrieved with the {@link connection.getEpochSchedule} method
*/
class EpochSchedule {
/** The maximum number of slots in each epoch */
/** The number of slots before beginning of an epoch to calculate a leader schedule for that epoch */
/** Indicates whether epochs start short and grow */
/** The first epoch with `slotsPerEpoch` slots */
/** The first slot of `firstNormalEpoch` */
constructor(slotsPerEpoch, leaderScheduleSlotOffset, warmup, firstNormalEpoch, firstNormalSlot) {
this.slotsPerEpoch = void 0;
this.leaderScheduleSlotOffset = void 0;
this.warmup = void 0;
this.firstNormalEpoch = void 0;
this.firstNormalSlot = void 0;
this.slotsPerEpoch = slotsPerEpoch;
this.leaderScheduleSlotOffset = leaderScheduleSlotOffset;
this.warmup = warmup;
this.firstNormalEpoch = firstNormalEpoch;
this.firstNormalSlot = firstNormalSlot;
}
getEpoch(slot) {
return this.getEpochAndSlotIndex(slot)[0];
}
getEpochAndSlotIndex(slot) {
if (slot < this.firstNormalSlot) {
const epoch = trailingZeros(nextPowerOfTwo(slot + MINIMUM_SLOT_PER_EPOCH + 1)) - trailingZeros(MINIMUM_SLOT_PER_EPOCH) - 1;
const epochLen = this.getSlotsInEpoch(epoch);
const slotIndex = slot - (epochLen - MINIMUM_SLOT_PER_EPOCH);
return [epoch, slotIndex];
} else {
const normalSlotIndex = slot - this.firstNormalSlot;
const normalEpochIndex = Math.floor(normalSlotIndex / this.slotsPerEpoch);
const epoch = this.firstNormalEpoch + normalEpochIndex;
const slotIndex = normalSlotIndex % this.slotsPerEpoch;
return [epoch, slotIndex];
}
}
getFirstSlotInEpoch(epoch) {
if (epoch <= this.firstNormalEpoch) {
return (Math.pow(2, epoch) - 1) * MINIMUM_SLOT_PER_EPOCH;
} else {
return (epoch - this.firstNormalEpoch) * this.slotsPerEpoch + this.firstNormalSlot;
}
}
getLastSlotInEpoch(epoch) {
return this.getFirstSlotInEpoch(epoch) + this.getSlotsInEpoch(epoch) - 1;
}
getSlotsInEpoch(epoch) {
if (epoch < this.firstNormalEpoch) {
return Math.pow(2, epoch + trailingZeros(MINIMUM_SLOT_PER_EPOCH));
} else {
return this.slotsPerEpoch;
}
}
}
class SendTransactionError extends Error {
constructor(message, logs) {
super(message);
this.logs = void 0;
this.logs = logs;
}
} // Keep in sync with client/src/rpc_custom_errors.rs
// Typescript `enums` thwart tree-shaking. See https://bargsten.org/jsts/enums/
const SolanaJSONRPCErrorCode = {
JSON_RPC_SERVER_ERROR_BLOCK_CLEANED_UP: -32001,
JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE: -32002,
JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE: -32003,
JSON_RPC_SERVER_ERROR_BLOCK_NOT_AVAILABLE: -32004,
JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY: -32005,
JSON_RPC_SERVER_ERROR_TRANSACTION_PRECOMPILE_VERIFICATION_FAILURE: -32006,
JSON_RPC_SERVER_ERROR_SLOT_SKIPPED: -32007,
JSON_RPC_SERVER_ERROR_NO_SNAPSHOT: -32008,
JSON_RPC_SERVER_ERROR_LONG_TERM_STORAGE_SLOT_SKIPPED: -32009,
JSON_RPC_SERVER_ERROR_KEY_EXCLUDED_FROM_SECONDARY_INDEX: -32010,
JSON_RPC_SERVER_ERROR_TRANSACTION_HISTORY_NOT_AVAILABLE: -32011,
JSON_RPC_SCAN_ERROR: -32012,
JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_LEN_MISMATCH: -32013,
JSON_RPC_SERVER_ERROR_BLOCK_STATUS_NOT_AVAILABLE_YET: -32014,
JSON_RPC_SERVER_ERROR_UNSUPPORTED_TRANSACTION_VERSION: -32015,
JSON_RPC_SERVER_ERROR_MIN_CONTEXT_SLOT_NOT_REACHED: -32016
};
class SolanaJSONRPCError extends Error {
constructor({
code,
message,
data
}, customMessage) {
super(customMessage != null ? `${customMessage}: ${message}` : message);
this.code = void 0;
this.data = void 0;
this.code = code;
this.data = data;
this.name = 'SolanaJSONRPCError';
}
}
/**
* https://github.com/solana-labs/solana/blob/90bedd7e067b5b8f3ddbb45da00a4e9cabb22c62/sdk/src/fee_calculator.rs#L7-L11
*
* @internal
*/
const FeeCalculatorLayout = BufferLayout.nu64('lamportsPerSignature');
/**
* Calculator for transaction fees.
*
* @deprecated Deprecated since Solana v1.8.0.
*/
/**
* Keypair signer interface
*/
/**
* An account keypair used for signing transactions.
*/
class Keypair {
/**
* Create a new keypair instance.
* Generate random keypair if no {@link Ed25519Keypair} is provided.
*
* @param keypair ed25519 keypair
*/
constructor(keypair) {
this._keypair = void 0;
this._keypair = keypair !== null && keypair !== void 0 ? keypair : generateKeypair();
}
/**
* Generate a new random keypair
*/
static generate() {
return new Keypair(generateKeypair());
}
/**
* Create a keypair from a raw secret key byte array.
*
* This method should only be used to recreate a keypair from a previously
* generated secret key. Generating keypairs from a random seed should be done
* with the {@link Keypair.fromSeed} method.
*
* @throws error if the provided secret key is invalid and validation is not skipped.
*
* @param secretKey secret key byte array
* @param options: skip secret key validation
*/
static fromSecretKey(secretKey, options) {
if (secretKey.byteLength !== 64) {
throw new Error('bad secret key size');
}
const publicKey = secretKey.slice(32, 64);
if (!options || !options.skipValidation) {
const privateScalar = secretKey.slice(0, 32);
const computedPublicKey = getPublicKey$1(privateScalar);
for (let ii = 0; ii < 32; ii++) {
if (publicKey[ii] !== computedPublicKey[ii]) {
throw new Error('provided secretKey is invalid');
}
}
}
return new Keypair({
publicKey,
secretKey
});
}
/**
* Generate a keypair from a 32 byte seed.
*
* @param seed seed byte array
*/
static fromSeed(seed) {
const publicKey = getPublicKey$1(seed);
const secretKey = new Uint8Array(64);
secretKey.set(seed);
secretKey.set(publicKey, 32);
return new Keypair({
publicKey,
secretKey
});
}
/**
* The public key for this keypair
*/
get publicKey() {
return new PublicKey(this._keypair.publicKey);
}
/**
* The raw secret key for this keypair
*/
get secretKey() {
return new Uint8Array(this._keypair.secretKey);
}
}
/**
* Maximum over-the-wire size of a Transaction
*
* 1280 is IPv6 minimum MTU
* 40 bytes is the size of the IPv6 header
* 8 bytes is the size of the fragment header
*/
const PACKET_DATA_SIZE = 1280 - 40 - 8;
const VERSION_PREFIX_MASK = 0x7f;
const SIGNATURE_LENGTH_IN_BYTES = 64;
class TransactionExpiredBlockheightExceededError extends Error {
constructor(signature) {
super(`Signature ${signature} has expired: block height exceeded.`);
this.signature = void 0;
this.signature = signature;
}
}
Object.defineProperty(TransactionExpiredBlockheightExceededError.prototype, 'name', {
value: 'TransactionExpiredBlockheightExceededError'
});
class TransactionExpiredTimeoutError extends Error {
constructor(signature, timeoutSeconds) {
super(`Transaction was not confirmed in ${timeoutSeconds.toFixed(2)} seconds. It is ` + 'unknown if it succeeded or failed. Check signature ' + `${signature} using the Solana Explorer or CLI tools.`);
this.signature = void 0;
this.signature = signature;
}
}
Object.defineProperty(TransactionExpiredTimeoutError.prototype, 'name', {
value: 'TransactionExpiredTimeoutError'
});
class MessageAccountKeys {
constructor(staticAccountKeys, accountKeysFromLookups) {
this.staticAccountKeys = void 0;
this.accountKeysFromLookups = void 0;
this.staticAccountKeys = staticAccountKeys;
this.accountKeysFromLookups = accountKeysFromLookups;
}
keySegments() {
const keySegments = [this.staticAccountKeys];
if (this.accountKeysFromLookups) {
keySegments.push(this.accountKeysFromLookups.writable);
keySegments.push(this.accountKeysFromLookups.readonly);
}
return keySegments;
}
get(index) {
for (const keySegment of this.keySegments()) {
if (index < keySegment.length) {
return keySegment[index];
} else {
index -= keySegment.length;
}
}
return;
}
get length() {
return this.keySegments().flat().length;
}
compileInstructions(instructions) {
// Bail early if any account indexes would overflow a u8
const U8_MAX = 255;
if (this.length > U8_MAX) {
throw new Error('Account index overflow encountered during compilation');
}
const keyIndexMap = new Map();
this.keySegments().flat().forEach((key, index) => {
keyIndexMap.set(key.toBase58(), index);
});
const findKeyIndex = key => {
const keyIndex = keyIndexMap.get(key.toBase58());
if (keyIndex === undefined) throw new Error('Encountered an unknown instruction account key during compilation');
return keyIndex;
};
return instructions.map(instruction => {
return {
programIdIndex: findKeyIndex(instruction.programId),
accountKeyIndexes: instruction.keys.map(meta => findKeyIndex(meta.pubkey)),
data: instruction.data
};
});
}
}
/**
* Layout for a public key
*/
const publicKey = (property = 'publicKey') => {
return BufferLayout.blob(32, property);
};
/**
* Layout for a signature
*/
const signature = (property = 'signature') => {
return BufferLayout.blob(64, property);
};
/**
* Layout for a 64bit unsigned value
*/
const uint64 = (property = 'uint64') => {
return BufferLayout.blob(8, property);
};
/**
* Layout for a Rust String type
*/
const rustString = (property = 'string') => {
const rsl = BufferLayout.struct([BufferLayout.u32('length'), BufferLayout.u32('lengthPadding'), BufferLayout.blob(BufferLayout.offset(BufferLayout.u32(), -8), 'chars')], property);
const _decode = rsl.decode.bind(rsl);
const _encode = rsl.encode.bind(rsl);
const rslShim = rsl;
rslShim.decode = (b, offset) => {
const data = _decode(b, offset);
return data['chars'].toString();
};
rslShim.encode = (str, b, offset) => {
const data = {
chars: Buffer$1.from(str, 'utf8')
};
return _encode(data, b, offset);
};
rslShim.alloc = str => {
return BufferLayout.u32().span + BufferLayout.u32().span + Buffer$1.from(str, 'utf8').length;
};
return rslShim;
};
/**
* Layout for an Authorized object
*/
const authorized = (property = 'authorized') => {
return BufferLayout.struct([publicKey('staker'), publicKey('withdrawer')], property);
};
/**
* Layout for a Lockup object
*/
const lockup = (property = 'lockup') => {
return BufferLayout.struct([BufferLayout.ns64('unixTimestamp'), BufferLayout.ns64('epoch'), publicKey('custodian')], property);
};
/**
* Layout for a VoteInit object
*/
const voteInit = (property = 'voteInit') => {
return BufferLayout.struct([publicKey('nodePubkey'), publicKey('authorizedVoter'), publicKey('authorizedWithdrawer'), BufferLayout.u8('commission')], property);
};
/**
* Layout for a VoteAuthorizeWithSeedArgs object
*/
const voteAuthorizeWithSeedArgs = (property = 'voteAuthorizeWithSeedArgs') => {
return BufferLayout.struct([BufferLayout.u32('voteAuthorizationType'), publicKey('currentAuthorityDerivedKeyOwnerPubkey'), rustString('currentAuthorityDerivedKeySeed'), publicKey('newAuthorized')], property);
};
function getAlloc(type, fields) {
const getItemAlloc = item => {
if (item.span >= 0) {
return item.span;
} else if (typeof item.alloc === 'function') {
return item.alloc(fields[item.property]);
} else if ('count' in item && 'elementLayout' in item) {
const field = fields[item.property];
if (Array.isArray(field)) {
return field.length * getItemAlloc(item.elementLayout);
}
} else if ('fields' in item) {
// This is a `Structure` whose size needs to be recursively measured.
return getAlloc({
layout: item
}, fields[item.property]);
} // Couldn't determine allocated size of layout
return 0;
};
let alloc = 0;
type.layout.fields.forEach(item => {
alloc += getItemAlloc(item);
});
return alloc;
}
function decodeLength(bytes) {
let len = 0;
let size = 0;
for (;;) {
let elem = bytes.shift();
len |= (elem & 0x7f) << size * 7;
size += 1;
if ((elem & 0x80) === 0) {
break;
}
}
return len;
}
function encodeLength(bytes, len) {
let rem_len = len;
for (;;) {
let elem = rem_len & 0x7f;
rem_len >>= 7;
if (rem_len == 0) {
bytes.push(elem);
break;
} else {
elem |= 0x80;
bytes.push(elem);
}
}
}
function assert (condition, message) {
if (!condition) {
throw new Error(message || 'Assertion failed');
}
}
class CompiledKeys {
constructor(payer, keyMetaMap) {
this.payer = void 0;
this.keyMetaMap = void 0;
this.payer = payer;
this.keyMetaMap = keyMetaMap;
}
static compile(instructions, payer) {
const keyMetaMap = new Map();
const getOrInsertDefault = pubkey => {
const address = pubkey.toBase58();
let keyMeta = keyMetaMap.get(address);
if (keyMeta === undefined) {
keyMeta = {
isSigner: false,
isWritable: false,
isInvoked: false
};
keyMetaMap.set(address, keyMeta);
}
return keyMeta;
};
const payerKeyMeta = getOrInsertDefault(payer);
payerKeyMeta.isSigner = true;
payerKeyMeta.isWritable = true;
for (const ix of instructions) {
getOrInsertDefault(ix.programId).isInvoked = true;
for (const accountMeta of ix.keys) {
const keyMeta = getOrInsertDefault(accountMeta.pubkey);
keyMeta.isSigner || (keyMeta.isSigner = accountMeta.isSigner);
keyMeta.isWritable || (keyMeta.isWritable = accountMeta.isWritable);
}
}
return new CompiledKeys(payer, keyMetaMap);
}
getMessageComponents() {
const mapEntries = [...this.keyMetaMap.entries()];
assert(mapEntries.length < 256, 'Max static account keys length exceeded');
const writableSigners = mapEntries.filter(([, meta]) => meta.isSigner && meta.isWritable);
const readonlySigners = mapEntries.filter(([, meta]) => meta.isSigner && !meta.isWritable);
const writableNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && meta.isWritable);
const readonlyNonSigners = mapEntries.filter(([, meta]) => !meta.isSigner && !meta.isWritable);
const header = {
numRequiredSignatures: writableSigners.length + readonlySigners.length,
numReadonlySignedAccounts: readonlySigners.length,
numReadonlyUnsignedAccounts: readonlyNonSigners.length
}; // sanity checks
{
assert(writableSigners.length > 0, 'Expected at least one writable signer key');
const [payerAddress] = writableSigners[0];
assert(payerAddress === this.payer.toBase58(), 'Expected first writable signer key to be the fee payer');
}
const staticAccountKeys = [...writableSigners.map(([address]) => new PublicKey(address)), ...readonlySigners.map(([address]) => new PublicKey(address)), ...writableNonSigners.map(([address]) => new PublicKey(address)), ...readonlyNonSigners.map(([address]) => new PublicKey(address))];
return [header, staticAccountKeys];
}
extractTableLookup(lookupTable) {
const [writableIndexes, drainedWritableKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && keyMeta.isWritable);
const [readonlyIndexes, drainedReadonlyKeys] = this.drainKeysFoundInLookupTable(lookupTable.state.addresses, keyMeta => !keyMeta.isSigner && !keyMeta.isInvoked && !keyMeta.isWritable); // Don't extract lookup if no keys were found
if (writableIndexes.length === 0 && readonlyIndexes.length === 0) {
return;
}
return [{
accountKey: lookupTable.key,
writableIndexes,
readonlyIndexes
}, {
writable: drainedWritableKeys,
readonly: drainedReadonlyKeys
}];
}
/** @internal */
drainKeysFoundInLookupTable(lookupTableEntries, keyMetaFilter) {
const lookupTableIndexes = new Array();
const drainedKeys = new Array();
for (const [address, keyMeta] of this.keyMetaMap.entries()) {
if (keyMetaFilter(keyMeta)) {
const key = new PublicKey(address);
const lookupTableIndex = lookupTableEntries.findIndex(entry => entry.equals(key));
if (lookupTableIndex >= 0) {
assert(lookupTableIndex < 256, 'Max lookup table index exceeded');
lookupTableIndexes.push(lookupTableIndex);
drainedKeys.push(key);
this.keyMetaMap.delete(address);
}
}
}
return [lookupTableIndexes, drainedKeys];
}
}
/**
* An instruction to execute by a program
*
* @property {number} programIdIndex
* @property {number[]} accounts
* @property {string} data
*/
/**
* List of instructions to be processed atomically
*/
class Message {
constructor(args) {
this.header = void 0;
this.accountKeys = void 0;
this.recentBlockhash = void 0;
this.instructions = void 0;
this.indexToProgramIds = new Map();
this.header = args.header;
this.accountKeys = args.accountKeys.map(account => new PublicKey(account));
this.recentBlockhash = args.recentBlockhash;
this.instructions = args.instructions;
this.instructions.forEach(ix => this.indexToProgramIds.set(ix.programIdIndex, this.accountKeys[ix.programIdIndex]));
}
get version() {
return 'legacy';
}
get staticAccountKeys() {
return this.accountKeys;
}
get compiledInstructions() {
return this.instructions.map(ix => ({
programIdIndex: ix.programIdIndex,
accountKeyIndexes: ix.accounts,
data: bs58.decode(ix.data)
}));
}
get addressTableLookups() {
return [];
}
getAccountKeys() {
return new MessageAccountKeys(this.staticAccountKeys);
}
static compile(args) {
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
const accountKeys = new MessageAccountKeys(staticAccountKeys);
const instructions = accountKeys.compileInstructions(args.instructions).map(ix => ({
programIdIndex: ix.programIdIndex,
accounts: ix.accountKeyIndexes,
data: bs58.encode(ix.data)
}));
return new Message({
header,
accountKeys: staticAccountKeys,
recentBlockhash: args.recentBlockhash,
instructions
});
}
isAccountSigner(index) {
return index < this.header.numRequiredSignatures;
}
isAccountWritable(index) {
const numSignedAccounts = this.header.numRequiredSignatures;
if (index >= this.header.numRequiredSignatures) {
const unsignedAccountIndex = index - numSignedAccounts;
const numUnsignedAccounts = this.accountKeys.length - numSignedAccounts;
const numWritableUnsignedAccounts = numUnsignedAccounts - this.header.numReadonlyUnsignedAccounts;
return unsignedAccountIndex < numWritableUnsignedAccounts;
} else {
const numWritableSignedAccounts = numSignedAccounts - this.header.numReadonlySignedAccounts;
return index < numWritableSignedAccounts;
}
}
isProgramId(index) {
return this.indexToProgramIds.has(index);
}
programIds() {
return [...this.indexToProgramIds.values()];
}
nonProgramIds() {
return this.accountKeys.filter((_, index) => !this.isProgramId(index));
}
serialize() {
const numKeys = this.accountKeys.length;
let keyCount = [];
encodeLength(keyCount, numKeys);
const instructions = this.instructions.map(instruction => {
const {
accounts,
programIdIndex
} = instruction;
const data = Array.from(bs58.decode(instruction.data));
let keyIndicesCount = [];
encodeLength(keyIndicesCount, accounts.length);
let dataCount = [];
encodeLength(dataCount, data.length);
return {
programIdIndex,
keyIndicesCount: Buffer$1.from(keyIndicesCount),
keyIndices: accounts,
dataLength: Buffer$1.from(dataCount),
data
};
});
let instructionCount = [];
encodeLength(instructionCount, instructions.length);
let instructionBuffer = Buffer$1.alloc(PACKET_DATA_SIZE);
Buffer$1.from(instructionCount).copy(instructionBuffer);
let instructionBufferLength = instructionCount.length;
instructions.forEach(instruction => {
const instructionLayout = BufferLayout.struct([BufferLayout.u8('programIdIndex'), BufferLayout.blob(instruction.keyIndicesCount.length, 'keyIndicesCount'), BufferLayout.seq(BufferLayout.u8('keyIndex'), instruction.keyIndices.length, 'keyIndices'), BufferLayout.blob(instruction.dataLength.length, 'dataLength'), BufferLayout.seq(BufferLayout.u8('userdatum'), instruction.data.length, 'data')]);
const length = instructionLayout.encode(instruction, instructionBuffer, instructionBufferLength);
instructionBufferLength += length;
});
instructionBuffer = instructionBuffer.slice(0, instructionBufferLength);
const signDataLayout = BufferLayout.struct([BufferLayout.blob(1, 'numRequiredSignatures'), BufferLayout.blob(1, 'numReadonlySignedAccounts'), BufferLayout.blob(1, 'numReadonlyUnsignedAccounts'), BufferLayout.blob(keyCount.length, 'keyCount'), BufferLayout.seq(publicKey('key'), numKeys, 'keys'), publicKey('recentBlockhash')]);
const transaction = {
numRequiredSignatures: Buffer$1.from([this.header.numRequiredSignatures]),
numReadonlySignedAccounts: Buffer$1.from([this.header.numReadonlySignedAccounts]),
numReadonlyUnsignedAccounts: Buffer$1.from([this.header.numReadonlyUnsignedAccounts]),
keyCount: Buffer$1.from(keyCount),
keys: this.accountKeys.map(key => toBuffer(key.toBytes())),
recentBlockhash: bs58.decode(this.recentBlockhash)
};
let signData = Buffer$1.alloc(2048);
const length = signDataLayout.encode(transaction, signData);
instructionBuffer.copy(signData, length);
return signData.slice(0, length + instructionBuffer.length);
}
/**
* Decode a compiled message into a Message object.
*/
static from(buffer) {
// Slice up wire data
let byteArray = [...buffer];
const numRequiredSignatures = byteArray.shift();
if (numRequiredSignatures !== (numRequiredSignatures & VERSION_PREFIX_MASK)) {
throw new Error('Versioned messages must be deserialized with VersionedMessage.deserialize()');
}
const numReadonlySignedAccounts = byteArray.shift();
const numReadonlyUnsignedAccounts = byteArray.shift();
const accountCount = decodeLength(byteArray);
let accountKeys = [];
for (let i = 0; i < accountCount; i++) {
const account = byteArray.slice(0, PUBLIC_KEY_LENGTH);
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
accountKeys.push(new PublicKey(Buffer$1.from(account)));
}
const recentBlockhash = byteArray.slice(0, PUBLIC_KEY_LENGTH);
byteArray = byteArray.slice(PUBLIC_KEY_LENGTH);
const instructionCount = decodeLength(byteArray);
let instructions = [];
for (let i = 0; i < instructionCount; i++) {
const programIdIndex = byteArray.shift();
const accountCount = decodeLength(byteArray);
const accounts = byteArray.slice(0, accountCount);
byteArray = byteArray.slice(accountCount);
const dataLength = decodeLength(byteArray);
const dataSlice = byteArray.slice(0, dataLength);
const data = bs58.encode(Buffer$1.from(dataSlice));
byteArray = byteArray.slice(dataLength);
instructions.push({
programIdIndex,
accounts,
data
});
}
const messageArgs = {
header: {
numRequiredSignatures,
numReadonlySignedAccounts,
numReadonlyUnsignedAccounts
},
recentBlockhash: bs58.encode(Buffer$1.from(recentBlockhash)),
accountKeys,
instructions
};
return new Message(messageArgs);
}
}
/**
* Message constructor arguments
*/
class MessageV0 {
constructor(args) {
this.header = void 0;
this.staticAccountKeys = void 0;
this.recentBlockhash = void 0;
this.compiledInstructions = void 0;
this.addressTableLookups = void 0;
this.header = args.header;
this.staticAccountKeys = args.staticAccountKeys;
this.recentBlockhash = args.recentBlockhash;
this.compiledInstructions = args.compiledInstructions;
this.addressTableLookups = args.addressTableLookups;
}
get version() {
return 0;
}
get numAccountKeysFromLookups() {
let count = 0;
for (const lookup of this.addressTableLookups) {
count += lookup.readonlyIndexes.length + lookup.writableIndexes.length;
}
return count;
}
getAccountKeys(args) {
let accountKeysFromLookups;
if (args && 'accountKeysFromLookups' in args && args.accountKeysFromLookups) {
if (this.numAccountKeysFromLookups != args.accountKeysFromLookups.writable.length + args.accountKeysFromLookups.readonly.length) {
throw new Error('Failed to get account keys because of a mismatch in the number of account keys from lookups');
}
accountKeysFromLookups = args.accountKeysFromLookups;
} else if (args && 'addressLookupTableAccounts' in args && args.addressLookupTableAccounts) {
accountKeysFromLookups = this.resolveAddressTableLookups(args.addressLookupTableAccounts);
} else if (this.addressTableLookups.length > 0) {
throw new Error('Failed to get account keys because address table lookups were not resolved');
}
return new MessageAccountKeys(this.staticAccountKeys, accountKeysFromLookups);
}
isAccountSigner(index) {
return index < this.header.numRequiredSignatures;
}
isAccountWritable(index) {
const numSignedAccounts = this.header.numRequiredSignatures;
const numStaticAccountKeys = this.staticAccountKeys.length;
if (index >= numStaticAccountKeys) {
const lookupAccountKeysIndex = index - numStaticAccountKeys;
const numWritableLookupAccountKeys = this.addressTableLookups.reduce((count, lookup) => count + lookup.writableIndexes.length, 0);
return lookupAccountKeysIndex < numWritableLookupAccountKeys;
} else if (index >= this.header.numRequiredSignatures) {
const unsignedAccountIndex = index - numSignedAccounts;
const numUnsignedAccounts = numStaticAccountKeys - numSignedAccounts;
const numWritableUnsignedAccounts = numUnsignedAccounts - this.header.numReadonlyUnsignedAccounts;
return unsignedAccountIndex < numWritableUnsignedAccounts;
} else {
const numWritableSignedAccounts = numSignedAccounts - this.header.numReadonlySignedAccounts;
return index < numWritableSignedAccounts;
}
}
resolveAddressTableLookups(addressLookupTableAccounts) {
const accountKeysFromLookups = {
writable: [],
readonly: []
};
for (const tableLookup of this.addressTableLookups) {
const tableAccount = addressLookupTableAccounts.find(account => account.key.equals(tableLookup.accountKey));
if (!tableAccount) {
throw new Error(`Failed to find address lookup table account for table key ${tableLookup.accountKey.toBase58()}`);
}
for (const index of tableLookup.writableIndexes) {
if (index < tableAccount.state.addresses.length) {
accountKeysFromLookups.writable.push(tableAccount.state.addresses[index]);
} else {
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
}
}
for (const index of tableLookup.readonlyIndexes) {
if (index < tableAccount.state.addresses.length) {
accountKeysFromLookups.readonly.push(tableAccount.state.addresses[index]);
} else {
throw new Error(`Failed to find address for index ${index} in address lookup table ${tableLookup.accountKey.toBase58()}`);
}
}
}
return accountKeysFromLookups;
}
static compile(args) {
const compiledKeys = CompiledKeys.compile(args.instructions, args.payerKey);
const addressTableLookups = new Array();
const accountKeysFromLookups = {
writable: new Array(),
readonly: new Array()
};
const lookupTableAccounts = args.addressLookupTableAccounts || [];
for (const lookupTable of lookupTableAccounts) {
const extractResult = compiledKeys.extractTableLookup(lookupTable);
if (extractResult !== undefined) {
const [addressTableLookup, {
writable,
readonly
}] = extractResult;
addressTableLookups.push(addressTableLookup);
accountKeysFromLookups.writable.push(...writable);
accountKeysFromLookups.readonly.push(...readonly);
}
}
const [header, staticAccountKeys] = compiledKeys.getMessageComponents();
const accountKeys = new MessageAccountKeys(staticAccountKeys, accountKeysFromLookups);
const compiledInstructions = accountKeys.compileInstructions(args.instructions);
return new MessageV0({
header,
staticAccountKeys,
recentBlockhash: args.recentBlockhash,
compiledInstructions,
addressTableLookups
});
}
serialize() {
const encodedStaticAccountKeysLength = Array();
encodeLength(encodedStaticAccountKeysLength, this.staticAccountKeys.length);
const serializedInstructions = this.serializeInstructions();
const encodedInstructionsLength = Array();
encodeLength(encodedInstructionsLength, this.compiledInstructions.length);
const serializedAddressTableLookups = this.serializeAddressTableLookups();
const encodedAddressTableLookupsLength = Array();
encodeLength(encodedAddressTableLookupsLength, this.addressTableLookups.length);
const messageLayout = BufferLayout.struct([BufferLayout.u8('prefix'), BufferLayout.struct([BufferLayout.u8('numRequiredSignatures'), BufferLayout.u8('numReadonlySignedAccounts'), BufferLayout.u8('numReadonlyUnsignedAccounts')], 'header'), BufferLayout.blob(encodedStaticAccountKeysLength.length, 'staticAccountKeysLength'), BufferLayout.seq(publicKey(), this.staticAccountKeys.length, 'staticAccountKeys'), publicKey('recentBlockhash'), BufferLayout.blob(encodedInstructionsLength.length, 'instructionsLength'), BufferLayout.blob(serializedInstructions.length, 'serializedInstructions'), BufferLayout.blob(encodedAddressTableLookupsLength.length, 'addressTableLookupsLength'), BufferLayout.blob(serializedAddressTableLookups.length, 'serializedAddressTableLookups')]);
const serializedMessage = new Uint8Array(PACKET_DATA_SIZE);
const MESSAGE_VERSION_0_PREFIX = 1 << 7;
const serializedMessageLength = messageLayout.encode({
prefix: MESSAGE_VERSION_0_PREFIX,
header: this.header,
staticAccountKeysLength: new Uint8Array(encodedStaticAccountKeysLength),
staticAccountKeys: this.staticAccountKeys.map(key => key.toBytes()),
recentBlockhash: bs58.decode(this.recentBlockhash),
instructionsLength: new Uint8Array(encodedInstructionsLength),
serializedInstructions,
addressTableLookupsLength: new Uint8Array(encodedAddressTableLookupsLength),
serializedAddressTableLookups
}, serializedMessage);
return serializedMessage.slice(0, serializedMessageLength);
}
serializeInstructions() {
let serializedLength = 0;
const serializedInstructions = new Uint8Array(PACKET_DATA_SIZE);
for (const instruction of this.compiledInstructions) {
const encodedAccountKeyIndexesLength = Array();
encodeLength(encodedAccountKeyIndexesLength, instruction.accountKeyIndexes.length);
const encodedDataLength = Array();
encodeLength(encodedDataLength, instruction.data.length);
const instructionLayout = BufferLayout.struct([BufferLayout.u8('programIdIndex'), BufferLayout.blob(encodedAccountKeyIndexesLength.length, 'encodedAccountKeyIndexesLength'), BufferLayout.seq(BufferLayout.u8(), instruction.accountKeyIndexes.length, 'accountKeyIndexes'), BufferLayout.blob(encodedDataLength.length, 'encodedDataLength'), BufferLayout.blob(instruction.data.length, 'data')]);
serializedLength += instructionLayout.encode({
programIdIndex: instruction.programIdIndex,
encodedAccountKeyIndexesLength: new Uint8Array(encodedAccountKeyIndexesLength),
accountKeyIndexes: instruction.accountKeyIndexes,
encodedDataLength: new Uint8Array(encodedDataLength),
data: instruction.data
}, serializedInstructions, serializedLength);
}
return serializedInstructions.slice(0, serializedLength);
}
serializeAddressTableLookups() {
let serializedLength = 0;
const serializedAddressTableLookups = new Uint8Array(PACKET_DATA_SIZE);
for (const lookup of this.addressTableLookups) {
const encodedWritableIndexesLength = Array();
encodeLength(encodedWritableIndexesLength, lookup.writableIndexes.length);
const encodedReadonlyIndexesLength = Array();
encodeLength(encodedReadonlyIndexesLength, lookup.readonlyIndexes.length);
const addressTableLookupLayout = BufferLayout.struct([publicKey('accountKey'), BufferLayout.blob(encodedWritableIndexesLength.length, 'encodedWritableIndexesLength'), BufferLayout.seq(BufferLayout.u8(), lookup.writableIndexes.length, 'writableIndexes'), BufferLayout.blob(encodedReadonlyIndexesLength.length, 'encodedReadonlyIndexesLength'), BufferLayout.seq(BufferLayout.u8(), lookup.readonlyIndexes.length, 'readonlyIndexes')]);
serializedLength += addressTableLookupLayout.encode({
accountKey: lookup.accountKey.toBytes(),
encodedWritableIndexesLength: new Uint8Array(encodedWritableIndexesLength),
writableIndexes: lookup.writableIndexes,
encodedReadonlyIndexesLength: new Uint8Array(encodedReadonlyIndexesLength),
readonlyIndexes: lookup.readonlyIndexes
}, serializedAddressTableLookups, serializedLength);
}
return serializedAddressTableLookups.slice(0, serializedLength);
}
static deserialize(serializedMessage) {
let byteArray = [...serializedMessage];
const prefix = byteArray.shift();
const maskedPrefix = prefix & VERSION_PREFIX_MASK;
assert(prefix !== maskedPrefix, `Expected versioned message but received legacy message`);
const version = maskedPrefix;
assert(version === 0, `Expected versioned message with version 0 but found version ${version}`);
const header = {
numRequiredSignatures: byteArray.shift(),
numReadonlySignedAccounts: byteArray.shift(),
numReadonlyUnsignedAccounts: byteArray.shift()
};
const staticAccountKeys = [];
const staticAccountKeysLength = decodeLength(byteArray);
for (let i = 0; i < staticAccountKeysLength; i++) {
staticAccountKeys.push(new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH)));
}
const recentBlockhash = bs58.encode(byteArray.splice(0, PUBLIC_KEY_LENGTH));
const instructionCount = decodeLength(byteArray);
const compiledInstructions = [];
for (let i = 0; i < instructionCount; i++) {
const programIdIndex = byteArray.shift();
const accountKeyIndexesLength = decodeLength(byteArray);
const accountKeyIndexes = byteArray.splice(0, accountKeyIndexesLength);
const dataLength = decodeLength(byteArray);
const data = new Uint8Array(byteArray.splice(0, dataLength));
compiledInstructions.push({
programIdIndex,
accountKeyIndexes,
data
});
}
const addressTableLookupsCount = decodeLength(byteArray);
const addressTableLookups = [];
for (let i = 0; i < addressTableLookupsCount; i++) {
const accountKey = new PublicKey(byteArray.splice(0, PUBLIC_KEY_LENGTH));
const writableIndexesLength = decodeLength(byteArray);
const writableIndexes = byteArray.splice(0, writableIndexesLength);
const readonlyIndexesLength = decodeLength(byteArray);
const readonlyIndexes = byteArray.splice(0, readonlyIndexesLength);
addressTableLookups.push({
accountKey,
writableIndexes,
readonlyIndexes
});
}
return new MessageV0({
header,
staticAccountKeys,
recentBlockhash,
compiledInstructions,
addressTableLookups
});
}
}
// eslint-disable-next-line no-redeclare
const VersionedMessage = {
deserializeMessageVersion(serializedMessage) {
const prefix = serializedMessage[0];
const maskedPrefix = prefix & VERSION_PREFIX_MASK; // if the highest bit of the prefix is not set, the message is not versioned
if (maskedPrefix === prefix) {
return 'legacy';
} // the lower 7 bits of the prefix indicate the message version
return maskedPrefix;
},
deserialize: serializedMessage => {
const version = VersionedMessage.deserializeMessageVersion(serializedMessage);
if (version === 'legacy') {
return Message.from(serializedMessage);
}
if (version === 0) {
return MessageV0.deserialize(serializedMessage);
} else {
throw new Error(`Transaction message version ${version} deserialization is not supported`);
}
}
};
/**
* Transaction signature as base-58 encoded string
*/
let TransactionStatus;
/**
* Default (empty) signature
*/
(function (TransactionStatus) {
TransactionStatus[TransactionStatus["BLOCKHEIGHT_EXCEEDED"] = 0] = "BLOCKHEIGHT_EXCEEDED";
TransactionStatus[TransactionStatus["PROCESSED"] = 1] = "PROCESSED";
TransactionStatus[TransactionStatus["TIMED_OUT"] = 2] = "TIMED_OUT";
})(TransactionStatus || (TransactionStatus = {}));
const DEFAULT_SIGNATURE = Buffer$1.alloc(SIGNATURE_LENGTH_IN_BYTES).fill(0);
/**
* Account metadata used to define instructions
*/
/**
* Transaction Instruction class
*/
class TransactionInstruction {
/**
* Public keys to include in this transaction
* Boolean represents whether this pubkey needs to sign the transaction
*/
/**
* Program Id to execute
*/
/**
* Program input
*/
constructor(opts) {
this.keys = void 0;
this.programId = void 0;
this.data = Buffer$1.alloc(0);
this.programId = opts.programId;
this.keys = opts.keys;
if (opts.data) {
this.data = opts.data;
}
}
/**
* @internal
*/
toJSON() {
return {
keys: this.keys.map(({
pubkey,
isSigner,
isWritable
}) => ({
pubkey: pubkey.toJSON(),
isSigner,
isWritable
})),
programId: this.programId.toJSON(),
data: [...this.data]