Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transfer hook: Add JS support for managing hook programs #5974

Open
buffalojoec opened this issue Dec 10, 2023 · 5 comments
Open

transfer hook: Add JS support for managing hook programs #5974

buffalojoec opened this issue Dec 10, 2023 · 5 comments
Labels

Comments

@buffalojoec
Copy link
Contributor

buffalojoec commented Dec 10, 2023

Problem

Currently, we've got some of the minimally necessary "extra account metas" support within @solana/spl-token. However, the toolset isn't complete for those who wish to create and test a transfer hook program against the interface.

For example, the instructions one would use to hit their hook program and initialize or update extra account metas is not present in @solana/spl-token, nor is there support for creating ExtraAccountMeta types with packed seed configurations, etc.

Solution

I believe the best way to do this is to roll a @solana/spl-transfer-hook package and provide all of the necessary off-chain tooling from the Rust libraries.

Then, @solana/spl-token can use this package to offer it's various tooling that matches Token2022's crate.

@buffalojoec buffalojoec self-assigned this Dec 10, 2023
@buffalojoec buffalojoec removed their assignment Jan 26, 2024
@deepto98
Copy link

@buffalojoec Can I work on this if its still open?

@buffalojoec
Copy link
Contributor Author

Sure! But since this issue was opened we've added a good amount of transfer hook support to @solana/spl-token, so I don't think we need to do a new library like I laid out in the original description.

Right now, I'd say we need the two instructions for manipulating your program's list of extra account metas, and maybe some extra API sugar for serialization of extra metas. We can just add this stuff to the transfer-hook extension in Token JS.

What do you think?

@deepto98
Copy link

Sounds good, I'm new to Solana and would love to contribute. I looked at the code base and found these files:

@buffalojoec
Copy link
Contributor Author

@deepto98 You're close, but there's also an interface that Transfer Hook programs are implementing, and in order to create/update that program's list of extra required metas, we're going to add the two client-side instructions.

That interface can be found here.

https://github.com/solana-labs/solana-program-library/tree/6edf3ecc3f51a9f7a6faba9a1a4d30f1e4857e69/token/transfer-hook/interface

What I would suggest is creating a file src/extensions/transferHook/interface.ts and writing helpers for the InitializeExtraAccountMetaList and UpdateExtraAccountMetaList instructions for the interface.

Like the Rust instructions, we can simply require a list of ExtraAccountMeta as input to the instruction helpers, but those helpers will need to serialize them into instruction data.

To do that, they'll leverage the layouts here.

/** ExtraAccountMeta as stored by the transfer hook program */
export interface ExtraAccountMeta {
discriminator: number;
addressConfig: Uint8Array;
isSigner: boolean;
isWritable: boolean;
}
/** Buffer layout for de/serializing an ExtraAccountMeta */
export const ExtraAccountMetaLayout = struct<ExtraAccountMeta>([
u8('discriminator'),
blob(32, 'addressConfig'),
bool('isSigner'),
bool('isWritable'),
]);
export interface ExtraAccountMetaList {
count: number;
extraAccounts: ExtraAccountMeta[];
}
/** Buffer layout for de/serializing a list of ExtraAccountMeta prefixed by a u32 length */
export const ExtraAccountMetaListLayout = struct<ExtraAccountMetaList>([
u32('count'),
seq<ExtraAccountMeta>(ExtraAccountMetaLayout, greedy(ExtraAccountMetaLayout.span), 'extraAccounts'),
]);
/** Buffer layout for de/serializing a list of ExtraAccountMetaAccountData prefixed by a u32 length */
export interface ExtraAccountMetaAccountData {
instructionDiscriminator: bigint;
length: number;
extraAccountsList: ExtraAccountMetaList;
}
/** Buffer layout for de/serializing an ExtraAccountMetaAccountData */
export const ExtraAccountMetaAccountDataLayout = struct<ExtraAccountMetaAccountData>([
u64('instructionDiscriminator'),
u32('length'),
ExtraAccountMetaListLayout.replicate('extraAccountsList'),
]);

@deepto98
Copy link

@buffalojoec Thanks for the pointers, I'll go through these and try to understand the architecture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants