Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4158fb7
refactor: compressed token program folder structure into light_token,…
ananas-block Jan 5, 2026
c17726b
refactor: remove ctoken prefix from file names
ananas-block Jan 5, 2026
d567e6e
refactor: compressed token program docs structure
ananas-block Jan 5, 2026
1917f52
fix: create ctoken account
ananas-block Jan 6, 2026
c4dff36
fix doc error codes
ananas-block Jan 6, 2026
9db54e8
refactor: unify process_compression_top_up with CalculateTopUp trait
ananas-block Jan 6, 2026
54a4461
fix: pinocchio token error conversion
ananas-block Jan 6, 2026
c889069
refactor: simplify ctoken account access with direct indexing
ananas-block Jan 6, 2026
bf219fb
fix: error conversions
ananas-block Jan 6, 2026
c72b0a9
fix stackframe issues
ananas-block Jan 6, 2026
13965d5
refactor and test check extensions transfer2
ananas-block Jan 7, 2026
e3b7bdb
refactor: remove CreateSplMint dead code and cleanup
ananas-block Jan 7, 2026
ff1f49b
refactor: validate CompressibleConfig state and simplify mint_output
ananas-block Jan 7, 2026
4abf946
fix comments
ananas-block Jan 7, 2026
4e4a709
fix feedback
ananas-block Jan 7, 2026
13d992b
fix js
ananas-block Jan 7, 2026
8c2e9f1
fix js tests
ananas-block Jan 7, 2026
4f2c674
fix: allow exactly MAX_COMPRESSIONS items in transfer2
ananas-block Jan 7, 2026
c74b901
fix: compressed token mint action and tests
ananas-block Jan 7, 2026
d1550ad
fix: adapt TypeScript MintAction layout to match Rust instruction data
ananas-block Jan 8, 2026
54c2523
review 1
SwenSchaeferjohann Jan 8, 2026
bbaad98
review 2
SwenSchaeferjohann Jan 9, 2026
e92701b
stash review fixes
ananas-block Jan 9, 2026
396f059
stash compress and close check refactor
ananas-block Jan 9, 2026
d9f1389
format and refactor
ananas-block Jan 9, 2026
4e637df
removed approve checked, refactored check extensions
ananas-block Jan 9, 2026
b3f0667
cleanup
ananas-block Jan 9, 2026
95f62bb
fix test
ananas-block Jan 10, 2026
0eec18a
refactor approve revoke, burn, mint to
ananas-block Jan 10, 2026
44b9c8e
fix: rent exemption in case that rent exemption sysvar changes
ananas-block Jan 10, 2026
0ed5625
fix: js tests
ananas-block Jan 10, 2026
05b5242
add decompress amount validation + tests
ananas-block Jan 10, 2026
39b9adf
add outof bounds check, add test_ata_decompress_with_mismatched_amoun…
ananas-block Jan 10, 2026
6a798a7
fix: explicit error on ATA derivation failure in decompress
ananas-block Jan 10, 2026
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
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ groth16-solana = { version = "0.2.0" }
bytemuck = { version = "1.19.0" }
arrayvec = "0.7"
tinyvec = "1.10.0"
pinocchio-token-program = { git= "https://github.com/Lightprotocol/token", rev="1bf7a9e525e753c3eb7bbf9971a26efbc23e5c73" }
pinocchio-token-program = { git= "https://github.com/Lightprotocol/token", rev="9ea04560a039d1a44f0411b5eaa7c0b79ed575ab" }
# Math and crypto
num-bigint = "0.4.6"
tabled = "0.20"
Expand Down
4 changes: 1 addition & 3 deletions js/compressed-token/src/v3/instructions/create-mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,6 @@ export function encodeCreateMintInstructionData(
leafIndex: 0,
proveByIndex: false,
rootIndex: params.rootIndex,
compressedAddress: Array.from(compressedAddress.toBytes()),
tokenPoolBump: 0,
tokenPoolIndex: 0,
maxTopUp: 0,
createMint: {
readOnlyAddressTrees: [0, 0, 0, 0],
Expand All @@ -144,6 +141,7 @@ export function encodeCreateMintInstructionData(
version: TokenDataVersion.ShaFlat,
cmintDecompressed: false,
mint: splMintPda,
compressedAddress: Array.from(compressedAddress.toBytes()),
},
mintAuthority: params.mintAuthority,
freezeAuthority: params.freezeAuthority,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ function encodeCompressedMintToInstructionData(
leafIndex: params.leafIndex,
proveByIndex: true,
rootIndex: params.rootIndex,
compressedAddress: Array.from(compressedAddress.toBytes()),
tokenPoolBump: 0,
tokenPoolIndex: 0,
maxTopUp: 0,
createMint: null,
actions: [
Expand All @@ -78,6 +75,7 @@ function encodeCompressedMintToInstructionData(
version: params.mintData.version,
cmintDecompressed: params.mintData.cmintDecompressed,
mint: params.mintData.splMint,
compressedAddress: Array.from(compressedAddress.toBytes()),
},
mintAuthority: params.mintData.mintAuthority,
freezeAuthority: params.mintData.freezeAuthority,
Expand Down
4 changes: 1 addition & 3 deletions js/compressed-token/src/v3/instructions/mint-to.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ function encodeMintToCTokenInstructionData(
leafIndex: params.leafIndex,
proveByIndex: true,
rootIndex: params.rootIndex,
compressedAddress: Array.from(compressedAddress.toBytes()),
tokenPoolBump: 0,
tokenPoolIndex: 0,
maxTopUp: 0,
createMint: null,
actions: [
Expand All @@ -73,6 +70,7 @@ function encodeMintToCTokenInstructionData(
version: params.mintData.version,
cmintDecompressed: params.mintData.cmintDecompressed,
mint: params.mintData.splMint,
compressedAddress: Array.from(compressedAddress.toBytes()),
},
mintAuthority: params.mintData.mintAuthority,
freezeAuthority: params.mintData.freezeAuthority,
Expand Down
4 changes: 1 addition & 3 deletions js/compressed-token/src/v3/instructions/update-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ function encodeUpdateMetadataInstructionData(
leafIndex: params.leafIndex,
proveByIndex: params.proof === null,
rootIndex: params.rootIndex,
compressedAddress: Array.from(compressedAddress.toBytes()),
tokenPoolBump: 0,
tokenPoolIndex: 0,
maxTopUp: 0,
createMint: null,
actions: [convertActionToBorsh(params.action)],
Expand All @@ -115,6 +112,7 @@ function encodeUpdateMetadataInstructionData(
version: mintInterface.mintContext!.version,
cmintDecompressed: mintInterface.mintContext!.cmintDecompressed,
mint: mintInterface.mintContext!.splMint,
compressedAddress: Array.from(compressedAddress.toBytes()),
},
mintAuthority: mintInterface.mint.mintAuthority,
freezeAuthority: mintInterface.mint.freezeAuthority,
Expand Down
4 changes: 1 addition & 3 deletions js/compressed-token/src/v3/instructions/update-mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ function encodeUpdateMintInstructionData(
leafIndex: params.leafIndex,
proveByIndex: params.proveByIndex,
rootIndex: params.rootIndex,
compressedAddress: Array.from(compressedAddress.toBytes()),
tokenPoolBump: 0,
tokenPoolIndex: 0,
maxTopUp: 0,
createMint: null,
actions: [action],
Expand All @@ -89,6 +86,7 @@ function encodeUpdateMintInstructionData(
cmintDecompressed:
params.mintInterface.mintContext!.cmintDecompressed,
mint: params.mintInterface.mintContext!.splMint,
compressedAddress: Array.from(compressedAddress.toBytes()),
},
mintAuthority: params.mintInterface.mint.mintAuthority,
freezeAuthority: params.mintInterface.mint.freezeAuthority,
Expand Down
17 changes: 2 additions & 15 deletions js/compressed-token/src/v3/layout/layout-mint-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ export const UpdateAuthorityLayout = struct([
option(publicKey(), 'newAuthority'),
]);

export const CreateSplMintActionLayout = struct([u8('mintBump')]);

export const MintToCTokenActionLayout = struct([
u8('accountIndex'),
u64('amount'),
Expand Down Expand Up @@ -74,7 +72,6 @@ export const ActionLayout = rustEnum([
MintToCompressedActionLayout.replicate('mintToCompressed'),
UpdateAuthorityLayout.replicate('updateMintAuthority'),
UpdateAuthorityLayout.replicate('updateFreezeAuthority'),
CreateSplMintActionLayout.replicate('createSplMint'),
MintToCTokenActionLayout.replicate('mintToCToken'),
UpdateMetadataFieldActionLayout.replicate('updateMetadataField'),
UpdateMetadataAuthorityActionLayout.replicate('updateMetadataAuthority'),
Expand Down Expand Up @@ -145,6 +142,7 @@ export const CompressedMintMetadataLayout = struct([
u8('version'),
bool('cmintDecompressed'),
publicKey('mint'),
array(u8(), 32, 'compressedAddress'),
]);

export const CompressedMintInstructionDataLayout = struct([
Expand All @@ -160,9 +158,6 @@ export const MintActionCompressedInstructionDataLayout = struct([
u32('leafIndex'),
bool('proveByIndex'),
u16('rootIndex'),
array(u8(), 32, 'compressedAddress'),
u8('tokenPoolBump'),
u8('tokenPoolIndex'),
u16('maxTopUp'),
option(CreateMintLayout, 'createMint'),
vec(ActionLayout, 'actions'),
Expand All @@ -176,7 +171,6 @@ const ActionLayoutV1 = rustEnum([
MintToCompressedActionLayout.replicate('mintToCompressed'),
UpdateAuthorityLayout.replicate('updateMintAuthority'),
UpdateAuthorityLayout.replicate('updateFreezeAuthority'),
CreateSplMintActionLayout.replicate('createSplMint'),
MintToCTokenActionLayout.replicate('mintToCToken'),
UpdateMetadataFieldActionLayout.replicate('updateMetadataField'),
UpdateMetadataAuthorityActionLayout.replicate('updateMetadataAuthority'),
Expand Down Expand Up @@ -233,10 +227,6 @@ export interface UpdateAuthority {
newAuthority: PublicKey | null;
}

export interface CreateSplMintAction {
mintBump: number;
}

export interface MintToCTokenAction {
accountIndex: number;
amount: bigint;
Expand Down Expand Up @@ -274,7 +264,6 @@ export type Action =
| { mintToCompressed: MintToCompressedAction }
| { updateMintAuthority: UpdateAuthority }
| { updateFreezeAuthority: UpdateAuthority }
| { createSplMint: CreateSplMintAction }
| { mintToCToken: MintToCTokenAction }
| { updateMetadataField: UpdateMetadataFieldAction }
| { updateMetadataAuthority: UpdateMetadataAuthorityAction }
Expand Down Expand Up @@ -320,6 +309,7 @@ export interface CompressedMintMetadata {
version: number;
cmintDecompressed: boolean;
mint: PublicKey;
compressedAddress: number[];
}

export interface CompressedMintInstructionData {
Expand All @@ -335,9 +325,6 @@ export interface MintActionCompressedInstructionData {
leafIndex: number;
proveByIndex: boolean;
rootIndex: number;
compressedAddress: number[];
tokenPoolBump: number;
tokenPoolIndex: number;
maxTopUp: number;
createMint: CreateMint | null;
actions: Action[];
Expand Down
20 changes: 19 additions & 1 deletion js/compressed-token/src/v3/layout/layout-mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,12 +157,16 @@ export interface CompressionInfo {
rentSponsor: PublicKey;
/** Last slot rent was claimed */
lastClaimedSlot: bigint;
/** Rent exemption lamports paid at account creation */
rentExemptionPaid: number;
/** Reserved for future use */
reserved: number;
/** Rent configuration */
rentConfig: RentConfig;
}

/** Byte length of CompressionInfo */
export const COMPRESSION_INFO_SIZE = 88; // 2 + 1 + 1 + 4 + 32 + 32 + 8 + 8
export const COMPRESSION_INFO_SIZE = 96; // 2 + 1 + 1 + 4 + 32 + 32 + 8 + 4 + 4 + 8

/**
* Calculate the byte length of a TokenMetadata extension from buffer.
Expand Down Expand Up @@ -256,6 +260,12 @@ function deserializeCompressionInfo(
const lastClaimedSlot = buffer.readBigUInt64LE(offset);
offset += 8;

// Read rent_exemption_paid (u32) and _reserved (u32)
const rentExemptionPaid = buffer.readUInt32LE(offset);
offset += 4;
const reserved = buffer.readUInt32LE(offset);
offset += 4;

// Read RentConfig (8 bytes)
const baseRent = buffer.readUInt16LE(offset);
offset += 2;
Expand Down Expand Up @@ -284,6 +294,8 @@ function deserializeCompressionInfo(
compressionAuthority,
rentSponsor,
lastClaimedSlot,
rentExemptionPaid,
reserved,
rentConfig,
};

Expand Down Expand Up @@ -416,6 +428,12 @@ function serializeCompressionInfo(compression: CompressionInfo): Buffer {
buffer.writeBigUInt64LE(compression.lastClaimedSlot, offset);
offset += 8;

// Write rent_exemption_paid (u32) and _reserved (u32)
buffer.writeUInt32LE(compression.rentExemptionPaid, offset);
offset += 4;
buffer.writeUInt32LE(compression.reserved, offset);
offset += 4;

// Write RentConfig (8 bytes)
buffer.writeUInt16LE(compression.rentConfig.baseRent, offset);
offset += 2;
Expand Down
4 changes: 4 additions & 0 deletions js/compressed-token/src/v3/layout/layout-transfer2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ const CompressionInfoLayout = struct([
array(u8(), 32, 'compressionAuthority'),
array(u8(), 32, 'rentSponsor'),
u64('lastClaimedSlot'),
u32('rentExemptionPaid'),
u32('reserved'),
RentConfigLayout.replicate('rentConfig'),
]);

Expand Down Expand Up @@ -255,6 +257,8 @@ function serializeExtensionInstructionData(
),
rentSponsor: Array.from(ext.data.rentSponsor.toBytes()),
lastClaimedSlot: bn(ext.data.lastClaimedSlot.toString()),
rentExemptionPaid: ext.data.rentExemptionPaid,
reserved: ext.data.reserved,
rentConfig: ext.data.rentConfig,
};
offset += CompressionInfoLayout.encode(data, buffer, offset);
Expand Down
2 changes: 2 additions & 0 deletions js/compressed-token/tests/e2e/unwrap.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ describe('createUnwrapInstruction', () => {
mint,
BigInt(1000),
tokenPoolInfo!,
TEST_TOKEN_DECIMALS,
);

expect(ix).toBeDefined();
Expand Down Expand Up @@ -125,6 +126,7 @@ describe('createUnwrapInstruction', () => {
mint,
BigInt(500),
tokenPoolInfo!,
TEST_TOKEN_DECIMALS,
feePayer.publicKey,
);

Expand Down
Loading