Skip to content

Latest commit

 

History

History
218 lines (173 loc) · 7.89 KB

self-custodial-facebook.md

File metadata and controls

218 lines (173 loc) · 7.89 KB

Self-custodial Facebook

In this document, we will show how a developer can use Flare to test and interact with the Self-custodial Facebook example Anchor program. You can find more information about the program in its Anchor by Example tutorial.

For documentation of all of Flare's commands, see here.

Note: For beginners, we recommend starting with the on chain voting example.

Set-up

We assume Flare was installed and in the system path (or a binary is present in the working directory), see more information here. We provide a devnet deployment for you to test out the commands. Otherwise, feel free to use your own deployment instead.

  • Self-custodial Facebook (devnet): DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn

IDL

We will first start by grabbing a copy of the IDL. If you are using your own deployment, you can find it at the target/idl folder generated by Anchor. Otherwise, we can get it with Flare by:

flare fetch-idl --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn

Flare will create a file called DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn.json with the IDL. For simplicity, we will rename it to idl.json:

mv DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn.json idl.json

Creating our Facebook account

Generating the Program Derived Address

IDL of the instruction:

    {
      "name": "createFacebook",
      "accounts": [
        {
          "name": "signer",
          "isMut": true,
          "isSigner": true
        },
        {
          "name": "facebookAccount",
          "isMut": true,
          "isSigner": false,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "type": "string",
                "value": "self-custodial-facebook2"
              },
              {
                "kind": "account",
                "type": "publicKey",
                "path": "signer"
              }
            ]
          }
        },
        {
          "name": "systemProgram",
          "isMut": false,
          "isSigner": false
        }
      ],
      "args": [
        {
          "name": "name",
          "type": "string"
        },
        {
          "name": "status",
          "type": "string"
        },
        {
          "name": "twitter",
          "type": "string"
        }
      ]
    }

Looking at the IDL, we see that the createFacebook method requires three accounts: the signer, the facebookAccount, and the fixed systemProgram account. We will use our wallet address as the signer, and the address of the systemProgram is 11111111111111111111111111111111. For the facebookAccount, however, we can see it is marked as a pda, meaning Program Derived Address. This means its address is deterministically generated from a set of seeds, in this case, the string "self-custodial-facebook2" and the public key of the signer. Flare allows us to easily derive this address using the generate-pda command and providing it with a list of seeds:

flare generate-pda --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn self-custodial-facebook2,(your wallet address)

And we will get an output like this:

Epy6kvKYKcdFDTRG1ZHwW4R1vuKMRuSmWXxsajqER8UB
Bump: 255

The first line will be your facebookAccount address, and will be different. The second value is the bump, and we can ignore this for this case.

Calling the method

Now that we have all the account addresses, we can use Flare to call the program method with the call command. For this, we need to provide it with the account addresses, as well as the program address and method arguments. In this case, we will name our Facebook Anthias Labs, and set a corresponding status and twitter:

flare -c devnet call \
    --keypair keypair.json \
    --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn \
    --accounts (your wallet address),Epy6kvKYKcdFDTRG1ZHwW4R1vuKMRuSmWXxsajqER8UB,11111111111111111111111111111111 \
    --idl idl.json \
    -- createFacebook "Anthias Labs,Anthias Research,@anthiasxyz"

For the --accounts, we provide the signer, facebookAccount, and systemProgram as discussed above.

The last line indicates that we are calling the createFacebook method with three arguments in the order presented in the IDL, the name Anthias Labs, the status Anthias Research, and the Twitter @anthiasxyz. Notice the space between -- and createFacebook; it's just used to separate the Flare options from the actual method and arguments passed to the on-chain program.

If we ommited the --idl idl.json Flare would automatically download the published IDL. However, that would make the command call slower and would fail for programs where the IDL is not published.

Reading an account

Now, we can use Flare to read the state of our Facebook Account:

flare -c devnet read-account \
    --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn \
    --account Epy6kvKYKcdFDTRG1ZHwW4R1vuKMRuSmWXxsajqER8UB \
    --idl idl.json

Where --account is the Program Derived Address of our Facebook Account. We get an output like this:

{"authority":"CbteoRqP7iwDZvpKTci1hpeUVrajDjT61uXrGGGQApuL","bump":255,"name":"Anthias Labs","status":"Anthias Research","twitter":"@anthiasxyz"}

Updating the status

The program also has an updateStatus method, as specified in the IDL:

  {
      "name": "updateStatus",
      "accounts": [
        {
          "name": "signer",
          "isMut": true,
          "isSigner": true
        },
        {
          "name": "facebookAccount",
          "isMut": true,
          "isSigner": false,
          "pda": {
            "seeds": [
              {
                "kind": "const",
                "type": "string",
                "value": "self-custodial-facebook2"
              },
              {
                "kind": "account",
                "type": "publicKey",
                "path": "signer"
              }
            ]
          }
        }
      ],
      "args": [
        {
          "name": "newStatus",
          "type": "string"
        }
      ]
    }

As we can see, it takes the signer and facebookAccount addresses, and a single argument with the new status. Let's try to update our status to "Boutique blockchain r&d firm focused on public goods tooling and actionable research":

flare -c devnet call \
    --keypair keypair.json \
    --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn \
    --accounts (your wallet address),Epy6kvKYKcdFDTRG1ZHwW4R1vuKMRuSmWXxsajqER8UB \
    --idl idl.json \
    -- updateStatus "Boutique blockchain r&d firm focused on public goods tooling and actionable research"

Let's try to read the account again to see how it got updated:

flare -c devnet read-account \
    --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn \
    --account Epy6kvKYKcdFDTRG1ZHwW4R1vuKMRuSmWXxsajqER8UB \
    --idl idl.json

And we get:

{"authority":"CbteoRqP7iwDZvpKTci1hpeUVrajDjT61uXrGGGQApuL","bump":255,"name":"Anthias Labs","status":"Boutique blockchain r&d firm focused on public goods tooling and actionable research","twitter":"@anthiasxyz"}

Extra: Finding and reading someone's Facebook

We can write a short Bash script to find combine these tools in order to find and read any Facebook account:

#!/bin/bash

# Get the Facebook address by deriving the PDA and getting the first line (head -n1)
facebookAddress=$(flare generate-pda --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn self-custodial-facebook2,$1 | head -n1)

# Read the contents of that account
flare read-account --program DMUK1PVbLRrX8eK63K7F4jt31nnAQ5Vp8mgs7mnrbQNn --account $facebookAddress

You can find the script here, and run ./find-facebook.sh CbteoRqP7iwDZvpKTci1hpeUVrajDjT61uXrGGGQApuL to find the Anthias Facebook account!