Skip to content

Commit 8fb4a13

Browse files
committed
test(opencode): add VirtualMachineProgram and CurrencyCreatorProgram tests
- VirtualMachineProgramTest: TransferForSwap and CloseSwapAccountIfEmpty encoding, account counts, signer flags, command bytes - CurrencyCreatorProgramTest: BuyAndDepositIntoVm and SellAndDepositIntoVm encoding, account counts, U16 vmMemoryIndex encoding, command bytes
1 parent 131a804 commit 8fb4a13

2 files changed

Lines changed: 288 additions & 0 deletions

File tree

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package com.getcode.opencode.internal.solana.programs
2+
3+
import com.getcode.solana.keys.PublicKey
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
7+
class CurrencyCreatorProgramTest {
8+
9+
private fun testKey(seed: Int): PublicKey =
10+
PublicKey(ByteArray(32) { seed.toByte() }.toList())
11+
12+
// --- Command enum ---
13+
14+
@Test
15+
fun commandBuyTokensValue() {
16+
assertEquals(4.toByte(), CurrencyCreatorProgram.Command.buyTokens.value)
17+
}
18+
19+
@Test
20+
fun commandSellTokensValue() {
21+
assertEquals(5.toByte(), CurrencyCreatorProgram.Command.sellTokens.value)
22+
}
23+
24+
@Test
25+
fun commandBuyAndDepositValue() {
26+
assertEquals(6.toByte(), CurrencyCreatorProgram.Command.buyAndDepositIntoVm.value)
27+
}
28+
29+
@Test
30+
fun commandSellAndDepositValue() {
31+
assertEquals(7.toByte(), CurrencyCreatorProgram.Command.sellAndDepositIntoVm.value)
32+
}
33+
34+
// --- BuyAndDepositIntoVm ---
35+
36+
@Test
37+
fun buyEncodeStartsWithCommand() {
38+
val ix = CurrencyCreatorProgram_BuyAndDepositIntoVm(
39+
inAmount = 1000L, minOutAmount = 900L, vmMemoryIndex = 0,
40+
buyer = testKey(1), pool = testKey(2),
41+
targetMint = testKey(3), baseMint = testKey(4),
42+
vaultTarget = testKey(5), vaultBase = testKey(6),
43+
buyerBase = testKey(7), vmAuthority = testKey(8),
44+
vm = testKey(9), vmMemory = testKey(10),
45+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
46+
)
47+
assertEquals(6.toByte(), ix.encode()[0])
48+
}
49+
50+
@Test
51+
fun buyEncodeLength() {
52+
val ix = CurrencyCreatorProgram_BuyAndDepositIntoVm(
53+
inAmount = 1000L, minOutAmount = 900L, vmMemoryIndex = 0,
54+
buyer = testKey(1), pool = testKey(2),
55+
targetMint = testKey(3), baseMint = testKey(4),
56+
vaultTarget = testKey(5), vaultBase = testKey(6),
57+
buyerBase = testKey(7), vmAuthority = testKey(8),
58+
vm = testKey(9), vmMemory = testKey(10),
59+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
60+
)
61+
// 1 byte command + 8 bytes inAmount + 8 bytes minOutAmount + 2 bytes vmMemoryIndex = 19
62+
assertEquals(19, ix.encode().size)
63+
}
64+
65+
@Test
66+
fun buyInstructionHas14Accounts() {
67+
val ix = CurrencyCreatorProgram_BuyAndDepositIntoVm(
68+
inAmount = 1000L, minOutAmount = 900L, vmMemoryIndex = 0,
69+
buyer = testKey(1), pool = testKey(2),
70+
targetMint = testKey(3), baseMint = testKey(4),
71+
vaultTarget = testKey(5), vaultBase = testKey(6),
72+
buyerBase = testKey(7), vmAuthority = testKey(8),
73+
vm = testKey(9), vmMemory = testKey(10),
74+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
75+
)
76+
assertEquals(14, ix.instruction().accounts.size)
77+
}
78+
79+
@Test
80+
fun buyInstructionProgram() {
81+
val ix = CurrencyCreatorProgram_BuyAndDepositIntoVm(
82+
inAmount = 1000L, minOutAmount = 900L, vmMemoryIndex = 0,
83+
buyer = testKey(1), pool = testKey(2),
84+
targetMint = testKey(3), baseMint = testKey(4),
85+
vaultTarget = testKey(5), vaultBase = testKey(6),
86+
buyerBase = testKey(7), vmAuthority = testKey(8),
87+
vm = testKey(9), vmMemory = testKey(10),
88+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
89+
)
90+
assertEquals(CurrencyCreatorProgram.address, ix.instruction().program)
91+
}
92+
93+
// --- SellAndDepositIntoVm ---
94+
95+
@Test
96+
fun sellEncodeStartsWithCommand() {
97+
val ix = CurrencyCreatorProgram_SellAndDepositIntoVm(
98+
inAmount = 500L, minOutAmount = 400L, vmMemoryIndex = 1,
99+
seller = testKey(1), pool = testKey(2),
100+
targetMint = testKey(3), baseMint = testKey(4),
101+
vaultTarget = testKey(5), vaultBase = testKey(6),
102+
sellerTarget = testKey(7), vmAuthority = testKey(8),
103+
vm = testKey(9), vmMemory = testKey(10),
104+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
105+
)
106+
assertEquals(7.toByte(), ix.encode()[0])
107+
}
108+
109+
@Test
110+
fun sellEncodeLength() {
111+
val ix = CurrencyCreatorProgram_SellAndDepositIntoVm(
112+
inAmount = 500L, minOutAmount = 400L, vmMemoryIndex = 1,
113+
seller = testKey(1), pool = testKey(2),
114+
targetMint = testKey(3), baseMint = testKey(4),
115+
vaultTarget = testKey(5), vaultBase = testKey(6),
116+
sellerTarget = testKey(7), vmAuthority = testKey(8),
117+
vm = testKey(9), vmMemory = testKey(10),
118+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
119+
)
120+
// 1 byte command + 8 + 8 + 2 = 19
121+
assertEquals(19, ix.encode().size)
122+
}
123+
124+
@Test
125+
fun sellInstructionHas14Accounts() {
126+
val ix = CurrencyCreatorProgram_SellAndDepositIntoVm(
127+
inAmount = 500L, minOutAmount = 400L, vmMemoryIndex = 1,
128+
seller = testKey(1), pool = testKey(2),
129+
targetMint = testKey(3), baseMint = testKey(4),
130+
vaultTarget = testKey(5), vaultBase = testKey(6),
131+
sellerTarget = testKey(7), vmAuthority = testKey(8),
132+
vm = testKey(9), vmMemory = testKey(10),
133+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
134+
)
135+
assertEquals(14, ix.instruction().accounts.size)
136+
}
137+
138+
@Test
139+
fun sellVmMemoryIndexEncodedAsU16() {
140+
val ix = CurrencyCreatorProgram_SellAndDepositIntoVm(
141+
inAmount = 0L, minOutAmount = 0L, vmMemoryIndex = 0x0102,
142+
seller = testKey(1), pool = testKey(2),
143+
targetMint = testKey(3), baseMint = testKey(4),
144+
vaultTarget = testKey(5), vaultBase = testKey(6),
145+
sellerTarget = testKey(7), vmAuthority = testKey(8),
146+
vm = testKey(9), vmMemory = testKey(10),
147+
vmOmnibus = testKey(11), vtaOwner = testKey(12)
148+
)
149+
val encoded = ix.encode()
150+
// Last 2 bytes should be little-endian 0x0102 → [0x02, 0x01]
151+
assertEquals(0x02.toByte(), encoded[encoded.size - 2])
152+
assertEquals(0x01.toByte(), encoded[encoded.size - 1])
153+
}
154+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package com.getcode.opencode.internal.solana.programs
2+
3+
import com.getcode.solana.keys.PublicKey
4+
import kotlin.test.Test
5+
import kotlin.test.assertEquals
6+
7+
class VirtualMachineProgramTest {
8+
9+
private fun testKey(seed: Int): PublicKey =
10+
PublicKey(ByteArray(32) { seed.toByte() }.toList())
11+
12+
// --- VirtualMachineProgram ---
13+
14+
@Test
15+
fun commandTransferForSwapValue() {
16+
assertEquals(17.toByte(), VirtualMachineProgram.Command.transferForSwap.value)
17+
}
18+
19+
@Test
20+
fun commandCloseSwapValue() {
21+
assertEquals(19.toByte(), VirtualMachineProgram.Command.closeSwapAccountIfEmpty.value)
22+
}
23+
24+
// --- TransferForSwap ---
25+
26+
@Test
27+
fun transferForSwapEncodeStartsWithCommand() {
28+
val ix = VirtualMachineProgram_TransferForSwap(
29+
vmAuthority = testKey(1), vm = testKey(2),
30+
swapper = testKey(3), swapPda = testKey(4),
31+
swapAta = testKey(5), destination = testKey(6),
32+
amount = 1000L, bump = 255
33+
)
34+
val encoded = ix.encode()
35+
assertEquals(17.toByte(), encoded[0])
36+
}
37+
38+
@Test
39+
fun transferForSwapEncodeLength() {
40+
val ix = VirtualMachineProgram_TransferForSwap(
41+
vmAuthority = testKey(1), vm = testKey(2),
42+
swapper = testKey(3), swapPda = testKey(4),
43+
swapAta = testKey(5), destination = testKey(6),
44+
amount = 1000L, bump = 255
45+
)
46+
// 1 byte command + 8 bytes amount + 1 byte bump = 10
47+
assertEquals(10, ix.encode().size)
48+
}
49+
50+
@Test
51+
fun transferForSwapEncodesBump() {
52+
val ix = VirtualMachineProgram_TransferForSwap(
53+
vmAuthority = testKey(1), vm = testKey(2),
54+
swapper = testKey(3), swapPda = testKey(4),
55+
swapAta = testKey(5), destination = testKey(6),
56+
amount = 0L, bump = 42
57+
)
58+
val encoded = ix.encode()
59+
assertEquals(42.toByte(), encoded.last())
60+
}
61+
62+
@Test
63+
fun transferForSwapInstructionHasCorrectProgram() {
64+
val ix = VirtualMachineProgram_TransferForSwap(
65+
vmAuthority = testKey(1), vm = testKey(2),
66+
swapper = testKey(3), swapPda = testKey(4),
67+
swapAta = testKey(5), destination = testKey(6),
68+
amount = 1000L, bump = 255
69+
)
70+
assertEquals(VirtualMachineProgram.address, ix.instruction().program)
71+
}
72+
73+
@Test
74+
fun transferForSwapInstructionHas7Accounts() {
75+
val ix = VirtualMachineProgram_TransferForSwap(
76+
vmAuthority = testKey(1), vm = testKey(2),
77+
swapper = testKey(3), swapPda = testKey(4),
78+
swapAta = testKey(5), destination = testKey(6),
79+
amount = 1000L, bump = 255
80+
)
81+
assertEquals(7, ix.instruction().accounts.size)
82+
}
83+
84+
@Test
85+
fun transferForSwapSigners() {
86+
val ix = VirtualMachineProgram_TransferForSwap(
87+
vmAuthority = testKey(1), vm = testKey(2),
88+
swapper = testKey(3), swapPda = testKey(4),
89+
swapAta = testKey(5), destination = testKey(6),
90+
amount = 1000L, bump = 255
91+
)
92+
val accounts = ix.instruction().accounts
93+
// vmAuthority and swapper should be signers
94+
assert(accounts[0].isSigner) { "vmAuthority should be signer" }
95+
assert(accounts[2].isSigner) { "swapper should be signer" }
96+
assert(!accounts[1].isSigner) { "vm should not be signer" }
97+
}
98+
99+
// --- CloseSwapAccountIfEmpty ---
100+
101+
@Test
102+
fun closeSwapEncodeStartsWithCommand() {
103+
val ix = VirtualMachineProgram_CloseSwapAccountIfEmpty(
104+
vmAuthority = testKey(1), vm = testKey(2),
105+
swapper = testKey(3), swapPda = testKey(4),
106+
swapAta = testKey(5), destination = testKey(6),
107+
bump = 255
108+
)
109+
assertEquals(19.toByte(), ix.encode()[0])
110+
}
111+
112+
@Test
113+
fun closeSwapEncodeLength() {
114+
val ix = VirtualMachineProgram_CloseSwapAccountIfEmpty(
115+
vmAuthority = testKey(1), vm = testKey(2),
116+
swapper = testKey(3), swapPda = testKey(4),
117+
swapAta = testKey(5), destination = testKey(6),
118+
bump = 255
119+
)
120+
// 1 byte command + 1 byte bump = 2
121+
assertEquals(2, ix.encode().size)
122+
}
123+
124+
@Test
125+
fun closeSwapInstructionHas7Accounts() {
126+
val ix = VirtualMachineProgram_CloseSwapAccountIfEmpty(
127+
vmAuthority = testKey(1), vm = testKey(2),
128+
swapper = testKey(3), swapPda = testKey(4),
129+
swapAta = testKey(5), destination = testKey(6),
130+
bump = 255
131+
)
132+
assertEquals(7, ix.instruction().accounts.size)
133+
}
134+
}

0 commit comments

Comments
 (0)