1
1
package async_geyser
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
6
7
"github.com/mr-tron/base58"
7
8
"github.com/pkg/errors"
8
9
9
10
geyserpb "github.com/code-payments/code-server/pkg/code/async/geyser/api/gen"
11
+ indexerpb "github.com/code-payments/code-vm-indexer/generated/indexer/v1"
10
12
13
+ "github.com/code-payments/code-server/pkg/code/common"
11
14
code_data "github.com/code-payments/code-server/pkg/code/data"
12
15
"github.com/code-payments/code-server/pkg/solana/token"
13
16
)
@@ -25,110 +28,95 @@ type ProgramAccountUpdateHandler interface {
25
28
}
26
29
27
30
type TokenProgramAccountHandler struct {
28
- conf * conf
29
- data code_data.Provider
31
+ conf * conf
32
+ data code_data.Provider
33
+ vmIndexerClient indexerpb.IndexerClient
30
34
}
31
35
32
- func NewTokenProgramAccountHandler (conf * conf , data code_data.Provider ) ProgramAccountUpdateHandler {
36
+ func NewTokenProgramAccountHandler (conf * conf , data code_data.Provider , vmIndexerClient indexerpb. IndexerClient ) ProgramAccountUpdateHandler {
33
37
return & TokenProgramAccountHandler {
34
- conf : conf ,
35
- data : data ,
38
+ conf : conf ,
39
+ data : data ,
40
+ vmIndexerClient : vmIndexerClient ,
36
41
}
37
42
}
38
43
39
- // todo: implement real-time external deposits for the VM
44
+ // todo: This needs to handle swaps
40
45
func (h * TokenProgramAccountHandler ) Handle (ctx context.Context , update * geyserpb.AccountUpdate ) error {
41
- return nil
46
+ if ! bytes .Equal (update .Owner , token .ProgramKey ) {
47
+ return ErrUnexpectedProgramOwner
48
+ }
42
49
43
- /*
44
- if !bytes.Equal(update.Owner, token.ProgramKey) {
45
- return ErrUnexpectedProgramOwner
46
- }
50
+ // We need to know the amount being deposited, and that's impossible without
51
+ // a transaction signature.
52
+ if update .TxSignature == nil {
53
+ return nil
54
+ }
47
55
48
- // We need to know the amount being deposited, and that's impossible without
49
- // a transaction signature.
50
- if update.TxSignature == nil {
51
- return nil
52
- }
56
+ // We need to know more about the account before accessing our data stores,
57
+ // so skip anything that doesn't have data. I'm assuming this means the account
58
+ // is closed anyways.
59
+ if len (update .Data ) == 0 {
60
+ return nil
61
+ }
53
62
54
- // We need to know more about the account before accessing our data stores,
55
- // so skip anything that doesn't have data. I'm assuming this means the account
56
- // is closed anyways.
57
- if len(update.Data) == 0 {
58
- return nil
59
- }
63
+ var unmarshalled token.Account
64
+ if ! unmarshalled .Unmarshal (update .Data ) {
65
+ // Probably not a token account (eg. mint)
66
+ return nil
67
+ }
60
68
61
- var unmarshalled token.Account
62
- if !unmarshalled.Unmarshal(update.Data) {
63
- // Probably not a token account (eg. mint)
64
- return nil
65
- }
69
+ tokenAccount , err := common .NewAccountFromPublicKeyBytes (update .Pubkey )
70
+ if err != nil {
71
+ return errors .Wrap (err , "invalid token account" )
72
+ }
66
73
67
- tokenAccount , err := common.NewAccountFromPublicKeyBytes(update.Pubkey )
68
- if err != nil {
69
- return errors.Wrap(err, "invalid token account")
70
- }
74
+ ownerAccount , err := common .NewAccountFromPublicKeyBytes (unmarshalled . Owner )
75
+ if err != nil {
76
+ return errors .Wrap (err , "invalid owner account" )
77
+ }
71
78
72
- ownerAccount , err := common.NewAccountFromPublicKeyBytes(unmarshalled.Owner )
73
- if err != nil {
74
- return errors.Wrap(err, "invalid owner account")
75
- }
79
+ mintAccount , err := common .NewAccountFromPublicKeyBytes (unmarshalled .Mint )
80
+ if err != nil {
81
+ return errors .Wrap (err , "invalid mint account" )
82
+ }
76
83
77
- mintAccount, err := common.NewAccountFromPublicKeyBytes(unmarshalled.Mint)
78
- if err != nil {
79
- return errors.Wrap(err, "invalid mint account")
80
- }
84
+ switch mintAccount .PublicKey ().ToBase58 () {
81
85
82
- // Account is empty, and all we care about are external deposits at this point,
83
- // so filter it out
84
- if unmarshalled.Amount == 0 {
86
+ case common . CoreMintAccount . PublicKey (). ToBase58 ():
87
+ // Not an ATA, so filter it out. It cannot be a VM deposit ATA
88
+ if bytes . Equal ( tokenAccount . PublicKey (). ToBytes (), ownerAccount . PublicKey (). ToBytes ()) {
85
89
return nil
86
90
}
87
91
88
- switch mintAccount.PublicKey().ToBase58() {
89
-
90
- case common.CoreMintAccount.PublicKey().ToBase58():
91
- // Not a program vault account, so filter it out. It cannot be a Timelock
92
- // account.
93
- if !bytes.Equal(tokenAccount.PublicKey().ToBytes(), ownerAccount.PublicKey().ToBytes()) {
94
- return nil
95
- }
96
-
97
- // todo: Need to implement VM deposit flow
92
+ exists , userAuthorityAccount , err := testForKnownUserAuthorityFromDepositPda (ctx , h .data , tokenAccount )
93
+ if err != nil {
94
+ return errors .Wrap (err , "error testing for user authority from deposit pda" )
95
+ } else if ! exists {
98
96
return nil
97
+ }
99
98
100
- case common.UsdcMintAccount.PublicKey().ToBase58():
101
- ata, err := ownerAccount.ToAssociatedTokenAccount(common.UsdcMintAccount)
102
- if err != nil {
103
- return errors.Wrap(err, "error deriving usdc ata")
104
- }
105
-
106
- // Not an ATA, so filter it out
107
- if !bytes.Equal(tokenAccount.PublicKey().ToBytes(), ata.PublicKey().ToBytes()) {
108
- return nil
109
- }
99
+ err = processPotentialExternalDepositIntoVm (ctx , h .data , * update .TxSignature , userAuthorityAccount )
100
+ if err != nil {
101
+ return errors .Wrap (err , "error processing signature for external deposit into vm" )
102
+ }
110
103
111
- isCodeSwapAccount, err := testForKnownCodeSwapAccount(ctx, h.data, tokenAccount)
104
+ if unmarshalled .Amount > 0 {
105
+ err = maybeInitiateExternalDepositIntoVm (ctx , h .data , h .vmIndexerClient , userAuthorityAccount )
112
106
if err != nil {
113
- return errors.Wrap(err, "error testing for known account")
114
- } else if !isCodeSwapAccount {
115
- // Not an account we track, so skip the update
116
- return nil
107
+ return errors .Wrap (err , "error depositing into the vm" )
117
108
}
118
-
119
- default:
120
- // Not a Core Mint or USDC account, so filter it out
121
- return nil
122
109
}
123
110
124
- // We've determined this token account is one that we care about. Process
125
- // the update as an external deposit.
126
- return processPotentialExternalDeposit(ctx, h.conf, h.data, *update.TxSignature, tokenAccount)
127
- */
111
+ return nil
112
+ default :
113
+ // Not a Core Mint account, so filter it out
114
+ return nil
115
+ }
128
116
}
129
117
130
- func initializeProgramAccountUpdateHandlers (conf * conf , data code_data.Provider ) map [string ]ProgramAccountUpdateHandler {
118
+ func initializeProgramAccountUpdateHandlers (conf * conf , data code_data.Provider , vmIndexerClient indexerpb. IndexerClient ) map [string ]ProgramAccountUpdateHandler {
131
119
return map [string ]ProgramAccountUpdateHandler {
132
- base58 .Encode (token .ProgramKey ): NewTokenProgramAccountHandler (conf , data ),
120
+ base58 .Encode (token .ProgramKey ): NewTokenProgramAccountHandler (conf , data , vmIndexerClient ),
133
121
}
134
122
}
0 commit comments