Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,30 @@ import {
type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM,
type SolanaError,
} from '@solana/kit';
import { SOLANA_FEATURE_GATE_PROGRAM_ADDRESS } from '../programs';
import { FEATURE_GATE_PROGRAM_ADDRESS } from '../programs';

/** FeatureAlreadyActivated: Feature already activated */
export const SOLANA_FEATURE_GATE_ERROR__FEATURE_ALREADY_ACTIVATED = 0x0; // 0
export const FEATURE_GATE_ERROR__FEATURE_ALREADY_ACTIVATED = 0x0; // 0

export type SolanaFeatureGateError =
typeof SOLANA_FEATURE_GATE_ERROR__FEATURE_ALREADY_ACTIVATED;
export type FeatureGateError =
typeof FEATURE_GATE_ERROR__FEATURE_ALREADY_ACTIVATED;

let solanaFeatureGateErrorMessages:
| Record<SolanaFeatureGateError, string>
| undefined;
let featureGateErrorMessages: Record<FeatureGateError, string> | undefined;
if (process.env['NODE_ENV'] !== 'production') {
solanaFeatureGateErrorMessages = {
[SOLANA_FEATURE_GATE_ERROR__FEATURE_ALREADY_ACTIVATED]: `Feature already activated`,
featureGateErrorMessages = {
[FEATURE_GATE_ERROR__FEATURE_ALREADY_ACTIVATED]: `Feature already activated`,
};
}

export function getSolanaFeatureGateErrorMessage(
code: SolanaFeatureGateError
): string {
export function getFeatureGateErrorMessage(code: FeatureGateError): string {
if (process.env['NODE_ENV'] !== 'production') {
return (
solanaFeatureGateErrorMessages as Record<SolanaFeatureGateError, string>
)[code];
return (featureGateErrorMessages as Record<FeatureGateError, string>)[code];
}

return 'Error message not available in production bundles.';
}

export function isSolanaFeatureGateError<
TProgramErrorCode extends SolanaFeatureGateError,
>(
export function isFeatureGateError<TProgramErrorCode extends FeatureGateError>(
error: unknown,
transactionMessage: {
instructions: Record<number, { programAddress: Address }>;
Expand All @@ -54,7 +46,7 @@ export function isSolanaFeatureGateError<
return isProgramError<TProgramErrorCode>(
error,
transactionMessage,
SOLANA_FEATURE_GATE_PROGRAM_ADDRESS,
FEATURE_GATE_PROGRAM_ADDRESS,
code
);
}
2 changes: 1 addition & 1 deletion clients/js/src/generated/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
* @see https://github.com/codama-idl/codama
*/

export * from './solanaFeatureGate';
export * from './featureGate';
11 changes: 5 additions & 6 deletions clients/js/src/generated/instructions/revokePendingActivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
getAccountMetaFactory,
type ResolvedInstructionAccount,
} from '@solana/kit/program-client-core';
import { SOLANA_FEATURE_GATE_PROGRAM_ADDRESS } from '../programs';
import { FEATURE_GATE_PROGRAM_ADDRESS } from '../programs';

export const REVOKE_PENDING_ACTIVATION_DISCRIMINATOR = 0;

Expand All @@ -43,7 +43,7 @@ export function getRevokePendingActivationDiscriminatorBytes(): ReadonlyUint8Arr
}

export type RevokePendingActivationInstruction<
TProgram extends string = typeof SOLANA_FEATURE_GATE_PROGRAM_ADDRESS,
TProgram extends string = typeof FEATURE_GATE_PROGRAM_ADDRESS,
TAccountFeature extends string | AccountMeta<string> = string,
TAccountIncinerator extends string | AccountMeta<string> = string,
TAccountSystemProgram extends string | AccountMeta<string> =
Expand Down Expand Up @@ -112,7 +112,7 @@ export function getRevokePendingActivationInstruction<
TAccountFeature extends string,
TAccountIncinerator extends string,
TAccountSystemProgram extends string,
TProgramAddress extends Address = typeof SOLANA_FEATURE_GATE_PROGRAM_ADDRESS,
TProgramAddress extends Address = typeof FEATURE_GATE_PROGRAM_ADDRESS,
>(
input: RevokePendingActivationInput<
TAccountFeature,
Expand All @@ -127,8 +127,7 @@ export function getRevokePendingActivationInstruction<
TAccountSystemProgram
> {
// Program address.
const programAddress =
config?.programAddress ?? SOLANA_FEATURE_GATE_PROGRAM_ADDRESS;
const programAddress = config?.programAddress ?? FEATURE_GATE_PROGRAM_ADDRESS;

// Original accounts.
const originalAccounts = {
Expand Down Expand Up @@ -165,7 +164,7 @@ export function getRevokePendingActivationInstruction<
}

export type ParsedRevokePendingActivationInstruction<
TProgram extends string = typeof SOLANA_FEATURE_GATE_PROGRAM_ADDRESS,
TProgram extends string = typeof FEATURE_GATE_PROGRAM_ADDRESS,
TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],
> = {
programAddress: Address<TProgram>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,41 +32,41 @@ import {
type RevokePendingActivationInput,
} from '../instructions';

export const SOLANA_FEATURE_GATE_PROGRAM_ADDRESS =
export const FEATURE_GATE_PROGRAM_ADDRESS =
'Feature111111111111111111111111111111111111' as Address<'Feature111111111111111111111111111111111111'>;

export enum SolanaFeatureGateInstruction {
export enum FeatureGateInstruction {
RevokePendingActivation,
}

export function identifySolanaFeatureGateInstruction(
export function identifyFeatureGateInstruction(
instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array
): SolanaFeatureGateInstruction {
): FeatureGateInstruction {
const data = 'data' in instruction ? instruction.data : instruction;
if (containsBytes(data, getU8Encoder().encode(0), 0)) {
return SolanaFeatureGateInstruction.RevokePendingActivation;
return FeatureGateInstruction.RevokePendingActivation;
}
throw new SolanaError(
SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION,
{ instructionData: data, programName: 'solanaFeatureGate' }
{ instructionData: data, programName: 'featureGate' }
);
}

export type ParsedSolanaFeatureGateInstruction<
export type ParsedFeatureGateInstruction<
TProgram extends string = 'Feature111111111111111111111111111111111111',
> = {
instructionType: SolanaFeatureGateInstruction.RevokePendingActivation;
instructionType: FeatureGateInstruction.RevokePendingActivation;
} & ParsedRevokePendingActivationInstruction<TProgram>;

export function parseSolanaFeatureGateInstruction<TProgram extends string>(
export function parseFeatureGateInstruction<TProgram extends string>(
instruction: Instruction<TProgram> & InstructionWithData<ReadonlyUint8Array>
): ParsedSolanaFeatureGateInstruction<TProgram> {
const instructionType = identifySolanaFeatureGateInstruction(instruction);
): ParsedFeatureGateInstruction<TProgram> {
const instructionType = identifyFeatureGateInstruction(instruction);
switch (instructionType) {
case SolanaFeatureGateInstruction.RevokePendingActivation: {
case FeatureGateInstruction.RevokePendingActivation: {
assertIsInstructionWithAccounts(instruction);
return {
instructionType: SolanaFeatureGateInstruction.RevokePendingActivation,
instructionType: FeatureGateInstruction.RevokePendingActivation,
...parseRevokePendingActivationInstruction(instruction),
};
}
Expand All @@ -75,34 +75,30 @@ export function parseSolanaFeatureGateInstruction<TProgram extends string>(
SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE,
{
instructionType: instructionType as string,
programName: 'solanaFeatureGate',
programName: 'featureGate',
}
);
}
}

export type SolanaFeatureGatePlugin = {
instructions: SolanaFeatureGatePluginInstructions;
};
export type FeatureGatePlugin = { instructions: FeatureGatePluginInstructions };

export type SolanaFeatureGatePluginInstructions = {
export type FeatureGatePluginInstructions = {
revokePendingActivation: (
input: RevokePendingActivationInput
) => ReturnType<typeof getRevokePendingActivationInstruction> &
SelfPlanAndSendFunctions;
};

export type SolanaFeatureGatePluginRequirements =
ClientWithTransactionPlanning & ClientWithTransactionSending;
export type FeatureGatePluginRequirements = ClientWithTransactionPlanning &
ClientWithTransactionSending;

export function solanaFeatureGateProgram() {
return <T extends SolanaFeatureGatePluginRequirements>(
export function featureGateProgram() {
return <T extends FeatureGatePluginRequirements>(
client: T
): Omit<T, 'solanaFeatureGate'> & {
solanaFeatureGate: SolanaFeatureGatePlugin;
} => {
): Omit<T, 'featureGate'> & { featureGate: FeatureGatePlugin } => {
return extendClient(client, {
solanaFeatureGate: <SolanaFeatureGatePlugin>{
featureGate: <FeatureGatePlugin>{
instructions: {
revokePendingActivation: (input) =>
addSelfPlanAndSendFunctions(
Expand Down
2 changes: 1 addition & 1 deletion clients/js/src/generated/programs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
* @see https://github.com/codama-idl/codama
*/

export * from './solanaFeatureGate';
export * from './featureGate';
13 changes: 5 additions & 8 deletions clients/js/test/_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import { createClient, lamports } from '@solana/kit';
import { litesvm } from '@solana/kit-plugin-litesvm';
import { airdropSigner, generatedSigner } from '@solana/kit-plugin-signer';

import {
SOLANA_FEATURE_GATE_PROGRAM_ADDRESS,
solanaFeatureGateProgram,
} from '../src';
import { FEATURE_GATE_PROGRAM_ADDRESS, featureGateProgram } from '../src';

const SOLANA_FEATURE_GATE_BINARY_PATH = path.resolve(
const FEATURE_GATE_BINARY_PATH = path.resolve(
__dirname,
'..',
'..',
Expand All @@ -29,10 +26,10 @@ export const createTestClient = () => {
// compiled `.so` file. This must run after the `litesvm()` plugin so
// that `client.svm` is available.
client.svm.addProgramFromFile(
SOLANA_FEATURE_GATE_PROGRAM_ADDRESS,
SOLANA_FEATURE_GATE_BINARY_PATH
FEATURE_GATE_PROGRAM_ADDRESS,
FEATURE_GATE_BINARY_PATH
);
return client;
})
.use(solanaFeatureGateProgram());
.use(featureGateProgram());
};
2 changes: 1 addition & 1 deletion clients/js/test/example.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ it('sets up a LiteSVM client with the feature-gate program', async () => {
const client = await createTestClient();

// Then the client exposes the feature-gate program plugin.
expect(client.solanaFeatureGate).toBeDefined();
expect(client.featureGate).toBeDefined();

// And the payer was funded via LiteSVM.
const { value: balance } = await client.rpc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
use {num_derive::FromPrimitive, thiserror::Error};

#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)]
pub enum SolanaFeatureGateError {
pub enum FeatureGateError {
/// 0 - Feature already activated
#[error("Feature already activated")]
FeatureAlreadyActivated = 0x0,
}

impl From<SolanaFeatureGateError> for solana_program_error::ProgramError {
fn from(e: SolanaFeatureGateError) -> Self {
impl From<FeatureGateError> for solana_program_error::ProgramError {
fn from(e: FeatureGateError) -> Self {
solana_program_error::ProgramError::Custom(e as u32)
}
}
4 changes: 2 additions & 2 deletions clients/rust/src/generated/errors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
//!
//! <https://github.com/codama-idl/codama>

pub(crate) mod solana_feature_gate;
pub(crate) mod feature_gate;

pub use self::solana_feature_gate::SolanaFeatureGateError;
pub use self::feature_gate::FeatureGateError;
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl RevokePendingActivation {
.unwrap();

solana_instruction::Instruction {
program_id: crate::SOLANA_FEATURE_GATE_ID,
program_id: crate::FEATURE_GATE_ID,
accounts,
data,
}
Expand Down Expand Up @@ -223,7 +223,7 @@ impl<'a, 'b> RevokePendingActivationCpi<'a, 'b> {
.unwrap();

let instruction = solana_instruction::Instruction {
program_id: crate::SOLANA_FEATURE_GATE_ID,
program_id: crate::FEATURE_GATE_ID,
accounts,
data,
};
Expand Down
4 changes: 2 additions & 2 deletions clients/rust/src/generated/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@

use solana_address::{address, Address};

/// `solana_feature_gate` program ID.
pub const SOLANA_FEATURE_GATE_ID: Address = address!("Feature111111111111111111111111111111111111");
/// `feature_gate` program ID.
pub const FEATURE_GATE_ID: Address = address!("Feature111111111111111111111111111111111111");
2 changes: 1 addition & 1 deletion clients/rust/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[allow(deprecated)] // needed until Codama stops implementing deprecated traits
mod generated;

pub use generated::{programs::SOLANA_FEATURE_GATE_ID as ID, *};
pub use generated::{programs::FEATURE_GATE_ID as ID, *};
2 changes: 1 addition & 1 deletion codama.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default {
before: [
{
from: 'codama#updateProgramsVisitor',
args: [{ solanaFeatureGateProgram: { name: 'solanaFeatureGate' } }],
args: [{ solanaFeatureGateProgram: { name: 'featureGate' } }],
},
],
scripts: {
Expand Down
Loading