-
Notifications
You must be signed in to change notification settings - Fork 668
Expand file tree
/
Copy pathAddressTableLookupsCard.tsx
More file actions
executable file
·108 lines (99 loc) · 4.11 KB
/
Copy pathAddressTableLookupsCard.tsx
File metadata and controls
executable file
·108 lines (99 loc) · 4.11 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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
import { Address } from '@components/common/Address';
import { useAddressLookupTable } from '@providers/accounts';
import { FetchStatus } from '@providers/cache';
import { CollapsibleCard } from '@shared/ui/collapsible-card';
import { PublicKey, VersionedMessage } from '@solana/web3.js';
import React from 'react';
export function AddressTableLookupsCard({ message }: { message: VersionedMessage }) {
const lookupRows = React.useMemo(() => {
let key = 0;
return message.addressTableLookups.flatMap(lookup => {
const indexes = [
...lookup.writableIndexes.map(index => ({ index, readOnly: false })),
...lookup.readonlyIndexes.map(index => ({ index, readOnly: true })),
];
indexes.sort((a, b) => (a.index < b.index ? -1 : 1));
return indexes.map(({ index, readOnly }) => {
const props = {
lookupTableIndex: index,
lookupTableKey: lookup.accountKey,
readOnly,
};
return <LookupRow key={key++} {...props} />;
});
});
}, [message]);
if (message.version === 'legacy') return null;
return (
<CollapsibleCard title="Address Table Lookup(s)">
<div className="table-responsive mb-0">
<table className="table table-sm table-nowrap card-table">
<thead>
<tr>
<th className="text-muted">Address Lookup Table Address</th>
<th className="text-muted">Table Index</th>
<th className="text-muted">Resolved Address</th>
<th className="text-muted">Details</th>
</tr>
</thead>
{lookupRows.length > 0 ? (
<tbody className="list">{lookupRows}</tbody>
) : (
<tbody className="card-footer">
<tr>
<td colSpan={4}>
<span className="text-muted text-center">No entries found</span>
</td>
</tr>
</tbody>
)}
</table>
</div>
</CollapsibleCard>
);
}
function LookupRow({
lookupTableKey,
lookupTableIndex,
readOnly,
}: {
lookupTableKey: PublicKey;
lookupTableIndex: number;
readOnly: boolean;
}) {
const lookupTableInfo = useAddressLookupTable(lookupTableKey.toBase58());
const loadingComponent = (
<span className="text-muted">
<span className="spinner-grow spinner-grow-sm me-2"></span>
Loading
</span>
);
let resolvedKeyComponent;
if (!lookupTableInfo) {
resolvedKeyComponent = loadingComponent;
} else {
const [lookupTable, status] = lookupTableInfo;
if (status === FetchStatus.Fetching) {
resolvedKeyComponent = loadingComponent;
} else if (status === FetchStatus.FetchFailed || !lookupTable) {
resolvedKeyComponent = <span className="text-muted">Failed to fetch Lookup Table</span>;
} else if (typeof lookupTable === 'string') {
resolvedKeyComponent = <span className="text-muted">Invalid Lookup Table</span>;
} else if (lookupTableIndex >= lookupTable.state.addresses.length) {
resolvedKeyComponent = <span className="text-muted">Invalid Lookup Table Index</span>;
} else {
const resolvedKey = lookupTable.state.addresses[lookupTableIndex];
resolvedKeyComponent = <Address pubkey={resolvedKey} link />;
}
}
return (
<tr>
<td className="text-lg-end">
<Address pubkey={lookupTableKey} link />
</td>
<td className="text-lg-end">{lookupTableIndex}</td>
<td className="text-lg-end">{resolvedKeyComponent}</td>
<td>{!readOnly && <span className="badge bg-danger-soft me-1">Writable</span>}</td>
</tr>
);
}