-
-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add parsers for OKX DEX AggregationRouterV2
- add parser for Swap instruction - add parser for CommissionSplProxySwap instruction - merge program U6m2CDdhRg - fixes #8
- Loading branch information
Showing
12 changed files
with
1,116 additions
and
56 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package OKXDEXAggregationRouterV2 | ||
|
||
const Program = "6m2CDdhRgxpH4WjvdzxAYbGxwdGUz5MziiL5jek2kBma" | ||
const ProgramName = "OKX DEX: Aggregation Router V2" | ||
|
||
var CommissionSplProxySwapDiscriminator = [8]uint8{96, 67, 12, 151, 129, 164, 18, 71} | ||
var SwapDiscriminator = [8]uint8{65, 75, 63, 76, 235, 91, 91, 136} |
124 changes: 124 additions & 0 deletions
124
solana/programs/OKXDEXAggregationRouterV2/parsers/commissionSplProxySwap.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package parsers | ||
|
||
import ( | ||
"fmt" | ||
"github.com/0xjeffro/tx-parser/solana/globals" | ||
"github.com/0xjeffro/tx-parser/solana/programs/OKXDEXAggregationRouterV2" | ||
"github.com/0xjeffro/tx-parser/solana/programs/systemProgram" | ||
SystemProgramParsers "github.com/0xjeffro/tx-parser/solana/programs/systemProgram/parsers" | ||
"github.com/0xjeffro/tx-parser/solana/programs/tokenProgram" | ||
TokenProgramParsers "github.com/0xjeffro/tx-parser/solana/programs/tokenProgram/parsers" | ||
"github.com/0xjeffro/tx-parser/solana/types" | ||
) | ||
|
||
func CommissionSplProxySwapParser(result *types.ParsedResult, instruction types.Instruction) (*OKXDEXAggregationRouterV2.CommissionSplProxySwapAction, error) { | ||
|
||
var who string | ||
var fromToken, toToken string = globals.WSOL, globals.WSOL | ||
var fromTokenDecimals, toTokenDecimals uint64 = globals.SOLDecimals, globals.SOLDecimals | ||
var fromTokenAmount, toTokenAmount uint64 | ||
|
||
who = result.AccountList[instruction.Accounts[0]] | ||
fromToken = result.AccountList[instruction.Accounts[3]] | ||
toToken = result.AccountList[instruction.Accounts[4]] | ||
|
||
var fromTokenAccount, toTokenAccount string | ||
fromTokenAccount = result.AccountList[instruction.Accounts[1]] | ||
toTokenAccount = result.AccountList[instruction.Accounts[2]] | ||
|
||
// get index of this instruction | ||
var instructionIndex int | ||
for idx, instr := range result.RawTx.Transaction.Message.Instructions { | ||
if result.AccountList[instr.ProgramIDIndex] == OKXDEXAggregationRouterV2.Program && instr.Data == instruction.Data { | ||
instructionIndex = idx | ||
break | ||
} | ||
} | ||
|
||
// get all innerInstructions for this instruction | ||
var innerInstructions []types.Instruction | ||
for _, innerInstruction := range result.RawTx.Meta.InnerInstructions { | ||
if innerInstruction.Index == instructionIndex { | ||
innerInstructions = innerInstruction.Instructions | ||
break | ||
} | ||
} | ||
|
||
for _, instr := range innerInstructions { | ||
programId := result.AccountList[instr.ProgramIDIndex] | ||
switch programId { | ||
case systemProgram.Program: | ||
parsedData, err := SystemProgramParsers.InstructionRouter(result, instr) | ||
if err != nil { | ||
continue | ||
} | ||
switch p := parsedData.(type) { | ||
case *types.SystemProgramTransferAction: | ||
if p.From == fromTokenAccount { | ||
fromTokenAmount += p.Lamports | ||
} | ||
if p.To == toTokenAccount { | ||
toTokenAmount += p.Lamports | ||
} | ||
} | ||
case tokenProgram.Program: | ||
parsedData, err := TokenProgramParsers.InstructionRouter(result, instr) | ||
if err != nil { | ||
continue | ||
} | ||
switch p := parsedData.(type) { | ||
case *types.TokenProgramTransferAction: | ||
if p.From == fromTokenAccount { | ||
fromTokenAmount += p.Amount | ||
} | ||
if p.To == toTokenAccount { | ||
toTokenAmount += p.Amount | ||
} | ||
case *types.TokenProgramTransferCheckedAction: | ||
if p.From == fromTokenAccount { | ||
fromTokenAmount += p.Amount | ||
} | ||
if p.To == toTokenAccount { | ||
toTokenAmount += p.Amount | ||
} | ||
} | ||
default: | ||
continue | ||
} | ||
} | ||
|
||
var tokenBalances []types.TokenBalance | ||
tokenBalances = append(tokenBalances, result.RawTx.Meta.PreTokenBalances...) | ||
tokenBalances = append(tokenBalances, result.RawTx.Meta.PostTokenBalances...) | ||
|
||
for _, tokenBalance := range tokenBalances { | ||
account := result.AccountList[tokenBalance.AccountIndex] | ||
if account == fromTokenAccount { | ||
fromToken = tokenBalance.Mint | ||
fromTokenDecimals = tokenBalance.UITokenAmount.Decimals | ||
} else if account == toTokenAccount { | ||
toToken = tokenBalance.Mint | ||
toTokenDecimals = tokenBalance.UITokenAmount.Decimals | ||
} | ||
} | ||
|
||
fmt.Println("fromTokenAmount: ", fromTokenAmount) | ||
fmt.Println("toTokenAmount: ", toTokenAmount) | ||
|
||
action := OKXDEXAggregationRouterV2.CommissionSplProxySwapAction{ | ||
BaseAction: types.BaseAction{ | ||
ProgramID: OKXDEXAggregationRouterV2.Program, | ||
ProgramName: OKXDEXAggregationRouterV2.ProgramName, | ||
InstructionName: "CommissionSplProxySwap", | ||
}, | ||
Who: who, | ||
ToToken: toToken, | ||
FromToken: fromToken, | ||
ToTokenAmount: toTokenAmount, | ||
FromTokenAmount: fromTokenAmount, | ||
FromTokenDecimals: fromTokenDecimals, | ||
ToTokenDecimals: toTokenDecimals, | ||
} | ||
|
||
return &action, nil | ||
} |
31 changes: 31 additions & 0 deletions
31
solana/programs/OKXDEXAggregationRouterV2/parsers/index.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package parsers | ||
|
||
import ( | ||
"github.com/0xjeffro/tx-parser/solana/programs/OKXDEXAggregationRouterV2" | ||
"github.com/0xjeffro/tx-parser/solana/types" | ||
"github.com/mr-tron/base58" | ||
) | ||
|
||
func InstructionRouter(result *types.ParsedResult, instruction types.Instruction) (types.Action, error) { | ||
data := instruction.Data | ||
decode, err := base58.Decode(data) | ||
if err != nil { | ||
return nil, err | ||
} | ||
discriminator := *(*[8]byte)(decode[:8]) | ||
|
||
switch discriminator { | ||
case OKXDEXAggregationRouterV2.CommissionSplProxySwapDiscriminator: | ||
return CommissionSplProxySwapParser(result, instruction) | ||
case OKXDEXAggregationRouterV2.SwapDiscriminator: | ||
return SwapParser(result, instruction, decode) | ||
default: | ||
return types.UnknownAction{ | ||
BaseAction: types.BaseAction{ | ||
ProgramID: result.AccountList[instruction.ProgramIDIndex], | ||
ProgramName: OKXDEXAggregationRouterV2.ProgramName, | ||
InstructionName: "Unknown", | ||
}, | ||
}, nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package parsers | ||
|
||
import ( | ||
"encoding/binary" | ||
"github.com/0xjeffro/tx-parser/solana/programs/OKXDEXAggregationRouterV2" | ||
"github.com/0xjeffro/tx-parser/solana/types" | ||
"strconv" | ||
) | ||
|
||
func SwapParser(result *types.ParsedResult, instruction types.Instruction, decodedData []byte) (*OKXDEXAggregationRouterV2.SwapAction, error) { | ||
who := result.AccountList[instruction.Accounts[0]] | ||
fromToken := result.AccountList[instruction.Accounts[3]] | ||
toToken := result.AccountList[instruction.Accounts[4]] | ||
fromTokenAmount := binary.LittleEndian.Uint64(decodedData[8:16]) | ||
toTokenAmount := uint64(0) | ||
|
||
preTokenBalances := result.RawTx.Meta.PreTokenBalances | ||
postTokenBalances := result.RawTx.Meta.PostTokenBalances | ||
|
||
var preToTokenAmount, postToTokenAmount uint64 | ||
var fromTokenDecimals, toTokenDecimals uint64 | ||
for _, b := range preTokenBalances { | ||
if b.Mint == toToken && b.Owner == who { | ||
var err error | ||
preToTokenAmount, err = strconv.ParseUint(b.UITokenAmount.Amount, 10, 64) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
if b.Mint == fromToken { | ||
fromTokenDecimals = b.UITokenAmount.Decimals | ||
} | ||
if b.Mint == toToken { | ||
toTokenDecimals = b.UITokenAmount.Decimals | ||
} | ||
} | ||
for _, b := range postTokenBalances { | ||
if b.Mint == toToken && b.Owner == who { | ||
var err error | ||
postToTokenAmount, err = strconv.ParseUint(b.UITokenAmount.Amount, 10, 64) | ||
if err != nil { | ||
return nil, err | ||
} | ||
break | ||
} | ||
if b.Mint == fromToken { | ||
fromTokenDecimals = b.UITokenAmount.Decimals | ||
} | ||
if b.Mint == toToken { | ||
toTokenDecimals = b.UITokenAmount.Decimals | ||
} | ||
} | ||
toTokenAmount = postToTokenAmount - preToTokenAmount | ||
|
||
action := OKXDEXAggregationRouterV2.SwapAction{ | ||
BaseAction: types.BaseAction{ | ||
ProgramID: OKXDEXAggregationRouterV2.Program, | ||
ProgramName: OKXDEXAggregationRouterV2.ProgramName, | ||
InstructionName: "Swap", | ||
}, | ||
Who: who, | ||
FromToken: fromToken, | ||
ToToken: toToken, | ||
FromTokenAmount: fromTokenAmount, | ||
ToTokenAmount: toTokenAmount, | ||
FromTokenDecimals: fromTokenDecimals, | ||
ToTokenDecimals: toTokenDecimals, | ||
} | ||
return &action, nil | ||
} |
Oops, something went wrong.