Skip to content

Commit 76300d9

Browse files
authored
fix(sdk): allow signer freeze authorities without accounts (#62)
1 parent 543083d commit 76300d9

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

packages/sdk/src/__tests__/test-utils.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export function createMockRpc(): Rpc<any> {
2222
},
2323
}),
2424
}),
25-
getAccountInfo: (address: Address, opts: { encoding: 'jsonParsed' | 'base64' }) => ({
25+
getAccountInfo: (address: Address, opts?: { encoding?: 'jsonParsed' | 'base64' }) => ({
2626
send: async () => {
2727
const entry = accountInfoRegistry.get(address as string);
2828
if (!entry) return { value: null };
@@ -35,7 +35,7 @@ export function createMockRpc(): Rpc<any> {
3535
if (opts?.encoding === 'base64') {
3636
return entry.base64 ? { value: { data: [entry.base64, 'base64'], owner } } : { value: null };
3737
}
38-
return { value: null };
38+
return { value: { owner } };
3939
},
4040
}),
4141
getProgramAccounts: (programAddress: Address, _opts?: any) => ({
@@ -168,3 +168,11 @@ export function seedProgramAccountBase64(
168168
arr.push(entry);
169169
reg.programAccountsRegistry.set(programAddress as string, arr);
170170
}
171+
172+
/**
173+
* Seeds a plain account owner for getAccountInfo calls that only need owner metadata.
174+
*/
175+
export function seedAccountOwner(rpc: Rpc<any>, account: Address, owner: Address): void {
176+
const reg = (rpc as any).__registry;
177+
reg.accountInfoRegistry.set(account as string, { owner });
178+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { Address, Rpc, SolanaRpcApi } from '@solana/kit';
2+
import { createMockRpc, resetMockRpc, seedAccountOwner, seedMintDetails, TEST_AUTHORITY } from './__tests__/test-utils';
3+
import { TOKEN_ACL_PROGRAM_ID } from './token-acl/utils';
4+
import { getMintDetails } from './transaction-util';
5+
6+
describe('getMintDetails', () => {
7+
let rpc: Rpc<SolanaRpcApi>;
8+
const mint = 'Mint777777777777777777777777777777777777777' as Address;
9+
const signerFreezeAuthority = TEST_AUTHORITY;
10+
11+
beforeEach(() => {
12+
rpc = createMockRpc();
13+
resetMockRpc(rpc);
14+
});
15+
16+
test('does not throw when a signer freeze authority has no on-chain account', async () => {
17+
seedMintDetails(rpc, {
18+
address: mint,
19+
decimals: 6,
20+
freezeAuthority: signerFreezeAuthority,
21+
mintAuthority: signerFreezeAuthority,
22+
});
23+
24+
await expect(getMintDetails(rpc, mint)).resolves.toMatchObject({
25+
decimals: 6,
26+
freezeAuthority: signerFreezeAuthority,
27+
mintAuthority: signerFreezeAuthority,
28+
usesTokenAcl: false,
29+
});
30+
});
31+
32+
test('marks usesTokenAcl when the freeze authority account is owned by the Token ACL program', async () => {
33+
seedMintDetails(rpc, {
34+
address: mint,
35+
decimals: 6,
36+
freezeAuthority: signerFreezeAuthority,
37+
});
38+
seedAccountOwner(rpc, signerFreezeAuthority, TOKEN_ACL_PROGRAM_ID);
39+
40+
await expect(getMintDetails(rpc, mint)).resolves.toMatchObject({
41+
freezeAuthority: signerFreezeAuthority,
42+
usesTokenAcl: true,
43+
});
44+
});
45+
});

packages/sdk/src/transaction-util.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,6 @@ export async function getMintDetails(rpc: Rpc<SolanaRpcApi>, mint: Address, comm
216216
const freezeAuthorityAccountInfo = await rpc
217217
.getAccountInfo(address(mintInfo.freezeAuthority), { commitment })
218218
.send();
219-
if (!freezeAuthorityAccountInfo.value) {
220-
throw new Error(`Freeze authority account ${mintInfo.freezeAuthority} not found`);
221-
}
222219
usesTokenAcl = freezeAuthorityAccountInfo.value?.owner === TOKEN_ACL_PROGRAM_ID;
223220
}
224221

0 commit comments

Comments
 (0)