forked from solana-foundation/explorer
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAnchorAccountCard.tsx
More file actions
80 lines (73 loc) · 3.36 KB
/
AnchorAccountCard.tsx
File metadata and controls
80 lines (73 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import { ErrorCard } from '@components/common/ErrorCard';
import { BorshAccountsCoder } from '@coral-xyz/anchor';
import { IdlTypeDef } from '@coral-xyz/anchor/dist/cjs/idl';
import { useAnchorProgram } from '@entities/idl';
import { Account } from '@providers/accounts';
import { useCluster } from '@providers/cluster';
import { getAnchorProgramName, mapAccountToRows } from '@utils/anchor';
import React, { useMemo } from 'react';
import { equals, toBuffer } from '@/app/shared/lib/bytes';
import { Logger } from '@/app/shared/lib/logger';
export function AnchorAccountCard({ account }: { account: Account }) {
const { lamports } = account;
const { url, cluster } = useCluster();
const { program: anchorProgram } = useAnchorProgram(account.owner.toString(), url, cluster);
const rawData = account.data.raw;
const programName = getAnchorProgramName(anchorProgram) || 'Unknown Program';
const { decodedAccountData, accountDef } = useMemo(() => {
let decodedAccountData: any | null = null;
let accountDef: IdlTypeDef | undefined = undefined;
if (anchorProgram && rawData) {
const coder = new BorshAccountsCoder(anchorProgram.idl);
const account = anchorProgram.idl.accounts?.find((accountType: any) =>
equals(rawData.slice(0, 8), coder.accountDiscriminator(accountType.name)),
);
if (account) {
accountDef = anchorProgram.idl.types?.find((type: any) => type.name === account.name);
try {
decodedAccountData = coder.decode(account.name, toBuffer(rawData));
} catch (err) {
Logger.debug('[components:anchor-account] Failed to decode account data', { error: err });
}
}
}
return {
accountDef,
decodedAccountData,
};
}, [anchorProgram, rawData]);
if (lamports === undefined) return null;
if (!anchorProgram) return <ErrorCard text="No Anchor IDL found" />;
if (!decodedAccountData || !accountDef) {
return <ErrorCard text="Failed to decode account data according to the public Anchor interface" />;
}
return (
<div>
<div className="card">
<div className="card-header">
<div className="row align-items-center">
<div className="col">
<h3 className="card-header-title">
{programName}: {accountDef.name.charAt(0).toUpperCase() + accountDef.name.slice(1)}
</h3>
</div>
</div>
</div>
<div className="table-responsive mb-0">
<table className="table table-sm table-nowrap card-table">
<thead>
<tr>
<th className="w-1">Field</th>
<th className="w-1">Type</th>
<th className="w-1">Value</th>
</tr>
</thead>
<tbody>
{mapAccountToRows(decodedAccountData, accountDef as IdlTypeDef, anchorProgram.idl)}
</tbody>
</table>
</div>
</div>
</div>
);
}