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
5 changes: 5 additions & 0 deletions .changeset/polite-women-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solana-program/token-wrap": patch
---

Update CreateMint helper to support token-2022 extension sizing
5 changes: 5 additions & 0 deletions .changeset/tiny-dancers-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@solana-program/token-wrap": minor
---

Bump deps to Kit 3.0
10 changes: 5 additions & 5 deletions clients/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@
"url": "https://github.com/solana-program/token-wrap/issues"
},
"peerDependencies": {
"@solana/kit": "^2.2.1"
"@solana/kit": "^3.0.1"
},
"dependencies": {
"@solana-program/system": "^0.7.0",
"@solana-program/system": "^0.8.0",
"@solana-program/token": "^0.5.1",
"@solana-program/token-2022": "^0.4.2",
"@solana/accounts": "^3.0.1",
"@solana/rpc-types": "^2.3.0"
"@solana/rpc-types": "^3.0.1"
},
"devDependencies": {
"@eslint/js": "^9.34.0",
"@solana/kit": "^2.2.1",
"@solana/kit": "^3.0.1",
"@tsconfig/strictest": "^2.0.5",
"@types/node": "^24.3.0",
"eslint": "^9.34.0",
Expand All @@ -65,5 +65,5 @@
"typescript": "^5.9.2",
"typescript-eslint": "^8.41.0"
},
"packageManager": "pnpm@9.1.0"
"packageManager": "pnpm@10.15.0"
}
30 changes: 25 additions & 5 deletions clients/js/src/create-mint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import {
fetchEncodedAccount,
GetAccountInfoApi,
GetMinimumBalanceForRentExemptionApi,
IInstruction,
Instruction,
KeyPairSigner,
Rpc,
} from '@solana/kit';
import { getMintSize } from '@solana-program/token-2022';
import { getMintSize, TOKEN_2022_PROGRAM_ADDRESS, extension } from '@solana-program/token-2022';
import { getTransferSolInstruction } from '@solana-program/system';
import {
findBackpointerPda,
Expand All @@ -29,9 +29,25 @@ export interface CreateMintResult {
backpointer: Address;
fundedWrappedMintLamports: bigint;
fundedBackpointerLamports: bigint;
ixs: IInstruction[];
ixs: Instruction[];
}

// The on-chain program adds these two extensions by default. We must account for
// their size here. The `getMintSize` function from the library expects extension
// data objects, but since the size of these extensions is fixed, we can pass
// dummy/default values.
const DEFAULT_EXTENSIONS = [
extension('ConfidentialTransferMint', {
autoApproveNewAccounts: true,
authority: null,
auditorElgamalPubkey: null,
}),
extension('MetadataPointer', {
authority: null,
metadataAddress: null,
}),
];

export async function createMint({
rpc,
unwrappedMint,
Expand All @@ -45,12 +61,16 @@ export async function createMint({
});
const [backpointer] = await findBackpointerPda({ wrappedMint });

const instructions: IInstruction[] = [];
const instructions: Instruction[] = [];

// Fund wrapped mint account if needed
let fundedWrappedMintLamports = 0n;

const mintSize = BigInt(getMintSize());
let mintSize = BigInt(getMintSize());
if (wrappedTokenProgram === TOKEN_2022_PROGRAM_ADDRESS) {
mintSize = BigInt(getMintSize(DEFAULT_EXTENSIONS));
}

const [wrappedMintAccount, wrappedMintRent] = await Promise.all([
fetchEncodedAccount(rpc, wrappedMint),
rpc.getMinimumBalanceForRentExemption(mintSize).send(),
Expand Down
4 changes: 4 additions & 0 deletions clients/js/src/examples/multisig.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
address,
appendTransactionMessageInstructions,
assertIsSendableTransaction,
createKeyPairSignerFromBytes,
createNoopSigner,
createSolanaRpc,
Expand Down Expand Up @@ -78,6 +79,7 @@ async function main() {
tx => appendTransactionMessageInstructions(createMintHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(createMintTx);
await sendAndConfirm(createMintTx, { commitment: 'confirmed' });
const createMintSignature = getSignatureFromTransaction(createMintTx);

Expand Down Expand Up @@ -105,6 +107,7 @@ async function main() {
tx => appendTransactionMessageInstructions(createEscrowHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(createEscrowTx);
await sendAndConfirm(createEscrowTx, { commitment: 'confirmed' });
const createEscrowSignature = getSignatureFromTransaction(createEscrowTx);

Expand Down Expand Up @@ -134,6 +137,7 @@ async function main() {
tx => appendTransactionMessageInstructions(recipientTokenAccountHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(recipientTokenAccountTx);
await sendAndConfirm(recipientTokenAccountTx, { commitment: 'confirmed' });

const unwrappedTokenProgram = await getOwnerFromAccount(rpc, UNWRAPPED_TOKEN_ACCOUNT);
Expand Down
6 changes: 6 additions & 0 deletions clients/js/src/examples/single-signer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
address,
appendTransactionMessageInstructions,
assertIsSendableTransaction,
createKeyPairSignerFromBytes,
createSolanaRpc,
createSolanaRpcSubscriptions,
Expand Down Expand Up @@ -56,6 +57,7 @@ async function main() {
tx => appendTransactionMessageInstructions(createMintHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(createMintTx);
await sendAndConfirm(createMintTx, { commitment: 'confirmed' });
const createMintSignature = getSignatureFromTransaction(createMintTx);

Expand Down Expand Up @@ -83,6 +85,7 @@ async function main() {
tx => appendTransactionMessageInstructions(createEscrowHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(createEscrowTx);
await sendAndConfirm(createEscrowTx, { commitment: 'confirmed' });
const createEscrowSignature = getSignatureFromTransaction(createEscrowTx);

Expand Down Expand Up @@ -112,6 +115,7 @@ async function main() {
tx => appendTransactionMessageInstructions(recipientTokenAccountHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(recipientTokenAccountTx);
await sendAndConfirm(recipientTokenAccountTx, { commitment: 'confirmed' });

// Execute wrap
Expand All @@ -132,6 +136,7 @@ async function main() {
tx => appendTransactionMessageInstructions(wrapHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(wrapTx);
await sendAndConfirm(wrapTx, { commitment: 'confirmed' });
const wrapSignature = getSignatureFromTransaction(wrapTx);

Expand All @@ -158,6 +163,7 @@ async function main() {
tx => appendTransactionMessageInstructions(unwrapHelper.ixs, tx),
tx => signTransactionMessageWithSigners(tx),
);
assertIsSendableTransaction(unwrapTx);
await sendAndConfirm(unwrapTx, { commitment: 'confirmed' });
const unwrapSignature = getSignatureFromTransaction(unwrapTx);

Expand Down
15 changes: 9 additions & 6 deletions clients/js/src/generated/accounts/backpointer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ import {
getStructEncoder,
type Account,
type Address,
type Codec,
type Decoder,
type EncodedAccount,
type Encoder,
type FetchAccountConfig,
type FetchAccountsConfig,
type FixedSizeCodec,
type FixedSizeDecoder,
type FixedSizeEncoder,
type MaybeAccount,
type MaybeEncodedAccount,
} from '@solana/kit';
Expand All @@ -34,15 +34,18 @@ export type Backpointer = { unwrappedMint: Address };

export type BackpointerArgs = Backpointer;

export function getBackpointerEncoder(): Encoder<BackpointerArgs> {
export function getBackpointerEncoder(): FixedSizeEncoder<BackpointerArgs> {
return getStructEncoder([['unwrappedMint', getAddressEncoder()]]);
}

export function getBackpointerDecoder(): Decoder<Backpointer> {
export function getBackpointerDecoder(): FixedSizeDecoder<Backpointer> {
return getStructDecoder([['unwrappedMint', getAddressDecoder()]]);
}

export function getBackpointerCodec(): Codec<BackpointerArgs, Backpointer> {
export function getBackpointerCodec(): FixedSizeCodec<
BackpointerArgs,
Backpointer
> {
return combineCodec(getBackpointerEncoder(), getBackpointerDecoder());
}

Expand Down
53 changes: 27 additions & 26 deletions clients/js/src/generated/instructions/closeStuckEscrow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ import {
getU8Decoder,
getU8Encoder,
transformEncoder,
type AccountMeta,
type Address,
type Codec,
type Decoder,
type Encoder,
type IAccountMeta,
type IInstruction,
type IInstructionWithAccounts,
type IInstructionWithData,
type FixedSizeCodec,
type FixedSizeDecoder,
type FixedSizeEncoder,
type Instruction,
type InstructionWithAccounts,
type InstructionWithData,
type ReadonlyAccount,
type ReadonlyUint8Array,
type WritableAccount,
} from '@solana/kit';
import { TOKEN_WRAP_PROGRAM_ADDRESS } from '../programs';
Expand All @@ -35,18 +36,18 @@ export function getCloseStuckEscrowDiscriminatorBytes() {

export type CloseStuckEscrowInstruction<
TProgram extends string = typeof TOKEN_WRAP_PROGRAM_ADDRESS,
TAccountEscrow extends string | IAccountMeta<string> = string,
TAccountDestination extends string | IAccountMeta<string> = string,
TAccountUnwrappedMint extends string | IAccountMeta<string> = string,
TAccountWrappedMint extends string | IAccountMeta<string> = string,
TAccountWrappedMintAuthority extends string | IAccountMeta<string> = string,
TAccountEscrow extends string | AccountMeta<string> = string,
TAccountDestination extends string | AccountMeta<string> = string,
TAccountUnwrappedMint extends string | AccountMeta<string> = string,
TAccountWrappedMint extends string | AccountMeta<string> = string,
TAccountWrappedMintAuthority extends string | AccountMeta<string> = string,
TAccountToken2022Program extends
| string
| IAccountMeta<string> = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
> = IInstruction<TProgram> &
IInstructionWithData<Uint8Array> &
IInstructionWithAccounts<
| AccountMeta<string> = 'TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb',
TRemainingAccounts extends readonly AccountMeta<string>[] = [],
> = Instruction<TProgram> &
InstructionWithData<ReadonlyUint8Array> &
InstructionWithAccounts<
[
TAccountEscrow extends string
? WritableAccount<TAccountEscrow>
Expand Down Expand Up @@ -74,18 +75,18 @@ export type CloseStuckEscrowInstructionData = { discriminator: number };

export type CloseStuckEscrowInstructionDataArgs = {};

export function getCloseStuckEscrowInstructionDataEncoder(): Encoder<CloseStuckEscrowInstructionDataArgs> {
export function getCloseStuckEscrowInstructionDataEncoder(): FixedSizeEncoder<CloseStuckEscrowInstructionDataArgs> {
return transformEncoder(
getStructEncoder([['discriminator', getU8Encoder()]]),
(value) => ({ ...value, discriminator: CLOSE_STUCK_ESCROW_DISCRIMINATOR })
);
}

export function getCloseStuckEscrowInstructionDataDecoder(): Decoder<CloseStuckEscrowInstructionData> {
export function getCloseStuckEscrowInstructionDataDecoder(): FixedSizeDecoder<CloseStuckEscrowInstructionData> {
return getStructDecoder([['discriminator', getU8Decoder()]]);
}

export function getCloseStuckEscrowInstructionDataCodec(): Codec<
export function getCloseStuckEscrowInstructionDataCodec(): FixedSizeCodec<
CloseStuckEscrowInstructionDataArgs,
CloseStuckEscrowInstructionData
> {
Expand Down Expand Up @@ -200,7 +201,7 @@ export function getCloseStuckEscrowInstruction<

export type ParsedCloseStuckEscrowInstruction<
TProgram extends string = typeof TOKEN_WRAP_PROGRAM_ADDRESS,
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[],
> = {
programAddress: Address<TProgram>;
accounts: {
Expand All @@ -222,19 +223,19 @@ export type ParsedCloseStuckEscrowInstruction<

export function parseCloseStuckEscrowInstruction<
TProgram extends string,
TAccountMetas extends readonly IAccountMeta[],
TAccountMetas extends readonly AccountMeta[],
>(
instruction: IInstruction<TProgram> &
IInstructionWithAccounts<TAccountMetas> &
IInstructionWithData<Uint8Array>
instruction: Instruction<TProgram> &
InstructionWithAccounts<TAccountMetas> &
InstructionWithData<ReadonlyUint8Array>
): ParsedCloseStuckEscrowInstruction<TProgram, TAccountMetas> {
if (instruction.accounts.length < 6) {
// TODO: Coded error.
throw new Error('Not enough accounts');
}
let accountIndex = 0;
const getNextAccount = () => {
const accountMeta = instruction.accounts![accountIndex]!;
const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
accountIndex += 1;
return accountMeta;
};
Expand Down
Loading