Skip to content

Commit 5a88c9b

Browse files
committed
Blockchain support for new VM and currency creator program instructions and flows
1 parent 9a685af commit 5a88c9b

12 files changed

+690
-13
lines changed

pkg/code/async/geyser/external_deposit.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ func initiateExternalDepositIntoVm(ctx context.Context, data code_data.Provider,
122122
memo.Instruction(codeVmDepositMemoValue),
123123
compute_budget.SetComputeUnitPrice(1_000),
124124
compute_budget.SetComputeUnitLimit(50_000),
125-
cvm.NewDepositInstruction(
126-
&cvm.DepositInstructionAccounts{
125+
cvm.NewDepositFromPdaInstruction(
126+
&cvm.DepositFromPdaInstructionAccounts{
127127
VmAuthority: vmConfig.Authority.PublicKey().ToBytes(),
128128
Vm: vmConfig.Vm.PublicKey().ToBytes(),
129129
VmMemory: memoryAccount.PublicKey().ToBytes(),
@@ -132,7 +132,7 @@ func initiateExternalDepositIntoVm(ctx context.Context, data code_data.Provider,
132132
DepositAta: timelockAccounts.VmDepositAccounts.Ata.PublicKey().ToBytes(),
133133
VmOmnibus: vmConfig.Omnibus.PublicKey().ToBytes(),
134134
},
135-
&cvm.DepositInstructionArgs{
135+
&cvm.DepositFromPdaInstructionArgs{
136136
AccountIndex: memoryIndex,
137137
Amount: balance,
138138
Bump: timelockAccounts.VmDepositAccounts.PdaBump,

pkg/code/common/account.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ type TimelockAccounts struct {
3838
UnlockBump uint8
3939

4040
VmDepositAccounts *VmDepositAccounts
41+
VmSwapAccounts *VmSwapAccounts
4142

4243
Vm *Account
4344
Mint *Account
@@ -55,6 +56,18 @@ type VmDepositAccounts struct {
5556
Mint *Account
5657
}
5758

59+
type VmSwapAccounts struct {
60+
VaultOwner *Account
61+
62+
Pda *Account
63+
PdaBump uint8
64+
65+
Ata *Account
66+
67+
Vm *Account
68+
Mint *Account
69+
}
70+
5871
type AccountRecords struct {
5972
General *account.Record
6073
Timelock *timelock.Record
@@ -208,6 +221,18 @@ func (a *Account) ToVmDepositAta(vmConfig *VmConfig) (*Account, error) {
208221
return vmDepositAccounts.Ata, nil
209222
}
210223

224+
func (a *Account) ToVmSwapAta(vmConfig *VmConfig) (*Account, error) {
225+
if err := a.Validate(); err != nil {
226+
return nil, errors.Wrap(err, "error validating owner account")
227+
}
228+
229+
vmSwapAccounts, err := a.GetVmSwapAccounts(vmConfig)
230+
if err != nil {
231+
return nil, err
232+
}
233+
return vmSwapAccounts.Ata, nil
234+
}
235+
211236
func (a *Account) GetTimelockAccounts(vmConfig *VmConfig) (*TimelockAccounts, error) {
212237
if err := a.Validate(); err != nil {
213238
return nil, errors.Wrap(err, "error validating owner account")
@@ -259,6 +284,11 @@ func (a *Account) GetTimelockAccounts(vmConfig *VmConfig) (*TimelockAccounts, er
259284
return nil, errors.Wrap(err, "error getting vm deposit accounts")
260285
}
261286

287+
vmSwapAccounts, err := a.GetVmSwapAccounts(vmConfig)
288+
if err != nil {
289+
return nil, errors.Wrap(err, "error getting vm swap accounts")
290+
}
291+
262292
return &TimelockAccounts{
263293
VaultOwner: a,
264294

@@ -272,6 +302,7 @@ func (a *Account) GetTimelockAccounts(vmConfig *VmConfig) (*TimelockAccounts, er
272302
UnlockBump: unlockBump,
273303

274304
VmDepositAccounts: vmDepositAccounts,
305+
VmSwapAccounts: vmSwapAccounts,
275306

276307
Vm: vmConfig.Vm,
277308
Mint: vmConfig.Mint,
@@ -315,6 +346,43 @@ func (a *Account) GetVmDepositAccounts(vmConfig *VmConfig) (*VmDepositAccounts,
315346
}, nil
316347
}
317348

349+
func (a *Account) GetVmSwapAccounts(vmConfig *VmConfig) (*VmSwapAccounts, error) {
350+
swapPdaAddress, swapPdaBump, err := cvm.GetVmSwapAddress(&cvm.GetVmSwapAddressArgs{
351+
Swapper: a.PublicKey().ToBytes(),
352+
Vm: vmConfig.Vm.PublicKey().ToBytes(),
353+
})
354+
if err != nil {
355+
return nil, errors.Wrap(err, "error getting swap pda address")
356+
}
357+
358+
swapAtaAddress, err := token.GetAssociatedAccount(swapPdaAddress, vmConfig.Mint.PublicKey().ToBytes())
359+
if err != nil {
360+
return nil, errors.Wrap(err, "error getting swap ata address")
361+
}
362+
363+
swapPdaAccount, err := NewAccountFromPublicKeyBytes(swapPdaAddress)
364+
if err != nil {
365+
return nil, errors.Wrap(err, "invalid deposit pda address")
366+
}
367+
368+
swapAtaAccount, err := NewAccountFromPublicKeyBytes(swapAtaAddress)
369+
if err != nil {
370+
return nil, errors.Wrap(err, "invalid deposit ata address")
371+
}
372+
373+
return &VmSwapAccounts{
374+
Pda: swapPdaAccount,
375+
PdaBump: swapPdaBump,
376+
377+
Ata: swapAtaAccount,
378+
379+
VaultOwner: a,
380+
381+
Vm: vmConfig.Vm,
382+
Mint: vmConfig.Mint,
383+
}, nil
384+
}
385+
318386
func (a *Account) IsManagedByCode(ctx context.Context, data code_data.Provider) (bool, error) {
319387
timelockRecord, err := data.GetTimelockByVault(ctx, a.PublicKey().ToBase58())
320388
if err == timelock.ErrTimelockNotFound {

pkg/code/common/account_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,30 @@ func TestGetVmDepositAccounts(t *testing.T) {
187187
assert.EqualValues(t, vmConfig.Mint.PublicKey().ToBytes(), actual.Mint.PublicKey().ToBytes())
188188
}
189189

190+
func TestGetVmSwapAccounts(t *testing.T) {
191+
vmConfig := newRandomVmConfig(t, true)
192+
193+
ownerAccount := newRandomTestAccount(t)
194+
195+
expectedSwapPdaAddress, expectedSwapPdaBump, err := cvm.GetVmSwapAddress(&cvm.GetVmSwapAddressArgs{
196+
Swapper: ownerAccount.PublicKey().ToBytes(),
197+
Vm: vmConfig.Vm.PublicKey().ToBytes(),
198+
})
199+
require.NoError(t, err)
200+
201+
expectedSwapAtaAddress, err := token.GetAssociatedAccount(expectedSwapPdaAddress, vmConfig.Mint.PublicKey().ToBytes())
202+
require.NoError(t, err)
203+
204+
actual, err := ownerAccount.GetVmSwapAccounts(vmConfig)
205+
require.NoError(t, err)
206+
assert.EqualValues(t, ownerAccount.PublicKey().ToBytes(), actual.VaultOwner.PublicKey().ToBytes())
207+
assert.EqualValues(t, expectedSwapPdaAddress, actual.Pda.PublicKey().ToBytes())
208+
assert.Equal(t, expectedSwapPdaBump, actual.PdaBump)
209+
assert.EqualValues(t, expectedSwapAtaAddress, actual.Ata.PublicKey().ToBytes())
210+
assert.EqualValues(t, vmConfig.Vm.PublicKey().ToBytes(), actual.Vm.PublicKey().ToBytes())
211+
assert.EqualValues(t, vmConfig.Mint.PublicKey().ToBytes(), actual.Mint.PublicKey().ToBytes())
212+
}
213+
190214
func TestIsOnCurve(t *testing.T) {
191215
for _, tc := range []struct {
192216
expected bool
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package currencycreator
2+
3+
import (
4+
"crypto/ed25519"
5+
6+
"github.com/code-payments/code-server/pkg/solana"
7+
"github.com/code-payments/code-server/pkg/solana/cvm"
8+
)
9+
10+
const (
11+
BuyAndDepositIntoVmInstructionArgsSize = (8 + // in_amount
12+
8 + // min_out_amount
13+
2) // account_index
14+
)
15+
16+
type BuyAndDepositIntoVmInstructionArgs struct {
17+
InAmount uint64
18+
MinOutAmount uint64
19+
VmMemoryIndex uint16
20+
}
21+
22+
type BuyAndDepositIntoVmInstructionAccounts struct {
23+
Buyer ed25519.PublicKey
24+
Pool ed25519.PublicKey
25+
Currency ed25519.PublicKey
26+
TargetMint ed25519.PublicKey
27+
BaseMint ed25519.PublicKey
28+
VaultTarget ed25519.PublicKey
29+
VaultBase ed25519.PublicKey
30+
BuyerBase ed25519.PublicKey
31+
FeeTarget ed25519.PublicKey
32+
FeeBase ed25519.PublicKey
33+
34+
VmAuthority ed25519.PublicKey
35+
Vm ed25519.PublicKey
36+
VmMemory ed25519.PublicKey
37+
VmOmnibus ed25519.PublicKey
38+
VtaOwner ed25519.PublicKey
39+
}
40+
41+
func NewBuyAndDepositIntoVmInstruction(
42+
accounts *BuyAndDepositIntoVmInstructionAccounts,
43+
args *BuyAndDepositIntoVmInstructionArgs,
44+
) solana.Instruction {
45+
var offset int
46+
47+
// Serialize instruction arguments
48+
data := make([]byte, 1+BuyAndDepositIntoVmInstructionArgsSize)
49+
50+
putInstructionType(data, InstructionTypeBuyAndDepositIntoVm, &offset)
51+
putUint64(data, args.InAmount, &offset)
52+
putUint64(data, args.MinOutAmount, &offset)
53+
putUint16(data, args.VmMemoryIndex, &offset)
54+
55+
return solana.Instruction{
56+
Program: PROGRAM_ADDRESS,
57+
58+
// Instruction args
59+
Data: data,
60+
61+
// Instruction accounts
62+
Accounts: []solana.AccountMeta{
63+
{
64+
PublicKey: accounts.Buyer,
65+
IsWritable: true,
66+
IsSigner: true,
67+
},
68+
{
69+
PublicKey: accounts.Pool,
70+
IsWritable: true,
71+
IsSigner: false,
72+
},
73+
{
74+
PublicKey: accounts.Currency,
75+
IsWritable: true,
76+
IsSigner: false,
77+
},
78+
{
79+
PublicKey: accounts.TargetMint,
80+
IsWritable: true,
81+
IsSigner: false,
82+
},
83+
{
84+
PublicKey: accounts.BaseMint,
85+
IsWritable: false,
86+
IsSigner: false,
87+
},
88+
{
89+
PublicKey: accounts.VaultTarget,
90+
IsWritable: true,
91+
IsSigner: false,
92+
},
93+
{
94+
PublicKey: accounts.VaultBase,
95+
IsWritable: true,
96+
IsSigner: false,
97+
},
98+
{
99+
PublicKey: accounts.BuyerBase,
100+
IsWritable: true,
101+
IsSigner: false,
102+
},
103+
{
104+
PublicKey: accounts.FeeTarget,
105+
IsWritable: true,
106+
IsSigner: false,
107+
},
108+
{
109+
PublicKey: accounts.FeeBase,
110+
IsWritable: false,
111+
IsSigner: false,
112+
},
113+
114+
{
115+
PublicKey: accounts.VmAuthority,
116+
IsWritable: true,
117+
IsSigner: true,
118+
},
119+
{
120+
PublicKey: accounts.Vm,
121+
IsWritable: true,
122+
IsSigner: false,
123+
},
124+
{
125+
PublicKey: accounts.VmMemory,
126+
IsWritable: true,
127+
IsSigner: false,
128+
},
129+
130+
{
131+
PublicKey: accounts.VmOmnibus,
132+
IsWritable: true,
133+
IsSigner: false,
134+
},
135+
{
136+
PublicKey: accounts.VtaOwner,
137+
IsWritable: false,
138+
IsSigner: false,
139+
},
140+
{
141+
PublicKey: SPL_TOKEN_PROGRAM_ID,
142+
IsWritable: false,
143+
IsSigner: false,
144+
},
145+
{
146+
PublicKey: cvm.PROGRAM_ID,
147+
IsWritable: false,
148+
IsSigner: false,
149+
},
150+
},
151+
}
152+
}

0 commit comments

Comments
 (0)