Skip to content
New issue

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

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

Already on GitHub? # to your account

Feature Proposal: Account-Side Transfer Hook Extension #124

Open
tonton-sol opened this issue Jan 27, 2025 · 4 comments
Open

Feature Proposal: Account-Side Transfer Hook Extension #124

tonton-sol opened this issue Jan 27, 2025 · 4 comments

Comments

@tonton-sol
Copy link
Contributor

Proposed Feature

Introduce an account-side transfer-hook extension that allows each individual token account to define its own logic for approving or rejecting token transfers and other logic/cpi's. Rather than specifying a single global hook at the mint level, this new extension places a reference to a hook program directly in each token account’s data. Whenever a transfer involves that account, the token program would call into the specified hook to run user-defined checks and actions before finalizing the transfer. If the hook signals disapproval, the transfer halts.

Why Is This Needed

Current approaches to token-level customization often rely on a mint-side transfer hook with separate per account configurations, forcing all accounts under that mint to share the same limited policy or logic options. This can lead to conflicts between different users’ preferences and complicate scenarios where users need accounts with unique or specialized requirements (e.g., pay a fee, log statistics, or block specific transfers) not covered in the configuration. By localizing the logic on the account-side, the extension would let each owner adopt a unique set of conditions without impacting other accounts or rewriting the entire mint-side transfer hook. This finer-grained autonomy is especially valuable in multi-financial-entity environments where distinct operational or compliance rules may be necessary.

Proposed Solution

A new field in the token account structure, called something like transfer_hook_program, would store the public key of a custom hook program. Whenever a token transfer is executed, the token program performs a cross-program invocation (CPI) to both the sender’s and receiver’s hook programs. Each hook operates exactly the same as the existing transfer hook extension, i.e. can inspect details such as the source address, destination address, transferred amount, or any additional data the developer chooses to provide. If either hook issues an error, the transfer reverts; otherwise, it proceeds as normal.

This solution maintains the existing pattern of cross-program invocations during transfers but relocates the hook reference from the mint to the account. Users remain free to keep this field unset if they do not require specialized logic. By supporting distinct hooks per account, the extension delivers maximum flexibility and reduces the need for a single “one-size-fits-all” policy at the mint level.

Other Considerations

  • Since the account-side transfer hook is optional, the sender could also perform all checks and other operation client side before the transfer.
  • There could be a compatibility issue if a mint allows both the mint-side and account-side transfer hooks.
  • If both the sender and receiver hooks are executed on transfer there could be conflicts.
  • Increases the attack surface area for the same mint as there are many possibly unique transfer-hooks.
@buffalojoec
Copy link
Contributor

Hey @tonton-sol thanks for writing this up! A few questions/comments from my side.

Since the account-side transfer hook is optional, the sender could also perform all checks and other operation client side before the transfer.

Assuming you mean the client would check for the presence of the extension before attempting a transfer, similar to the Token client and the existing transfer hook extension?

There could be a compatibility issue if a mint allows both the mint-side and account-side transfer hooks.

How do you propose handling a situation where a mint hook and an account hook are both present; execute both or let one usurp the other? Furthermore, we would also want to consider an extension for mints that disallows the creation of account-side transfer hooks, if the mint issuer so desired.


In general, I am apprehensive about this only because it adds a lot of complexity and can cause transfer transactions to get seriously large/complex (imagine a transfer with a mint hook and two account hooks).

However, I can see a few benefits for this in situations where a protocol doesn't have control over some mint (therefore also its transfer hook program, if any) it wishes to include in tracking/compliance. I'd like to see what discussion we can generate about it here first!

@tonton-sol
Copy link
Contributor Author

Assuming you mean the client would check for the presence of the extension before attempting a transfer, similar to the Token client and the existing transfer hook extension?

I mean that everything the sender transfer hook would do could just be done as an instruction before the transfer.

How do you propose handling a situation where a mint hook and an account hook are both present; execute both or let one usurp the other?

Ideally both would be executed in some predefined order by the token program.

Furthermore, we would also want to consider an extension for mints that disallows the creation of account-side transfer hooks, if the mint issuer so desired.

I believe this could just be done by not enabling the account-side transfer hook extension for the mint.


I think minimally a receiver-side transfer hook would be interesting compliance wise. For example, I as the receiver could create a "payment escrow" type account that only expects certain amounts of tokens from certain senders.

@buffalojoec
Copy link
Contributor

I believe this could just be done by not enabling the account-side transfer hook extension for the mint.

Ah, maybe I misread your initial post. So you want to have a mint-side extension that will enable account-side transfer hook extensions? In other words, if I want to add a transfer hook to my token account, the mint has to have AccountSideExtensionsAllowed (or whatever)?

@tonton-sol
Copy link
Contributor Author

Ah, maybe I misread your initial post. So you want to have a mint-side extension that will enable account-side transfer hook extensions? In other words, if I want to add a transfer hook to my token account, the mint has to have AccountSideExtensionsAllowed (or whatever)?

Yes exactly! Another interesting use case would be the ability for the account owner to "lock" their account.

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

No branches or pull requests

2 participants