Skip to main content
deleted 4 characters in body
Source Link
john
  • 7.8k
  • 2
  • 10
  • 26

Here are two references of transfer hook programs built using Anchor!

https://github.com/0ximalice/spl-token-2022-transfer-hook-anchor

https://github.com/TeamRaccoons/raccoons-program-library/tree/main/permissioned-token

It looks like the solution is to use the a fallback instruction in Anchor to work around the instruction discriminator.

Here's the fallback instructions for the two references:

First reference:


// Sha256(spl-transfer-hook-interface:execute)[..8]
pub const EXECUTE_IX_TAG_LE: [u8; 8] = [105, 37, 101, 197, 75, 251, 102, 26];

...

    pub fn fallback(program_id: &Pubkey, accounts: &[AccountInfo], ix_data: &[u8]) -> Result<()> {
        let mut ix_data: &[u8] = ix_data;
        let sighash: [u8; 8] = {
            let mut sighash: [u8; 8] = [0; 8];
            sighash.copy_from_slice(&ix_data[..8]);
            ix_data = &ix_data[8..];
            sighash
        };
        match sighash {
            EXECUTE_IX_TAG_LE => {__private::__global::transfer_hook(program_id, accounts, ix_data)},
            _ => Err(ProgramError::InvalidInstructionData.into()),
        }
    }

Second reference:

/// The fallback allows routing methods to match the transfer hook interface
    pub fn fallback(
        program_id: &Pubkey,
        accounts: &[AccountInfo],
        instruction_data: &[u8],
    ) -> Result<()> {
        if let Err(error) = processor::process(program_id, accounts, instruction_data) {
            // catch the error so we can print it
            error.print::<TransferHookError>();
            return Err(error.into());
        }

        Ok(())
    }
}

Here are two references of transfer hook programs built using Anchor!

https://github.com/0ximalice/spl-token-2022-transfer-hook-anchor

https://github.com/TeamRaccoons/raccoons-program-library/tree/main/permissioned-token

It looks like the solution is to use the a fallback instruction in Anchor to work around the instruction discriminator.

Here's the fallback instructions for the two references:

First reference:


// Sha256(spl-transfer-hook-interface:execute)[..8]
pub const EXECUTE_IX_TAG_LE: [u8; 8] = [105, 37, 101, 197, 75, 251, 102, 26];

...

    pub fn fallback(program_id: &Pubkey, accounts: &[AccountInfo], ix_data: &[u8]) -> Result<()> {
        let mut ix_data: &[u8] = ix_data;
        let sighash: [u8; 8] = {
            let mut sighash: [u8; 8] = [0; 8];
            sighash.copy_from_slice(&ix_data[..8]);
            ix_data = &ix_data[8..];
            sighash
        };
        match sighash {
            EXECUTE_IX_TAG_LE => {__private::__global::transfer_hook(program_id, accounts, ix_data)},
            _ => Err(ProgramError::InvalidInstructionData.into()),
        }
    }

Second reference:

/// The fallback allows routing methods to match the transfer hook interface
    pub fn fallback(
        program_id: &Pubkey,
        accounts: &[AccountInfo],
        instruction_data: &[u8],
    ) -> Result<()> {
        if let Err(error) = processor::process(program_id, accounts, instruction_data) {
            // catch the error so we can print it
            error.print::<TransferHookError>();
            return Err(error.into());
        }

        Ok(())
    }
}

Here are two references of transfer hook programs built using Anchor!

https://github.com/0ximalice/spl-token-2022-transfer-hook-anchor

https://github.com/TeamRaccoons/raccoons-program-library/tree/main/permissioned-token

It looks like the solution is to use a fallback instruction in Anchor to work around the instruction discriminator.

Here's the fallback instructions for the two references:

First reference:


// Sha256(spl-transfer-hook-interface:execute)[..8]
pub const EXECUTE_IX_TAG_LE: [u8; 8] = [105, 37, 101, 197, 75, 251, 102, 26];

...

    pub fn fallback(program_id: &Pubkey, accounts: &[AccountInfo], ix_data: &[u8]) -> Result<()> {
        let mut ix_data: &[u8] = ix_data;
        let sighash: [u8; 8] = {
            let mut sighash: [u8; 8] = [0; 8];
            sighash.copy_from_slice(&ix_data[..8]);
            ix_data = &ix_data[8..];
            sighash
        };
        match sighash {
            EXECUTE_IX_TAG_LE => {__private::__global::transfer_hook(program_id, accounts, ix_data)},
            _ => Err(ProgramError::InvalidInstructionData.into()),
        }
    }

Second reference:

/// The fallback allows routing methods to match the transfer hook interface
    pub fn fallback(
        program_id: &Pubkey,
        accounts: &[AccountInfo],
        instruction_data: &[u8],
    ) -> Result<()> {
        if let Err(error) = processor::process(program_id, accounts, instruction_data) {
            // catch the error so we can print it
            error.print::<TransferHookError>();
            return Err(error.into());
        }

        Ok(())
    }
}
Source Link
john
  • 7.8k
  • 2
  • 10
  • 26

Here are two references of transfer hook programs built using Anchor!

https://github.com/0ximalice/spl-token-2022-transfer-hook-anchor

https://github.com/TeamRaccoons/raccoons-program-library/tree/main/permissioned-token

It looks like the solution is to use the a fallback instruction in Anchor to work around the instruction discriminator.

Here's the fallback instructions for the two references:

First reference:


// Sha256(spl-transfer-hook-interface:execute)[..8]
pub const EXECUTE_IX_TAG_LE: [u8; 8] = [105, 37, 101, 197, 75, 251, 102, 26];

...

    pub fn fallback(program_id: &Pubkey, accounts: &[AccountInfo], ix_data: &[u8]) -> Result<()> {
        let mut ix_data: &[u8] = ix_data;
        let sighash: [u8; 8] = {
            let mut sighash: [u8; 8] = [0; 8];
            sighash.copy_from_slice(&ix_data[..8]);
            ix_data = &ix_data[8..];
            sighash
        };
        match sighash {
            EXECUTE_IX_TAG_LE => {__private::__global::transfer_hook(program_id, accounts, ix_data)},
            _ => Err(ProgramError::InvalidInstructionData.into()),
        }
    }

Second reference:

/// The fallback allows routing methods to match the transfer hook interface
    pub fn fallback(
        program_id: &Pubkey,
        accounts: &[AccountInfo],
        instruction_data: &[u8],
    ) -> Result<()> {
        if let Err(error) = processor::process(program_id, accounts, instruction_data) {
            // catch the error so we can print it
            error.print::<TransferHookError>();
            return Err(error.into());
        }

        Ok(())
    }
}