Skip to content

Commit

Permalink
Add integration test for token program set authority
Browse files Browse the repository at this point in the history
  • Loading branch information
ml-james committed Sep 14, 2024
1 parent 6c09d77 commit b4e90e3
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,68 @@ void shouldCreateMultiSig(final String messageEncoding, final String tokenProgra

}

@Disabled
@ParameterizedTokenTest
void shouldSetAuthority(final String messageEncoding, final String tokenProgram)
{
fail();
solana.setMessageEncoding(messageEncoding);

solana.createKeyPair("tokenMint");
solana.createKeyPair("mintAuthority");
solana.createKeyPair("freezeAuthority");
solana.createKeyPair("tokenAccountSender");
solana.createKeyPair("tokenAccountReceiver");
solana.createKeyPair("tokenAccountOwner");
solana.createKeyPair("tokenAccountNewOwner");

solana.maybeCreateAndExtendAddressLookupTables(
messageEncoding, "payer: payer",
"lookupTableAddress: addressLookupTable1", "addresses: tokenMint, mintAuthority, freezeAuthority",
"lookupTableAddress: addressLookupTable2", "addresses: tokenAccountSender, tokenAccountReceiver, tokenAccountOwner");

solana.createMintAccount("tokenMint", "18", "mintAuthority", "freezeAuthority", "payer", tokenProgram, "addressLookupTable1", "addressLookupTable2");
solana.createTokenAccount("tokenAccountSender", "tokenAccountOwner", "tokenMint", "payer", tokenProgram, "addressLookupTable1", "addressLookupTable2");

solana.mintTo("tokenMint", "tokenAccountSender", "mintAuthority", "payer", "100", tokenProgram, "addressLookupTable1", "addressLookupTable2");
solana.tokenBalance("tokenAccountSender", "0.0000000000000001");

solana.createTokenAccount("tokenAccountReceiver", "tokenAccountOwner", "tokenMint", "payer", tokenProgram, "addressLookupTable1", "addressLookupTable2");

solana.tokenTransfer(
"tokenAccountSender",
"tokenAccountReceiver",
"tokenAccountOwner",
"10",
"payer",
"signers: payer, tokenAccountOwner",
"tokenProgram: " + tokenProgram,
"addressLookupTables: addressLookupTable1, addressLookupTable2");

solana.tokenBalance("tokenAccountSender", "0.00000000000000009");
solana.tokenBalance("tokenAccountReceiver", "0.00000000000000001");

solana.setAuthority(
"tokenAccountSender",
"tokenAccountOwner",
"tokenAccountNewOwner",
"ACCOUNT_OWNER",
"payer",
"signers: payer, tokenAccountOwner",
"tokenProgram: " + tokenProgram);

// now try a transfer with the new owner
solana.tokenTransfer(
"tokenAccountSender",
"tokenAccountReceiver",
"tokenAccountNewOwner",
"10",
"payer",
"signers: payer, tokenAccountNewOwner",
"tokenProgram: " + tokenProgram,
"addressLookupTables: addressLookupTable1, addressLookupTable2");

solana.tokenBalance("tokenAccountSender", "0.00000000000000008");
solana.tokenBalance("tokenAccountReceiver", "0.00000000000000002");

}

}
30 changes: 28 additions & 2 deletions src/test-support/java/com/lmax/solana4j/SolanaDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -302,30 +302,56 @@ public String transfer(
}

public String createAssociatedTokenAddress(
final TokenProgram tokenProgram,
final ProgramDerivedAddress associatedTokenAddress,
final PublicKey mint,
final PublicKey owner,
final boolean idempotent,
final PublicKey tokenProgramId,
final TestKeyPair payer,
final List<AddressLookupTable> addressLookupTables)
{
final Blockhash blockhash = solanaApi.getRecentBlockHash();

final String transactionBlob = getTransactionFactory().createAssociatedTokenAddress(
tokenProgram,
owner,
associatedTokenAddress,
Solana.blockhash(blockhash.getBytes()),
mint,
idempotent,
tokenProgramId,
payer.getSolana4jPublicKey(),
List.of(payer),
addressLookupTables);

return solanaApi.sendTransaction(transactionBlob);
}

public String setAuthority(
final TokenProgram tokenProgram,
final PublicKey account,
final PublicKey oldAuthority,
final PublicKey newAuthority,
final com.lmax.solana4j.programs.TokenProgram.AuthorityType authorityType,
final TestKeyPair payer,
final List<TestKeyPair> signers,
final List<AddressLookupTable> addressLookupTables)
{
final Blockhash blockhash = solanaApi.getRecentBlockHash();

final String transactionBlob = getTransactionFactory().setAuthority(
tokenProgram,
account,
oldAuthority,
newAuthority,
authorityType,
Solana.blockhash(blockhash.getBytes()),
payer,
signers,
addressLookupTables);

return solanaApi.sendTransaction(transactionBlob);
}

public void setMessageEncoding(final String messageEncoding)
{
if (messageEncoding.equals("V0"))
Expand Down
46 changes: 45 additions & 1 deletion src/test-support/java/com/lmax/solana4j/SolanaNodeDsl.java
Original file line number Diff line number Diff line change
Expand Up @@ -499,11 +499,11 @@ public void createAssociatedTokenAddress(final String... args)
.toList();

final String transactionSignature = solanaDriver.createAssociatedTokenAddress(
tokenProgram,
associatedTokenAddress,
tokenMint.getSolana4jPublicKey(),
owner.getSolana4jPublicKey(),
params.valueAsBoolean("idempotent"),
tokenProgram.getProgram(),
payer,
addressLookupTables
);
Expand Down Expand Up @@ -538,6 +538,50 @@ public void maybeCreateAndExtendAddressLookupTables(final String... args)
}
}

public void setAuthority(final String... args)
{
final DslParams params = DslParams.create(
args,
new RequiredArg("account"),
new RequiredArg("oldAuthority"),
new RequiredArg("newAuthority"),
new RequiredArg("authorityType").setAllowedValues(com.lmax.solana4j.programs.TokenProgram.AuthorityType.class),
new RequiredArg("payer"),
new RequiredArg("signers").setAllowMultipleValues(),
new OptionalArg("tokenProgram").setAllowedValues("Token", "Token2022").setDefault("Token"),
new OptionalArg("addressLookupTables").setAllowMultipleValues()
);

final TestPublicKey account = testContext.data(TestDataType.TEST_PUBLIC_KEY).lookup(params.value("account"));
final TestPublicKey oldAuthority = testContext.data(TestDataType.TEST_PUBLIC_KEY).lookup(params.value("oldAuthority"));
final TestPublicKey newAuthority = testContext.data(TestDataType.TEST_PUBLIC_KEY).lookup(params.value("newAuthority"));
final com.lmax.solana4j.programs.TokenProgram.AuthorityType authorityType = com.lmax.solana4j.programs.TokenProgram.AuthorityType.valueOf(params.value("authorityType"));
final TokenProgram tokenProgram = TokenProgram.fromName(params.value("tokenProgram"));
final TestKeyPair payer = testContext.data(TestDataType.TEST_KEY_PAIR).lookup(params.value("payer"));

final List<TestKeyPair> signers = params.valuesAsList("signers").stream()
.map(testContext.data(TestDataType.TEST_KEY_PAIR)::lookup)
.filter(Objects::nonNull)
.toList();

final List<AddressLookupTable> addressLookupTables = params.valuesAsList("addressLookupTables").stream()
.map(testContext.data(TestDataType.ADDRESS_LOOKUP_TABLE)::lookup)
.filter(Objects::nonNull)
.toList();

final String transactionSignature = solanaDriver.setAuthority(
tokenProgram,
account.getSolana4jPublicKey(),
oldAuthority.getSolana4jPublicKey(),
newAuthority.getSolana4jPublicKey(),
authorityType,
payer,
signers,
addressLookupTables);

Waiter.waitFor(isNotNull(() -> solanaDriver.getTransactionResponse(transactionSignature).getTransaction()));
}

private void waitForSlot(final long slot)
{
Waiter.waitFor(isTrue(() -> solanaDriver.getSlot() > slot));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,12 @@ public String advanceNonce(

@Override
public String createAssociatedTokenAddress(
final TokenProgram tokenProgram,
final PublicKey owner,
final ProgramDerivedAddress associatedTokenAddress,
final Blockhash blockhash,
final PublicKey mint,
final boolean idempotent,
final PublicKey tokenProgramId,
final PublicKey payer,
final List<TestKeyPair> signers,
final List<AddressLookupTable> addressLookupTables)
Expand All @@ -440,7 +440,7 @@ public String createAssociatedTokenAddress(
mint,
owner,
payer,
tokenProgramId,
tokenProgram.getProgram(),
idempotent))
.payer(payer)
.seal()
Expand All @@ -457,6 +457,44 @@ public String createAssociatedTokenAddress(
return base58encode(buffer);
}

@Override
public String setAuthority(
final TokenProgram tokenProgram,
final PublicKey account,
final PublicKey oldAuthority,
final PublicKey newAuthority,
final com.lmax.solana4j.programs.TokenProgram.AuthorityType authorityType,
final Blockhash blockhash,
final TestKeyPair payer,
final List<TestKeyPair> signers,
final List<AddressLookupTable> addressLookupTables)
{
final ByteBuffer buffer = ByteBuffer.allocate(Solana.MAX_MESSAGE_SIZE);
Solana.builder(buffer)
.legacy()
.recent(blockhash)
.instructions(legacyTransactionBuilder -> tokenProgram.getFactory().factory(legacyTransactionBuilder)
.setAuthority(
account,
newAuthority,
oldAuthority,
signers.stream().map(TestKeyPair::getSolana4jPublicKey).toList(),
authorityType))
.payer(payer.getSolana4jPublicKey())
.seal()
.unsigned()
.build();

final SignedMessageBuilder signedMessageBuilder = Solana.forSigning(buffer);
for (final TestKeyPair signer : signers)
{
signedMessageBuilder.by(signer.getSolana4jPublicKey(), new BouncyCastleSigner(signer.getPrivateKeyBytes()));
}
signedMessageBuilder.build();

return base58encode(buffer);
}

private static String base58encode(final ByteBuffer bytes)
{
return Base58.encode(ByteBufferPrimitiveArray.copy(bytes));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,24 @@ String advanceNonce(
List<AddressLookupTable> addressLookupTables);

String createAssociatedTokenAddress(
TokenProgram tokenProgram,
PublicKey owner,
ProgramDerivedAddress associatedTokenAddress,
Blockhash blockhash,
PublicKey mint,
boolean idempotent,
PublicKey tokenProgramId,
PublicKey payer,
List<TestKeyPair> signers,
List<AddressLookupTable> addressLookupTables);

String setAuthority(
TokenProgram tokenProgram,
PublicKey account,
PublicKey oldAuthority,
PublicKey newAuthority,
com.lmax.solana4j.programs.TokenProgram.AuthorityType authorityType,
Blockhash blockhash,
TestKeyPair payer,
List<TestKeyPair> signers,
List<AddressLookupTable> addressLookupTables);
}
Original file line number Diff line number Diff line change
Expand Up @@ -423,12 +423,12 @@ public String advanceNonce(

@Override
public String createAssociatedTokenAddress(
final TokenProgram tokenProgram,
final PublicKey owner,
final ProgramDerivedAddress associatedTokenAddress,
final Blockhash blockhash,
final PublicKey mint,
final boolean idempotent,
final PublicKey tokenProgramId,
final PublicKey payer,
final List<TestKeyPair> signers,
final List<AddressLookupTable> addressLookupTables)
Expand All @@ -440,7 +440,7 @@ public String createAssociatedTokenAddress(
.instructions(tb -> AssociatedTokenProgram.factory(tb)
.createAssociatedToken(
associatedTokenAddress, mint, owner, payer,
tokenProgramId,
tokenProgram.getProgram(),
idempotent))
.payer(payer)
.lookups(addressLookupTables)
Expand All @@ -458,6 +458,45 @@ public String createAssociatedTokenAddress(
return base58encode(buffer);
}

@Override
public String setAuthority(
final TokenProgram tokenProgram,
final PublicKey account,
final PublicKey oldAuthority,
final PublicKey newAuthority,
final com.lmax.solana4j.programs.TokenProgram.AuthorityType authorityType,
final Blockhash blockhash,
final TestKeyPair payer,
final List<TestKeyPair> signers,
final List<AddressLookupTable> addressLookupTables)
{
final ByteBuffer buffer = ByteBuffer.allocate(Solana.MAX_MESSAGE_SIZE);
Solana.builder(buffer)
.v0()
.recent(blockhash)
.instructions(versionedTransactionBuilder -> tokenProgram.getFactory().factory(versionedTransactionBuilder)
.setAuthority(
account,
newAuthority,
oldAuthority,
signers.stream().map(TestKeyPair::getSolana4jPublicKey).toList(),
authorityType))
.lookups(addressLookupTables)
.payer(payer.getSolana4jPublicKey())
.seal()
.unsigned()
.build();

final SignedMessageBuilder signedMessageBuilder = Solana.forSigning(buffer);
for (final TestKeyPair signer : signers)
{
signedMessageBuilder.by(signer.getSolana4jPublicKey(), new BouncyCastleSigner(signer.getPrivateKeyBytes()));
}
signedMessageBuilder.build();

return base58encode(buffer);
}

private static String base58encode(final ByteBuffer bytes)
{
return Base58.encode(ByteBufferPrimitiveArray.copy(bytes));
Expand Down

0 comments on commit b4e90e3

Please sign in to comment.