|
@@ -1,14 +1,15 @@
|
|
|
# Using token account data in transfer hook
|
|
|
|
|
|
-This examples shows you how you can use the token account data in the transfer
|
|
|
-hook. This is useful if you for example want to use the token account owner as a
|
|
|
-seed for a PDA.
|
|
|
+Sometimes you may want to use account data to derive additional accounts in the
|
|
|
+extra account metas. This is useful if, for example, you want to use the token
|
|
|
+account's owner as a seed for a PDA.
|
|
|
|
|
|
When creating the ExtraAccountMeta you can use the data of any account as an
|
|
|
extra seed. In this case we want to derive a counter account from the token
|
|
|
-account owner and the string 'counter'.
|
|
|
+account owner and the string 'counter'. This means we will be always able to see
|
|
|
+how often that token account owner has transferred tokens.
|
|
|
|
|
|
-This is how you set it up in the InitializeExtraAccountMetaList trait.
|
|
|
+This is how you set it up in the `extra_account_metas()` function.
|
|
|
|
|
|
```rust
|
|
|
// Define extra account metas to store on extra_account_meta_list account
|
|
@@ -32,10 +33,14 @@ impl<'info> InitializeExtraAccountMetaList<'info> {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-Lets look at the token account struct to understand how the account data is
|
|
|
-stored.This is how a token account looks like. So we can take 32 bytes at
|
|
|
-position 32 to 64 as the owner of the token account which is at 'account_index:
|
|
|
-0'.
|
|
|
+Let's look at the token account struct to understand how the account data is
|
|
|
+stored. Below is an example of a token account structure. So we can take 32
|
|
|
+bytes at position 32 to 64 as the owner of the token account, which is at
|
|
|
+'account_index: 0'. 'account_index` refers to the index of the account in the
|
|
|
+accounts array. In the case of a transfer hook, the owner token account is the
|
|
|
+first entry in the accounts array. The second account is always the mint and the
|
|
|
+third account is the destination token account. This account order is the same
|
|
|
+as in the old token program.
|
|
|
|
|
|
```rust
|
|
|
/// Account data.
|
|
@@ -56,8 +61,11 @@ pub struct Account {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-Now we need to put the extra account metas in the InitializeExtraAccountMetaList
|
|
|
-struct.
|
|
|
+I our case we want to derive a counter account from the owner of the sender
|
|
|
+token account so when we create the ExtraAccountMeta accounts we `init`this PDA
|
|
|
+counter account that is derived from the sender token account owner and the
|
|
|
+string 'counter'. When the PDA counter account is initialized we will be able to
|
|
|
+use it with in the transfer hook to increase it in every transfer.
|
|
|
|
|
|
```rust
|
|
|
#[derive(Accounts)]
|
|
@@ -85,7 +93,10 @@ pub struct InitializeExtraAccountMetaList<'info> {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-and then to the remaining accounts of the transfer hook accounts.
|
|
|
+We also need to define this extra counter account in the TransferHook struct.
|
|
|
+These are the accounts that are passed to our TransferHook program every time a
|
|
|
+transfer is done. The client get the additional accounts from the
|
|
|
+ExtraAccountsMetaList PDA but here in the program we still need to define it.
|
|
|
|
|
|
```rust
|
|
|
#[derive(Accounts)]
|
|
@@ -134,6 +145,11 @@ const [counterPDA] = PublicKey.findProgramAddressSync(
|
|
|
);
|
|
|
```
|
|
|
|
|
|
-The counter PDA in this case i created in the initialize hook. If you want this
|
|
|
-to work for every account you need to add some function on your website to
|
|
|
-create this account before hand probably.
|
|
|
+Note that the counter account is derived from the owner of the token account and
|
|
|
+needs to be initialized before doing a transfer. In the case of this example we
|
|
|
+initialize the counter account when we initialize the extra account metas. So we
|
|
|
+will only have a counter PDA for the owner of the token account that called that
|
|
|
+function. If you want to have a counter account for every token account for your
|
|
|
+mint out there you will need to have some functionality to create these PDAs
|
|
|
+before hand. There could be a button on your dapp to sign up for a counter that
|
|
|
+creates this PDA account and from then on the users can use this counter token.
|