Created
July 11, 2025 18:50
-
-
Save ngundotra/e1940b732574bc81a063eeae3fc10dc8 to your computer and use it in GitHub Desktop.
Get Top SAS Issuers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
createSolanaRpc, | |
getBase58Codec, | |
getBase64Encoder, | |
type Address, | |
type Base58EncodedBytes, | |
type Codec, | |
type GetProgramAccountsDatasizeFilter, | |
type GetProgramAccountsMemcmpFilter, | |
type Lamports, | |
type Rpc, | |
type SolanaRpcApi | |
} from '@solana/kit'; | |
import { | |
getCredentialCodec, | |
getAttestationCodec, | |
SOLANA_ATTESTATION_SERVICE_PROGRAM_ADDRESS, | |
type Attestation, | |
type Credential | |
} from 'sas-lib'; | |
import 'dotenv/config'; | |
const CREDENTIAL_DISCRIMINATOR = 0; | |
const ATTESTATION_DISCRIMINATOR = 2; | |
const DISCRIMATOR_POSITION = 0n; | |
const ENDPOINT = process.env.ENDPOINT || 'https://api.mainnet-beta.solana.com'; | |
type GetProgramAccountsFilter = | |
| GetProgramAccountsDatasizeFilter | |
| GetProgramAccountsMemcmpFilter; | |
type GetProgramAccountsFilters = Array<GetProgramAccountsFilter>; | |
interface DecodedAccount<T> { | |
address: Address; | |
lamports: Lamports; | |
owner: Address; | |
parsed: T; | |
} | |
interface TopIssuerResult { | |
authority: Address | null; | |
count: number; | |
} | |
async function getParsedAccounts<T>( | |
rpc: Rpc<SolanaRpcApi>, | |
programId: Address, | |
filters: GetProgramAccountsFilters, | |
codec: Codec<T> | |
): Promise<DecodedAccount<T>[]> { | |
try { | |
const base64Encoder = getBase64Encoder(); | |
const accounts = await rpc | |
.getProgramAccounts(programId, { | |
commitment: 'confirmed', | |
encoding: 'base64', | |
filters | |
}) | |
.send(); | |
return accounts.map((account) => { | |
let { data } = account.account; | |
let bytes = base64Encoder.encode(data[0]); | |
let address = account.pubkey; | |
let lamports = account.account.lamports; | |
let owner = account.account.owner; | |
return { | |
address, | |
lamports, | |
owner, | |
parsed: codec.decode(bytes) | |
}; | |
}); | |
} catch (error) { | |
throw new Error( | |
`Failed to fetch accounts for program ${programId}`, | |
); | |
} | |
} | |
export async function getAllCredentials( | |
rpc: Rpc<SolanaRpcApi> | |
): Promise<DecodedAccount<Credential>[]> { | |
const base58Codec = getBase58Codec(); | |
const credentialCodec = getCredentialCodec(); | |
const discriminatorByte = new Uint8Array([CREDENTIAL_DISCRIMINATOR]); | |
const filters: GetProgramAccountsFilters = [ | |
{ | |
memcmp: { | |
offset: DISCRIMATOR_POSITION, | |
encoding: 'base58', | |
bytes: base58Codec.decode(discriminatorByte) as Base58EncodedBytes, | |
}, | |
}, | |
]; | |
return await getParsedAccounts(rpc, SOLANA_ATTESTATION_SERVICE_PROGRAM_ADDRESS, filters, credentialCodec); | |
} | |
export async function getAllAttestations( | |
rpc: Rpc<SolanaRpcApi> | |
): Promise<DecodedAccount<Attestation>[]> { | |
const base58Codec = getBase58Codec(); | |
const attestationCodec = getAttestationCodec(); | |
const discriminatorByte = new Uint8Array([ATTESTATION_DISCRIMINATOR]); | |
const filters: GetProgramAccountsFilters = [ | |
{ | |
memcmp: { | |
offset: DISCRIMATOR_POSITION, | |
encoding: 'base58', | |
bytes: base58Codec.decode(discriminatorByte) as Base58EncodedBytes, | |
}, | |
}, | |
]; | |
return await getParsedAccounts(rpc, SOLANA_ATTESTATION_SERVICE_PROGRAM_ADDRESS, filters, attestationCodec); | |
} | |
export async function findIssuerWithMostAttestations( | |
rpc: Rpc<SolanaRpcApi> | |
): Promise<[Address, number][] | null> { | |
const [allCredentials, allAttestations] = await Promise.all([ | |
getAllCredentials(rpc), | |
getAllAttestations(rpc) | |
]); | |
if (allCredentials.length === 0) { | |
return null; | |
} | |
const credentialToAuthority = new Map<Address, Address>(); | |
allCredentials.forEach(credential => { | |
credentialToAuthority.set(credential.address, credential.parsed.authority); | |
}); | |
const authorityAttestationCounts = new Map<Address, number>(); | |
allAttestations.forEach(attestation => { | |
const authority = credentialToAuthority.get(attestation.parsed.credential); | |
if (authority) { | |
const currentCount = authorityAttestationCounts.get(authority) || 0; | |
authorityAttestationCounts.set(authority, currentCount + 1); | |
} | |
}); | |
return [...authorityAttestationCounts.entries()].sort((a, b) => b[1] - a[1]) | |
} | |
async function main() { | |
const rpc = createSolanaRpc(ENDPOINT); | |
const topIssuers = await findIssuerWithMostAttestations(rpc); | |
console.log('Top issuers:') | |
topIssuers?.forEach(([authority, count]) => { | |
console.log(`${authority}: ${count}`); | |
}); | |
} | |
main().catch((e) => console.log("ERROR", e)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment