Skip to content

Commit

Permalink
add SystemProgram: CreateAccountWithSeed Parser
Browse files Browse the repository at this point in the history
  • Loading branch information
0xjeffro committed Oct 4, 2024
1 parent 5546747 commit 7d344cb
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 112 deletions.
17 changes: 17 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,55 @@ module github.com/0xjeffro/tx-parser
go 1.19

require (
github.com/gagliardetto/solana-go v1.11.0
github.com/gin-gonic/gin v1.10.0
github.com/mr-tron/base58 v1.2.0
github.com/near/borsh-go v0.3.1
github.com/stretchr/testify v1.9.0
)

require (
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
github.com/blendle/zapdriver v1.3.1 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.9.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gagliardetto/binary v0.8.0 // indirect
github.com/gagliardetto/treeout v0.1.4 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
github.com/mattn/go-colorable v0.1.4 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
go.mongodb.org/mongo-driver v1.11.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
google.golang.org/protobuf v1.34.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
112 changes: 110 additions & 2 deletions go.sum

Large diffs are not rendered by default.

158 changes: 49 additions & 109 deletions solana/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,26 @@ import (
"testing"
)

func TestBrokenData_0(t *testing.T) {
jsonFile, err := os.Open("data/broken_data_0.json")
func readJsonFile(filename string) ([]byte, error) {
jsonFile, err := os.Open(filename)
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
return nil, err
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
return ioutil.ReadAll(jsonFile)
}

func TestBrokenData_0(t *testing.T) {
byteValue, err := readJsonFile("data/broken_data_0.json")
_, err = Parser(byteValue)
assert.NotEqual(t, err, nil)
}

func TestBrokenData_1(t *testing.T) {
jsonFile, err := os.Open("data/broken_data_1.json")
byteValue, err := readJsonFile("data/broken_data_1.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
t.Errorf("Error reading JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
results, err := Parser(byteValue)
assert.Equal(t, results[0].Actions[0].GetProgramID(), "Unknown")
assert.Equal(t, results[0].Actions[0].GetProgramName(), "Unknown")
Expand All @@ -41,15 +43,10 @@ func TestBrokenData_1(t *testing.T) {
}

func TestPumpFunSell_0(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_sell_0.json")
byteValue, err := readJsonFile("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
results, _ := Parser(byteValue)
action := results[0].Actions[3]
if sellAction, ok := action.(*types.PumpFunSellAction); ok {
Expand All @@ -67,12 +64,7 @@ func TestPumpFunSell_0(t *testing.T) {
}

func TestPumpFunBuy_0(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_buy_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/pumpfun_buy_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -94,12 +86,7 @@ func TestPumpFunBuy_0(t *testing.T) {
}

func TestPumpFunBuy_1(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_buy_1.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/pumpfun_buy_1.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -121,12 +108,7 @@ func TestPumpFunBuy_1(t *testing.T) {
}

func TestPumpFunCreate_0(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_create_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/pumpfun_create_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -152,12 +134,7 @@ func TestPumpFunCreate_0(t *testing.T) {
}

func TestComputeBudgetSetComputeUnitLimit(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -174,12 +151,7 @@ func TestComputeBudgetSetComputeUnitLimit(t *testing.T) {
}

func TestComputeBudgetSetComputeUnitPrice(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -196,12 +168,7 @@ func TestComputeBudgetSetComputeUnitPrice(t *testing.T) {
}

func TestSystemProgramTransfer(t *testing.T) {
jsonFile, err := os.Open("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/pumpfun_sell_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -219,13 +186,31 @@ func TestSystemProgramTransfer(t *testing.T) {
}
}

func TestTokenProgramTransfer(t *testing.T) {
jsonFile, err := os.Open("data/token_transfer_0.json")
func TestSystemProgramCreateAccountWithSeed(t *testing.T) {
byteValue, err := readJsonFile("data/raydiumLiquidityPoolV4_swap_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
t.Errorf("Error reading JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
results, _ := Parser(byteValue)
action := results[0].Actions[2]
if transferAction, ok := action.(*types.SystemProgramCreateAccountWithSeedAction); ok {
assert.Equal(t, transferAction.ProgramID, systemProgram.Program)
assert.Equal(t, transferAction.ProgramName, systemProgram.ProgramName)
assert.Equal(t, transferAction.InstructionName, "CreateAccountWithSeed")
assert.Equal(t, transferAction.Who, "Do3UdALe5F7NRXB4uYcBzZtCbAt8ssu4a5kGZVucKhC5")
assert.Equal(t, transferAction.NewAccount, "AgcEC7E1yxeZoRVnAZTmGA86ncrPTqKkBiz1T9F5MxhN")
assert.Equal(t, transferAction.Base, "Do3UdALe5F7NRXB4uYcBzZtCbAt8ssu4a5kGZVucKhC5")
assert.Equal(t, transferAction.Seed, "5PwC7hE3bfVrXbgN21qYnjizph1NWo7g")
assert.Equal(t, transferAction.Lamports, uint64(2039280))
assert.Equal(t, transferAction.Space, uint64(165))
assert.Equal(t, transferAction.Owner, "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
} else {
t.Errorf("Error type assertion")
}
}

func TestTokenProgramTransfer(t *testing.T) {
byteValue, err := readJsonFile("data/token_transfer_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -245,12 +230,7 @@ func TestTokenProgramTransfer(t *testing.T) {
}

func TestTokenProgramTransferChecked(t *testing.T) {
jsonFile, err := os.Open("data/transferChecked_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/transferChecked_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -272,12 +252,7 @@ func TestTokenProgramTransferChecked(t *testing.T) {
}

func TestTokenProgramInitializeAccount(t *testing.T) {
jsonFile, err := os.Open("data/raydiumLiquidityPoolV4_swap_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/raydiumLiquidityPoolV4_swap_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -298,12 +273,7 @@ func TestTokenProgramInitializeAccount(t *testing.T) {
}

func TestU6m2CDdhRgSwap(t *testing.T) {
jsonFile, err := os.Open("data/U6m2CDdhRg_swap_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/U6m2CDdhRg_swap_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -326,12 +296,7 @@ func TestU6m2CDdhRgSwap(t *testing.T) {
}

func TestU6m2CDdhRgSwap1(t *testing.T) {
jsonFile, err := os.Open("data/U6m2CDdhRg_swap_1.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/U6m2CDdhRg_swap_1.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -354,12 +319,7 @@ func TestU6m2CDdhRgSwap1(t *testing.T) {
}

func TestJupiterDcaOpenDcaV2_0(t *testing.T) {
jsonFile, err := os.Open("data/jupiterDca_openDcaV2_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/jupiterDca_openDcaV2_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand Down Expand Up @@ -389,12 +349,7 @@ func TestJupiterDcaOpenDcaV2_0(t *testing.T) {
}

func TestJupiterDcaOpenDcaV2_1(t *testing.T) {
jsonFile, err := os.Open("data/jupiterDca_openDcaV2_1.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/jupiterDca_openDcaV2_1.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand Down Expand Up @@ -424,12 +379,7 @@ func TestJupiterDcaOpenDcaV2_1(t *testing.T) {
}

func TestJupiterDcaEndAndClose_0(t *testing.T) {
jsonFile, err := os.Open("data/jupiterDca_endAndClose_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/jupiterDca_endAndClose_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -453,12 +403,7 @@ func TestJupiterDcaEndAndClose_0(t *testing.T) {
}

func TestJupiterDcaEndAndClose_1(t *testing.T) {
jsonFile, err := os.Open("data/jupiterDca_endAndClose_1.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/jupiterDca_endAndClose_1.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand All @@ -482,12 +427,7 @@ func TestJupiterDcaEndAndClose_1(t *testing.T) {
}

func TestJupiterDcaCloseDca_0(t *testing.T) {
jsonFile, err := os.Open("data/jupiterDca_CloseDca_0.json")
if err != nil {
t.Errorf("Error opening JSON file: %v", err)
}
defer jsonFile.Close()
byteValue, err := ioutil.ReadAll(jsonFile)
byteValue, err := readJsonFile("data/jupiterDca_CloseDca_0.json")
if err != nil {
t.Errorf("Error reading JSON file: %v", err)
}
Expand Down
1 change: 1 addition & 0 deletions solana/programs/systemProgram/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ const Program = "11111111111111111111111111111111"
const ProgramName = "System Program"

var TransferDiscriminator = uint32(2)
var CreateAccountWithSeedDiscriminator = uint32(3)
34 changes: 34 additions & 0 deletions solana/programs/systemProgram/parsers/createAccountWithSeed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package parsers

import (
"encoding/binary"
"github.com/0xjeffro/tx-parser/solana/programs/systemProgram"
"github.com/0xjeffro/tx-parser/solana/types"
solanago "github.com/gagliardetto/solana-go"
)

func CreateAccountWithSeedParser(result *types.ParsedResult, instruction types.Instruction, decodedData []byte) (*types.SystemProgramCreateAccountWithSeedAction, error) {
basePubKey := solanago.PublicKeyFromBytes(decodedData[4:36])
seedLength := binary.LittleEndian.Uint64(decodedData[36:44])
seed := string(decodedData[44 : 44+seedLength])
lamports := binary.LittleEndian.Uint64(decodedData[44+seedLength : 44+seedLength+8])
space := binary.LittleEndian.Uint64(decodedData[44+seedLength+8 : 44+seedLength+16])
ownerPubKey := solanago.PublicKeyFromBytes(decodedData[44+seedLength+16 : 44+seedLength+16+32])

action := types.SystemProgramCreateAccountWithSeedAction{
BaseAction: types.BaseAction{
ProgramID: result.AccountList[instruction.ProgramIDIndex],
ProgramName: systemProgram.ProgramName,
InstructionName: "CreateAccountWithSeed",
},
Who: result.AccountList[instruction.Accounts[0]],
NewAccount: result.AccountList[instruction.Accounts[1]],
Base: basePubKey.String(),
Seed: seed,
Lamports: lamports,
Space: space,
Owner: ownerPubKey.String(),
}

return &action, nil
}
Loading

0 comments on commit 7d344cb

Please sign in to comment.