Use wasm to decode stake account
This commit is contained in:
parent
29ec98d0a1
commit
26e4767fdd
@ -1 +1,2 @@
|
|||||||
build
|
build
|
||||||
|
wasm
|
||||||
|
25
explorer/config-overrides.js
Normal file
25
explorer/config-overrides.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = function override(config, env) {
|
||||||
|
const wasmExtensionRegExp = /\.wasm$/;
|
||||||
|
|
||||||
|
config.resolve.extensions.push(".wasm");
|
||||||
|
|
||||||
|
config.module.rules.forEach(rule => {
|
||||||
|
(rule.oneOf || []).forEach(oneOf => {
|
||||||
|
if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
|
||||||
|
// Make file-loader ignore WASM files
|
||||||
|
oneOf.exclude.push(wasmExtensionRegExp);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add a dedicated loader for WASM
|
||||||
|
config.module.rules.push({
|
||||||
|
test: wasmExtensionRegExp,
|
||||||
|
include: path.resolve(__dirname, "src"),
|
||||||
|
use: [{ loader: require.resolve("wasm-loader"), options: {} }]
|
||||||
|
});
|
||||||
|
|
||||||
|
return config;
|
||||||
|
};
|
59
explorer/package-lock.json
generated
59
explorer/package-lock.json
generated
@ -8902,6 +8902,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz",
|
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz",
|
||||||
"integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A=="
|
"integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A=="
|
||||||
},
|
},
|
||||||
|
"long": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz",
|
||||||
|
"integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s="
|
||||||
|
},
|
||||||
"loose-envify": {
|
"loose-envify": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
|
||||||
@ -11554,6 +11559,14 @@
|
|||||||
"whatwg-fetch": "^3.0.0"
|
"whatwg-fetch": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-app-rewired": {
|
||||||
|
"version": "2.1.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-app-rewired/-/react-app-rewired-2.1.6.tgz",
|
||||||
|
"integrity": "sha512-06flj0kK5tf/RN4naRv/sn6j3sQd7rsURoRLKLpffXDzJeNiAaTNic+0I8Basojy5WDwREkTqrMLewSAjcb13w==",
|
||||||
|
"requires": {
|
||||||
|
"semver": "^5.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-dev-utils": {
|
"react-dev-utils": {
|
||||||
"version": "10.2.0",
|
"version": "10.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.0.tgz",
|
||||||
@ -12959,6 +12972,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"solana-sdk-wasm": {
|
||||||
|
"version": "file:wasm/pkg"
|
||||||
|
},
|
||||||
"sort-keys": {
|
"sort-keys": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
|
||||||
@ -14194,6 +14210,34 @@
|
|||||||
"makeerror": "1.0.x"
|
"makeerror": "1.0.x"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"wasm-dce": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasm-dce/-/wasm-dce-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-Fq1+nu43ybsjSnBquLrW/cULmKs61qbv9k8ep13QUe0nABBezMoNAA+j6QY66MW0/eoDVDp1rjXDqQ2VKyS/Xg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/core": "^7.0.0-beta.39",
|
||||||
|
"@babel/traverse": "^7.0.0-beta.39",
|
||||||
|
"@babel/types": "^7.0.0-beta.39",
|
||||||
|
"babylon": "^7.0.0-beta.39",
|
||||||
|
"webassembly-interpreter": "0.0.30"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"babylon": {
|
||||||
|
"version": "7.0.0-beta.47",
|
||||||
|
"resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.47.tgz",
|
||||||
|
"integrity": "sha512-+rq2cr4GDhtToEzKFD6KZZMDBXhjFAr9JjPw9pAppZACeEWqNM294j+NdBzkSHYXwzzBmVjZ3nEVJlOhbR2gOQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wasm-loader": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasm-loader/-/wasm-loader-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-R4s75XH+o8qM+WaRrAU9S2rbAMDzob18/S3V8R9ZoFpZkPWLAohWWlzWAp1ybeTkOuuku/X1zJtxiV0pBYxZww==",
|
||||||
|
"requires": {
|
||||||
|
"loader-utils": "^1.1.0",
|
||||||
|
"wasm-dce": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||||
@ -14770,6 +14814,21 @@
|
|||||||
"minimalistic-assert": "^1.0.0"
|
"minimalistic-assert": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"webassembly-floating-point-hex-parser": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/webassembly-floating-point-hex-parser/-/webassembly-floating-point-hex-parser-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-TUf1H++8U10+stJbFydnvrpG5Sznz5Rilez/oZlV5zI0C/e4cSxd8rALAJ8VpTvjVWxLmL3SVSJUK6Ap9AoiNg=="
|
||||||
|
},
|
||||||
|
"webassembly-interpreter": {
|
||||||
|
"version": "0.0.30",
|
||||||
|
"resolved": "https://registry.npmjs.org/webassembly-interpreter/-/webassembly-interpreter-0.0.30.tgz",
|
||||||
|
"integrity": "sha512-+Jdy2piEvz9T5j751mOE8+rBO12p+nNW6Fg4kJZ+zP1oUfsm+151sbAbM8AFxWTURmWCGP+r8Lxwfv3pzN1bCQ==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/code-frame": "^7.0.0-beta.36",
|
||||||
|
"long": "^3.2.0",
|
||||||
|
"webassembly-floating-point-hex-parser": "0.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"webidl-conversions": {
|
"webidl-conversions": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
||||||
|
@ -18,16 +18,18 @@
|
|||||||
"node-sass": "^4.13.1",
|
"node-sass": "^4.13.1",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^1.19.1",
|
||||||
"react": "^16.13.0",
|
"react": "^16.13.0",
|
||||||
|
"react-app-rewired": "^2.1.6",
|
||||||
"react-dom": "^16.13.0",
|
"react-dom": "^16.13.0",
|
||||||
"react-router-dom": "^5.1.2",
|
"react-router-dom": "^5.1.2",
|
||||||
"react-scripts": "3.4.0",
|
"react-scripts": "3.4.0",
|
||||||
"typescript": "^3.8.0"
|
"solana-sdk-wasm": "file:wasm/pkg",
|
||||||
|
"typescript": "^3.8.0",
|
||||||
|
"wasm-loader": "^1.3.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-app-rewired start",
|
||||||
"build": "react-scripts build",
|
"build": "react-app-rewired build",
|
||||||
"test": "react-scripts test",
|
"test": "react-app-rewired test",
|
||||||
"eject": "react-scripts eject",
|
|
||||||
"format": "prettier -c \"**/*.+(js|jsx|ts|tsx|json|css|md)\"",
|
"format": "prettier -c \"**/*.+(js|jsx|ts|tsx|json|css|md)\"",
|
||||||
"format:fix": "prettier --write \"**/*.+(js|jsx|ts|tsx|json|css|md)\""
|
"format:fix": "prettier --write \"**/*.+(js|jsx|ts|tsx|json|css|md)\""
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { StakeAccount } from "solana-sdk-wasm";
|
||||||
import { useClusterModal } from "providers/cluster";
|
import { useClusterModal } from "providers/cluster";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey, StakeProgram } from "@solana/web3.js";
|
||||||
import ClusterStatusButton from "components/ClusterStatusButton";
|
import ClusterStatusButton from "components/ClusterStatusButton";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
@ -12,6 +13,10 @@ import {
|
|||||||
import { lamportsToSolString } from "utils";
|
import { lamportsToSolString } from "utils";
|
||||||
import Copyable from "./Copyable";
|
import Copyable from "./Copyable";
|
||||||
import { displayAddress } from "utils/tx";
|
import { displayAddress } from "utils/tx";
|
||||||
|
import { StakeAccountDetailsCard } from "components/account/StakeAccountDetailsCard";
|
||||||
|
import ErrorCard from "components/common/ErrorCard";
|
||||||
|
import LoadingCard from "components/common/LoadingCard";
|
||||||
|
import TableCardBody from "components/common/TableCardBody";
|
||||||
|
|
||||||
type Props = { address: string };
|
type Props = { address: string };
|
||||||
export default function AccountDetails({ address }: Props) {
|
export default function AccountDetails({ address }: Props) {
|
||||||
@ -84,11 +89,52 @@ export default function AccountDetails({ address }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{pubkey && <InfoCard pubkey={pubkey} />}
|
{pubkey && <InfoCard pubkey={pubkey} />}
|
||||||
|
{pubkey && <DetailsCard pubkey={pubkey} />}
|
||||||
{pubkey && <HistoryCard pubkey={pubkey} />}
|
{pubkey && <HistoryCard pubkey={pubkey} />}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Wasm = {
|
||||||
|
StakeAccount: typeof StakeAccount;
|
||||||
|
};
|
||||||
|
|
||||||
|
function DetailsCard({ pubkey }: { pubkey: PublicKey }) {
|
||||||
|
const address = pubkey.toBase58();
|
||||||
|
const info = useAccountInfo(address);
|
||||||
|
const [Wasm, setWasm] = React.useState<Wasm | undefined>(undefined);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
setWasm(await import("solana-sdk-wasm"));
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Unexpected error loading wasm", err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!info || !info.details || !info.details.data) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { data, owner } = info.details;
|
||||||
|
try {
|
||||||
|
if (owner.equals(StakeProgram.programId)) {
|
||||||
|
if (Wasm === undefined) {
|
||||||
|
return <LoadingCard />;
|
||||||
|
} else {
|
||||||
|
const stakeAccount = Wasm.StakeAccount.fromAccountData(data);
|
||||||
|
return <StakeAccountDetailsCard account={stakeAccount} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return <ErrorCard text="Failed to decode account data" />;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function InfoCard({ pubkey }: { pubkey: PublicKey }) {
|
function InfoCard({ pubkey }: { pubkey: PublicKey }) {
|
||||||
const address = pubkey.toBase58();
|
const address = pubkey.toBase58();
|
||||||
const info = useAccountInfo(address);
|
const info = useAccountInfo(address);
|
||||||
@ -100,7 +146,7 @@ function InfoCard({ pubkey }: { pubkey: PublicKey }) {
|
|||||||
info.status === Status.CheckFailed ||
|
info.status === Status.CheckFailed ||
|
||||||
info.lamports === undefined
|
info.lamports === undefined
|
||||||
) {
|
) {
|
||||||
return <RetryCard retry={() => refresh(pubkey)} text="Fetch Failed" />;
|
return <ErrorCard retry={() => refresh(pubkey)} text="Fetch Failed" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { details, lamports } = info;
|
const { details, lamports } = info;
|
||||||
@ -138,7 +184,7 @@ function InfoCard({ pubkey }: { pubkey: PublicKey }) {
|
|||||||
<td>Owner</td>
|
<td>Owner</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={details.owner.toBase58()}>
|
<Copyable text={details.owner.toBase58()}>
|
||||||
<code>{displayAddress(details.owner)}</code>
|
<code>{displayAddress(details.owner.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -166,7 +212,7 @@ function HistoryCard({ pubkey }: { pubkey: PublicKey }) {
|
|||||||
return <LoadingCard />;
|
return <LoadingCard />;
|
||||||
} else if (info.history === undefined) {
|
} else if (info.history === undefined) {
|
||||||
return (
|
return (
|
||||||
<RetryCard
|
<ErrorCard
|
||||||
retry={() => refresh(pubkey)}
|
retry={() => refresh(pubkey)}
|
||||||
text="Failed to fetch transaction history"
|
text="Failed to fetch transaction history"
|
||||||
/>
|
/>
|
||||||
@ -175,9 +221,9 @@ function HistoryCard({ pubkey }: { pubkey: PublicKey }) {
|
|||||||
|
|
||||||
if (info.history.size === 0) {
|
if (info.history.size === 0) {
|
||||||
return (
|
return (
|
||||||
<RetryCard
|
<ErrorCard
|
||||||
retry={() => refresh(pubkey)}
|
retry={() => refresh(pubkey)}
|
||||||
text="No transaction history found"
|
text="No recent transaction history found"
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -219,43 +265,3 @@ function HistoryCard({ pubkey }: { pubkey: PublicKey }) {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoadingCard() {
|
|
||||||
return (
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body text-center">
|
|
||||||
<span className="spinner-grow spinner-grow-sm mr-2"></span>
|
|
||||||
Loading
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function RetryCard({ retry, text }: { retry: () => void; text: string }) {
|
|
||||||
return (
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body text-center">
|
|
||||||
{text}
|
|
||||||
<span className="btn btn-white ml-3 d-none d-md-inline" onClick={retry}>
|
|
||||||
Try Again
|
|
||||||
</span>
|
|
||||||
<div className="d-block d-md-none mt-4">
|
|
||||||
<hr></hr>
|
|
||||||
<span className="btn btn-white" onClick={retry}>
|
|
||||||
Try Again
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function TableCardBody({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
|
||||||
<div className="table-responsive mb-0">
|
|
||||||
<table className="table table-sm table-nowrap card-table">
|
|
||||||
<tbody className="list">{children}</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
@ -140,7 +140,7 @@ const renderAccountRow = (account: Account) => {
|
|||||||
let owner = "-";
|
let owner = "-";
|
||||||
if (account.details) {
|
if (account.details) {
|
||||||
data = `${account.details.space}`;
|
data = `${account.details.space}`;
|
||||||
owner = displayAddress(account.details.owner);
|
owner = displayAddress(account.details.owner.toBase58());
|
||||||
}
|
}
|
||||||
|
|
||||||
let balance = "-";
|
let balance = "-";
|
||||||
|
@ -21,6 +21,9 @@ import { useHistory, useLocation } from "react-router-dom";
|
|||||||
import { UnknownDetailsCard } from "./instruction/UnknownDetailsCard";
|
import { UnknownDetailsCard } from "./instruction/UnknownDetailsCard";
|
||||||
import { SystemDetailsCard } from "./instruction/system/SystemDetailsCard";
|
import { SystemDetailsCard } from "./instruction/system/SystemDetailsCard";
|
||||||
import { StakeDetailsCard } from "./instruction/stake/StakeDetailsCard";
|
import { StakeDetailsCard } from "./instruction/stake/StakeDetailsCard";
|
||||||
|
import ErrorCard from "./common/ErrorCard";
|
||||||
|
import LoadingCard from "./common/LoadingCard";
|
||||||
|
import TableCardBody from "./common/TableCardBody";
|
||||||
|
|
||||||
type Props = { signature: TransactionSignature };
|
type Props = { signature: TransactionSignature };
|
||||||
export default function TransactionDetails({ signature }: Props) {
|
export default function TransactionDetails({ signature }: Props) {
|
||||||
@ -100,9 +103,9 @@ function StatusCard({ signature }: Props) {
|
|||||||
if (!status || status.fetchStatus === FetchStatus.Fetching) {
|
if (!status || status.fetchStatus === FetchStatus.Fetching) {
|
||||||
return <LoadingCard />;
|
return <LoadingCard />;
|
||||||
} else if (status?.fetchStatus === FetchStatus.FetchFailed) {
|
} else if (status?.fetchStatus === FetchStatus.FetchFailed) {
|
||||||
return <RetryCard retry={() => refresh(signature)} text="Fetch Failed" />;
|
return <ErrorCard retry={() => refresh(signature)} text="Fetch Failed" />;
|
||||||
} else if (!status.info) {
|
} else if (!status.info) {
|
||||||
return <RetryCard retry={() => refresh(signature)} text="Not Found" />;
|
return <ErrorCard retry={() => refresh(signature)} text="Not Found" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { info } = status;
|
const { info } = status;
|
||||||
@ -191,7 +194,7 @@ function AccountsCard({ signature }: Props) {
|
|||||||
return null;
|
return null;
|
||||||
} else if (!details) {
|
} else if (!details) {
|
||||||
return (
|
return (
|
||||||
<RetryCard
|
<ErrorCard
|
||||||
retry={refreshStatus}
|
retry={refreshStatus}
|
||||||
text="Details are not available until the transaction reaches MAX confirmations"
|
text="Details are not available until the transaction reaches MAX confirmations"
|
||||||
/>
|
/>
|
||||||
@ -199,14 +202,14 @@ function AccountsCard({ signature }: Props) {
|
|||||||
} else if (details.fetchStatus === FetchStatus.Fetching) {
|
} else if (details.fetchStatus === FetchStatus.Fetching) {
|
||||||
return <LoadingCard />;
|
return <LoadingCard />;
|
||||||
} else if (details?.fetchStatus === FetchStatus.FetchFailed) {
|
} else if (details?.fetchStatus === FetchStatus.FetchFailed) {
|
||||||
return <RetryCard retry={refreshDetails} text="Fetch Failed" />;
|
return <ErrorCard retry={refreshDetails} text="Fetch Failed" />;
|
||||||
} else if (!details.transaction || !message) {
|
} else if (!details.transaction || !message) {
|
||||||
return <RetryCard retry={refreshDetails} text="Not Found" />;
|
return <ErrorCard retry={refreshDetails} text="Not Found" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { meta } = details.transaction;
|
const { meta } = details.transaction;
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
return <RetryCard retry={refreshDetails} text="Metadata Missing" />;
|
return <ErrorCard retry={refreshDetails} text="Metadata Missing" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountRows = message.accountKeys.map((pubkey, index) => {
|
const accountRows = message.accountKeys.map((pubkey, index) => {
|
||||||
@ -228,7 +231,7 @@ function AccountsCard({ signature }: Props) {
|
|||||||
<tr key={key}>
|
<tr key={key}>
|
||||||
<td>
|
<td>
|
||||||
<Copyable text={key}>
|
<Copyable text={key}>
|
||||||
<code>{displayAddress(pubkey)}</code>
|
<code>{displayAddress(pubkey.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
<td>{renderChange()}</td>
|
<td>{renderChange()}</td>
|
||||||
@ -284,7 +287,7 @@ function InstructionsSection({ signature }: Props) {
|
|||||||
|
|
||||||
const { transaction } = details.transaction;
|
const { transaction } = details.transaction;
|
||||||
if (transaction.instructions.length === 0) {
|
if (transaction.instructions.length === 0) {
|
||||||
return <RetryCard retry={refreshDetails} text="No instructions found" />;
|
return <ErrorCard retry={refreshDetails} text="No instructions found" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = status.info.result;
|
const result = status.info.result;
|
||||||
@ -313,43 +316,3 @@ function InstructionsSection({ signature }: Props) {
|
|||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LoadingCard() {
|
|
||||||
return (
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body text-center">
|
|
||||||
<span className="spinner-grow spinner-grow-sm mr-2"></span>
|
|
||||||
Loading
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function RetryCard({ retry, text }: { retry: () => void; text: string }) {
|
|
||||||
return (
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-body text-center">
|
|
||||||
{text}
|
|
||||||
<span className="btn btn-white ml-3 d-none d-md-inline" onClick={retry}>
|
|
||||||
Try Again
|
|
||||||
</span>
|
|
||||||
<div className="d-block d-md-none mt-4">
|
|
||||||
<hr></hr>
|
|
||||||
<span className="btn btn-white" onClick={retry}>
|
|
||||||
Try Again
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function TableCardBody({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
|
||||||
<div className="table-responsive mb-0">
|
|
||||||
<table className="table table-sm table-nowrap card-table">
|
|
||||||
<tbody className="list">{children}</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
121
explorer/src/components/account/StakeAccountDetailsCard.tsx
Normal file
121
explorer/src/components/account/StakeAccountDetailsCard.tsx
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { StakeAccount } from "solana-sdk-wasm";
|
||||||
|
import TableCardBody from "components/common/TableCardBody";
|
||||||
|
import { lamportsToSolString } from "utils";
|
||||||
|
import Copyable from "components/Copyable";
|
||||||
|
import { displayAddress } from "utils/tx";
|
||||||
|
|
||||||
|
export function StakeAccountDetailsCard({
|
||||||
|
account
|
||||||
|
}: {
|
||||||
|
account: StakeAccount;
|
||||||
|
}) {
|
||||||
|
const { meta, stake } = account;
|
||||||
|
return (
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-header">
|
||||||
|
<h3 className="card-header-title mb-0 d-flex align-items-center">
|
||||||
|
Stake Account
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<TableCardBody>
|
||||||
|
<tr>
|
||||||
|
<td>State</td>
|
||||||
|
<td className="text-right">{account.displayState()}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{meta && (
|
||||||
|
<>
|
||||||
|
<tr>
|
||||||
|
<td>Rent Reserve (SOL)</td>
|
||||||
|
<td className="text-right">
|
||||||
|
{lamportsToSolString(meta.rentExemptReserve)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Authorized Staker Address</td>
|
||||||
|
<td className="text-right">
|
||||||
|
<Copyable text={meta.authorized.staker.toBase58()}>
|
||||||
|
<code>{meta.authorized.staker.toBase58()}</code>
|
||||||
|
</Copyable>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Authorized Withdrawer Address</td>
|
||||||
|
<td className="text-right">
|
||||||
|
<Copyable text={meta.authorized.withdrawer.toBase58()}>
|
||||||
|
<code>{meta.authorized.withdrawer.toBase58()}</code>
|
||||||
|
</Copyable>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Lockup Expiry Epoch</td>
|
||||||
|
<td className="text-right">{meta.lockup.epoch}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Lockup Expiry Timestamp</td>
|
||||||
|
<td className="text-right">
|
||||||
|
{new Date(meta.lockup.unixTimestamp).toUTCString()}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Lockup Custodian Address</td>
|
||||||
|
<td className="text-right">
|
||||||
|
<Copyable text={meta.lockup.custodian.toBase58()}>
|
||||||
|
<code>
|
||||||
|
{displayAddress(meta.lockup.custodian.toBase58())}
|
||||||
|
</code>
|
||||||
|
</Copyable>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{stake && (
|
||||||
|
<>
|
||||||
|
<tr>
|
||||||
|
<td>Delegated Stake (SOL)</td>
|
||||||
|
<td className="text-right">
|
||||||
|
{lamportsToSolString(stake.delegation.stake)}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Delegated Vote Address</td>
|
||||||
|
<td className="text-right">
|
||||||
|
<Copyable text={stake.delegation.voterPubkey.toBase58()}>
|
||||||
|
<code>
|
||||||
|
{displayAddress(stake.delegation.voterPubkey.toBase58())}
|
||||||
|
</code>
|
||||||
|
</Copyable>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Activation Epoch</td>
|
||||||
|
<td className="text-right">
|
||||||
|
{stake.delegation.isBootstrapStake()
|
||||||
|
? "-"
|
||||||
|
: stake.delegation.activationEpoch}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td>Deactivation Epoch</td>
|
||||||
|
<td className="text-right">
|
||||||
|
{stake.delegation.isDeactivated()
|
||||||
|
? stake.delegation.deactivationEpoch
|
||||||
|
: "-"}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</TableCardBody>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
33
explorer/src/components/common/ErrorCard.tsx
Normal file
33
explorer/src/components/common/ErrorCard.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function ErrorCard({
|
||||||
|
retry,
|
||||||
|
text
|
||||||
|
}: {
|
||||||
|
retry?: () => void;
|
||||||
|
text: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body text-center">
|
||||||
|
{text}
|
||||||
|
{retry && (
|
||||||
|
<>
|
||||||
|
<span
|
||||||
|
className="btn btn-white ml-3 d-none d-md-inline"
|
||||||
|
onClick={retry}
|
||||||
|
>
|
||||||
|
Try Again
|
||||||
|
</span>
|
||||||
|
<div className="d-block d-md-none mt-4">
|
||||||
|
<hr></hr>
|
||||||
|
<span className="btn btn-white" onClick={retry}>
|
||||||
|
Try Again
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
12
explorer/src/components/common/LoadingCard.tsx
Normal file
12
explorer/src/components/common/LoadingCard.tsx
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function LoadingCard() {
|
||||||
|
return (
|
||||||
|
<div className="card">
|
||||||
|
<div className="card-body text-center">
|
||||||
|
<span className="spinner-grow spinner-grow-sm mr-2"></span>
|
||||||
|
Loading
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
15
explorer/src/components/common/TableCardBody.tsx
Normal file
15
explorer/src/components/common/TableCardBody.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export default function TableCardBody({
|
||||||
|
children
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className="table-responsive mb-0">
|
||||||
|
<table className="table table-sm table-nowrap card-table">
|
||||||
|
<tbody className="list">{children}</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -19,7 +19,7 @@ export function RawDetails({ ix }: { ix: TransactionInstruction }) {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={ix.programId.toBase58()}>
|
<Copyable bottom text={ix.programId.toBase58()}>
|
||||||
<code>{displayAddress(ix.programId)}</code>
|
<code>{displayAddress(ix.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -53,7 +53,7 @@ export function AuthorizeDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(StakeProgram.programId)}</code>
|
<code>{displayAddress(StakeProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -39,7 +39,7 @@ export function DeactivateDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(StakeProgram.programId)}</code>
|
<code>{displayAddress(StakeProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -40,7 +40,7 @@ export function DelegateDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(StakeProgram.programId)}</code>
|
<code>{displayAddress(StakeProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -40,7 +40,7 @@ export function InitializeDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(StakeProgram.programId)}</code>
|
<code>{displayAddress(StakeProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -88,7 +88,7 @@ export function InitializeDetailsCard(props: {
|
|||||||
<td>Lockup Custodian Address</td>
|
<td>Lockup Custodian Address</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={params.lockup.custodian.toBase58()}>
|
<Copyable text={params.lockup.custodian.toBase58()}>
|
||||||
<code>{displayAddress(params.lockup.custodian)}</code>
|
<code>{displayAddress(params.lockup.custodian.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -36,7 +36,7 @@ export function SplitDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(StakeProgram.programId)}</code>
|
<code>{displayAddress(StakeProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -41,7 +41,7 @@ export function WithdrawDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
<Copyable bottom text={StakeProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(StakeProgram.programId)}</code>
|
<code>{displayAddress(StakeProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -38,7 +38,7 @@ export function AllocateDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -39,7 +39,7 @@ export function AllocateWithSeedDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -80,7 +80,7 @@ export function AllocateWithSeedDetailsCard(props: {
|
|||||||
<td>Assigned Owner</td>
|
<td>Assigned Owner</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={params.programId.toBase58()}>
|
<Copyable text={params.programId.toBase58()}>
|
||||||
<code>{displayAddress(params.programId)}</code>
|
<code>{displayAddress(params.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -38,7 +38,7 @@ export function AssignDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -56,7 +56,7 @@ export function AssignDetailsCard(props: {
|
|||||||
<td>Assigned Owner</td>
|
<td>Assigned Owner</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={params.programId.toBase58()}>
|
<Copyable text={params.programId.toBase58()}>
|
||||||
<code>{displayAddress(params.programId)}</code>
|
<code>{displayAddress(params.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -39,7 +39,7 @@ export function AssignWithSeedDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -75,7 +75,7 @@ export function AssignWithSeedDetailsCard(props: {
|
|||||||
<td>Assigned Owner</td>
|
<td>Assigned Owner</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={params.programId.toBase58()}>
|
<Copyable text={params.programId.toBase58()}>
|
||||||
<code>{displayAddress(params.programId)}</code>
|
<code>{displayAddress(params.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -40,7 +40,7 @@ export function CreateDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -77,7 +77,7 @@ export function CreateDetailsCard(props: {
|
|||||||
<td>Assigned Owner</td>
|
<td>Assigned Owner</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={params.programId.toBase58()}>
|
<Copyable text={params.programId.toBase58()}>
|
||||||
<code>{displayAddress(params.programId)}</code>
|
<code>{displayAddress(params.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -41,7 +41,7 @@ export function CreateWithSeedDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -105,7 +105,7 @@ export function CreateWithSeedDetailsCard(props: {
|
|||||||
<td>Assigned Owner</td>
|
<td>Assigned Owner</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable text={params.programId.toBase58()}>
|
<Copyable text={params.programId.toBase58()}>
|
||||||
<code>{displayAddress(params.programId)}</code>
|
<code>{displayAddress(params.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -39,7 +39,7 @@ export function NonceAdvanceDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -40,7 +40,7 @@ export function NonceAuthorizeDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -39,7 +39,7 @@ export function NonceInitializeDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -42,7 +42,7 @@ export function NonceWithdrawDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -34,7 +34,7 @@ export function TransferDetailsCard(props: {
|
|||||||
<td>Program</td>
|
<td>Program</td>
|
||||||
<td className="text-right">
|
<td className="text-right">
|
||||||
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
<Copyable bottom text={SystemProgram.programId.toBase58()}>
|
||||||
<code>{displayAddress(SystemProgram.programId)}</code>
|
<code>{displayAddress(SystemProgram.programId.toBase58())}</code>
|
||||||
</Copyable>
|
</Copyable>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -4,7 +4,8 @@ import {
|
|||||||
Connection,
|
Connection,
|
||||||
TransactionSignature,
|
TransactionSignature,
|
||||||
TransactionError,
|
TransactionError,
|
||||||
SignatureStatus
|
SignatureStatus,
|
||||||
|
StakeProgram
|
||||||
} from "@solana/web3.js";
|
} from "@solana/web3.js";
|
||||||
import { useQuery } from "../utils/url";
|
import { useQuery } from "../utils/url";
|
||||||
import { useCluster, ClusterStatus } from "./cluster";
|
import { useCluster, ClusterStatus } from "./cluster";
|
||||||
@ -27,6 +28,7 @@ export interface Details {
|
|||||||
executable: boolean;
|
executable: boolean;
|
||||||
owner: PublicKey;
|
owner: PublicKey;
|
||||||
space: number;
|
space: number;
|
||||||
|
data?: Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Account {
|
export interface Account {
|
||||||
@ -192,10 +194,18 @@ async function fetchAccountInfo(
|
|||||||
fetchStatus = Status.NotFound;
|
fetchStatus = Status.NotFound;
|
||||||
} else {
|
} else {
|
||||||
lamports = result.lamports;
|
lamports = result.lamports;
|
||||||
|
let data = undefined;
|
||||||
|
|
||||||
|
// Only save data in memory if we can decode it
|
||||||
|
if (result.owner.equals(StakeProgram.programId)) {
|
||||||
|
data = result.data;
|
||||||
|
}
|
||||||
|
|
||||||
details = {
|
details = {
|
||||||
space: result.data.length,
|
space: result.data.length,
|
||||||
executable: result.executable,
|
executable: result.executable,
|
||||||
owner: result.owner
|
owner: result.owner,
|
||||||
|
data
|
||||||
};
|
};
|
||||||
fetchStatus = Status.FetchingHistory;
|
fetchStatus = Status.FetchingHistory;
|
||||||
fetchAccountHistory(dispatch, pubkey, url);
|
fetchAccountHistory(dispatch, pubkey, url);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
PublicKey,
|
|
||||||
SystemProgram,
|
SystemProgram,
|
||||||
StakeProgram,
|
StakeProgram,
|
||||||
VOTE_PROGRAM_ID,
|
VOTE_PROGRAM_ID,
|
||||||
@ -40,8 +39,7 @@ const SYSVAR_IDS = {
|
|||||||
[SYSVAR_STAKE_HISTORY_PUBKEY.toBase58()]: "SYSVAR_STAKE_HISTORY"
|
[SYSVAR_STAKE_HISTORY_PUBKEY.toBase58()]: "SYSVAR_STAKE_HISTORY"
|
||||||
};
|
};
|
||||||
|
|
||||||
export function displayAddress(pubkey: PublicKey): string {
|
export function displayAddress(address: string): string {
|
||||||
const address = pubkey.toBase58();
|
|
||||||
return (
|
return (
|
||||||
PROGRAM_IDS[address] ||
|
PROGRAM_IDS[address] ||
|
||||||
LOADER_IDS[address] ||
|
LOADER_IDS[address] ||
|
||||||
|
16
explorer/wasm/.gitignore
vendored
Normal file
16
explorer/wasm/.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/target/
|
||||||
|
|
||||||
|
**/*.rs.bk
|
||||||
|
.cargo
|
||||||
|
|
||||||
|
/config/
|
||||||
|
|
||||||
|
# log files
|
||||||
|
*.log
|
||||||
|
log-*.txt
|
||||||
|
log-*/
|
||||||
|
|
||||||
|
# intellij files
|
||||||
|
/.idea/
|
||||||
|
/solana.iml
|
||||||
|
/.vscode/
|
179
explorer/wasm/Cargo.lock
generated
Normal file
179
explorer/wasm/Cargo.lock
generated
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "bincode"
|
||||||
|
version = "1.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bs58"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.110"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.110"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "solana-sdk-wasm"
|
||||||
|
version = "1.2.0"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"bs58",
|
||||||
|
"js-sys",
|
||||||
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4696caa4048ac7ce2bcd2e484b3cef88c1004e41b8e945a277e2c25dc0b72060"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.62"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3c7d40d09cdbf0f4895ae58cf57d92e1e57a9dd8ed2e8390514b54a47cc5551"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.62"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.62"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.62"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.62"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad"
|
27
explorer/wasm/Cargo.toml
Normal file
27
explorer/wasm/Cargo.toml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
[package]
|
||||||
|
name = "solana-sdk-wasm"
|
||||||
|
version = "1.2.0"
|
||||||
|
description = "Solana SDK Wasm"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||||
|
repository = "https://github.com/solana-labs/solana"
|
||||||
|
homepage = "https://solana.com/"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "solana_sdk_wasm"
|
||||||
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bincode = "1.2.1"
|
||||||
|
bs58 = "0.3.1"
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
js-sys = "0.3"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
targets = ["x86_64-unknown-linux-gnu"]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
# Tell `rustc` to optimize for small code size.
|
||||||
|
opt-level = "s"
|
15
explorer/wasm/README.md
Normal file
15
explorer/wasm/README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# solana-sdk-wasm
|
||||||
|
|
||||||
|
Temporary location for a Solana SDK for decoding account data in WebAssembly
|
||||||
|
|
||||||
|
### Install
|
||||||
|
|
||||||
|
cargo install wasm-pack
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
wasm-pack build
|
||||||
|
|
||||||
|
### Release
|
||||||
|
|
||||||
|
Add built files in `./pkg` to source control
|
22
explorer/wasm/pkg/package.json
Normal file
22
explorer/wasm/pkg/package.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "solana-sdk-wasm",
|
||||||
|
"collaborators": [
|
||||||
|
"Solana Maintainers <maintainers@solana.com>"
|
||||||
|
],
|
||||||
|
"description": "Solana SDK Wasm",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/solana-labs/solana"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"solana_sdk_wasm_bg.wasm",
|
||||||
|
"solana_sdk_wasm.js",
|
||||||
|
"solana_sdk_wasm.d.ts"
|
||||||
|
],
|
||||||
|
"module": "solana_sdk_wasm.js",
|
||||||
|
"homepage": "https://solana.com/",
|
||||||
|
"types": "solana_sdk_wasm.d.ts",
|
||||||
|
"sideEffects": false
|
||||||
|
}
|
140
explorer/wasm/pkg/solana_sdk_wasm.d.ts
vendored
Normal file
140
explorer/wasm/pkg/solana_sdk_wasm.d.ts
vendored
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export enum StakeState {
|
||||||
|
Uninitialized,
|
||||||
|
Initialized,
|
||||||
|
Delegated,
|
||||||
|
RewardsPool,
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Authorized {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
staker: Pubkey;
|
||||||
|
/**
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
withdrawer: Pubkey;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Delegation {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isBootstrapStake(): boolean;
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isDeactivated(): boolean;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly activationEpoch: number;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly deactivationEpoch: number;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly stake: number;
|
||||||
|
/**
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
readonly voterPubkey: Pubkey;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly warmupCooldownRate: number;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Lockup {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* custodian signature on a transaction exempts the operation from
|
||||||
|
* lockup constraints
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
custodian: Pubkey;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly epoch: number;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly unixTimestamp: number;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Meta {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @returns {Authorized}
|
||||||
|
*/
|
||||||
|
authorized: Authorized;
|
||||||
|
/**
|
||||||
|
* @returns {Lockup}
|
||||||
|
*/
|
||||||
|
lockup: Lockup;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly rentExemptReserve: number;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Pubkey {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
toBase58(): string;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Stake {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
readonly creditsObserved: number;
|
||||||
|
/**
|
||||||
|
* @returns {Delegation}
|
||||||
|
*/
|
||||||
|
delegation: Delegation;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class StakeAccount {
|
||||||
|
free(): void;
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @returns {StakeAccount}
|
||||||
|
*/
|
||||||
|
static fromAccountData(data: Uint8Array): StakeAccount;
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
displayState(): string;
|
||||||
|
/**
|
||||||
|
* @returns {Meta | undefined}
|
||||||
|
*/
|
||||||
|
meta?: Meta;
|
||||||
|
/**
|
||||||
|
* @returns {Stake | undefined}
|
||||||
|
*/
|
||||||
|
stake?: Stake;
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
state: number;
|
||||||
|
}
|
2
explorer/wasm/pkg/solana_sdk_wasm.js
Normal file
2
explorer/wasm/pkg/solana_sdk_wasm.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import * as wasm from "./solana_sdk_wasm_bg.wasm";
|
||||||
|
export * from "./solana_sdk_wasm_bg.js";
|
44
explorer/wasm/pkg/solana_sdk_wasm_bg.d.ts
vendored
Normal file
44
explorer/wasm/pkg/solana_sdk_wasm_bg.d.ts
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function __wbg_stakeaccount_free(a: number): void;
|
||||||
|
export function __wbg_get_stakeaccount_meta(a: number): number;
|
||||||
|
export function __wbg_set_stakeaccount_meta(a: number, b: number): void;
|
||||||
|
export function __wbg_get_stakeaccount_stake(a: number): number;
|
||||||
|
export function __wbg_set_stakeaccount_stake(a: number, b: number): void;
|
||||||
|
export function __wbg_get_stakeaccount_state(a: number): number;
|
||||||
|
export function __wbg_set_stakeaccount_state(a: number, b: number): void;
|
||||||
|
export function stakeaccount_fromAccountData(a: number, b: number): number;
|
||||||
|
export function stakeaccount_displayState(a: number, b: number): void;
|
||||||
|
export function __wbg_lockup_free(a: number): void;
|
||||||
|
export function __wbg_get_lockup_custodian(a: number): number;
|
||||||
|
export function __wbg_set_lockup_custodian(a: number, b: number): void;
|
||||||
|
export function lockup_unix_timestamp(a: number): number;
|
||||||
|
export function lockup_epoch(a: number): number;
|
||||||
|
export function __wbg_pubkey_free(a: number): void;
|
||||||
|
export function pubkey_toBase58(a: number, b: number): void;
|
||||||
|
export function __wbg_authorized_free(a: number): void;
|
||||||
|
export function __wbg_get_authorized_staker(a: number): number;
|
||||||
|
export function __wbg_set_authorized_staker(a: number, b: number): void;
|
||||||
|
export function __wbg_get_authorized_withdrawer(a: number): number;
|
||||||
|
export function __wbg_set_authorized_withdrawer(a: number, b: number): void;
|
||||||
|
export function __wbg_meta_free(a: number): void;
|
||||||
|
export function __wbg_get_meta_authorized(a: number): number;
|
||||||
|
export function __wbg_set_meta_authorized(a: number, b: number): void;
|
||||||
|
export function __wbg_get_meta_lockup(a: number): number;
|
||||||
|
export function __wbg_set_meta_lockup(a: number, b: number): void;
|
||||||
|
export function meta_rent_exempt_reserve(a: number): number;
|
||||||
|
export function __wbg_stake_free(a: number): void;
|
||||||
|
export function __wbg_get_stake_delegation(a: number): number;
|
||||||
|
export function __wbg_set_stake_delegation(a: number, b: number): void;
|
||||||
|
export function stake_credits_observed(a: number): number;
|
||||||
|
export function __wbg_delegation_free(a: number): void;
|
||||||
|
export function delegation_voter_pubkey(a: number): number;
|
||||||
|
export function delegation_stake(a: number): number;
|
||||||
|
export function delegation_isBootstrapStake(a: number): number;
|
||||||
|
export function delegation_isDeactivated(a: number): number;
|
||||||
|
export function delegation_activation_epoch(a: number): number;
|
||||||
|
export function delegation_deactivation_epoch(a: number): number;
|
||||||
|
export function delegation_warmup_cooldown_rate(a: number): number;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
483
explorer/wasm/pkg/solana_sdk_wasm_bg.js
Normal file
483
explorer/wasm/pkg/solana_sdk_wasm_bg.js
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
import * as wasm from './solana_sdk_wasm_bg.wasm';
|
||||||
|
|
||||||
|
const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;
|
||||||
|
|
||||||
|
let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
|
||||||
|
cachedTextDecoder.decode();
|
||||||
|
|
||||||
|
let cachegetUint8Memory0 = null;
|
||||||
|
function getUint8Memory0() {
|
||||||
|
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetUint8Memory0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStringFromWasm0(ptr, len) {
|
||||||
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
const heap = new Array(32).fill(undefined);
|
||||||
|
|
||||||
|
heap.push(undefined, null, true, false);
|
||||||
|
|
||||||
|
let heap_next = heap.length;
|
||||||
|
|
||||||
|
function addHeapObject(obj) {
|
||||||
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
|
const idx = heap_next;
|
||||||
|
heap_next = heap[idx];
|
||||||
|
|
||||||
|
heap[idx] = obj;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getObject(idx) { return heap[idx]; }
|
||||||
|
|
||||||
|
function dropObject(idx) {
|
||||||
|
if (idx < 36) return;
|
||||||
|
heap[idx] = heap_next;
|
||||||
|
heap_next = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function takeObject(idx) {
|
||||||
|
const ret = getObject(idx);
|
||||||
|
dropObject(idx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLikeNone(x) {
|
||||||
|
return x === undefined || x === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _assertClass(instance, klass) {
|
||||||
|
if (!(instance instanceof klass)) {
|
||||||
|
throw new Error(`expected instance of ${klass.name}`);
|
||||||
|
}
|
||||||
|
return instance.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
|
function passArray8ToWasm0(arg, malloc) {
|
||||||
|
const ptr = malloc(arg.length * 1);
|
||||||
|
getUint8Memory0().set(arg, ptr / 1);
|
||||||
|
WASM_VECTOR_LEN = arg.length;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cachegetInt32Memory0 = null;
|
||||||
|
function getInt32Memory0() {
|
||||||
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachegetInt32Memory0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export const StakeState = Object.freeze({ Uninitialized:0,Initialized:1,Delegated:2,RewardsPool:3, });
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Authorized {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(Authorized.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_authorized_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
get staker() {
|
||||||
|
var ret = wasm.__wbg_get_authorized_staker(this.ptr);
|
||||||
|
return Pubkey.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Pubkey} arg0
|
||||||
|
*/
|
||||||
|
set staker(arg0) {
|
||||||
|
_assertClass(arg0, Pubkey);
|
||||||
|
var ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
wasm.__wbg_set_authorized_staker(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
get withdrawer() {
|
||||||
|
var ret = wasm.__wbg_get_authorized_withdrawer(this.ptr);
|
||||||
|
return Pubkey.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Pubkey} arg0
|
||||||
|
*/
|
||||||
|
set withdrawer(arg0) {
|
||||||
|
_assertClass(arg0, Pubkey);
|
||||||
|
var ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
wasm.__wbg_set_authorized_withdrawer(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Delegation {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(Delegation.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_delegation_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
get voterPubkey() {
|
||||||
|
var ret = wasm.delegation_voter_pubkey(this.ptr);
|
||||||
|
return Pubkey.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get stake() {
|
||||||
|
var ret = wasm.delegation_stake(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isBootstrapStake() {
|
||||||
|
var ret = wasm.delegation_isBootstrapStake(this.ptr);
|
||||||
|
return ret !== 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
isDeactivated() {
|
||||||
|
var ret = wasm.delegation_isDeactivated(this.ptr);
|
||||||
|
return ret !== 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get activationEpoch() {
|
||||||
|
var ret = wasm.delegation_activation_epoch(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get deactivationEpoch() {
|
||||||
|
var ret = wasm.delegation_deactivation_epoch(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get warmupCooldownRate() {
|
||||||
|
var ret = wasm.delegation_warmup_cooldown_rate(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Lockup {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(Lockup.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_lockup_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* custodian signature on a transaction exempts the operation from
|
||||||
|
* lockup constraints
|
||||||
|
* @returns {Pubkey}
|
||||||
|
*/
|
||||||
|
get custodian() {
|
||||||
|
var ret = wasm.__wbg_get_lockup_custodian(this.ptr);
|
||||||
|
return Pubkey.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* custodian signature on a transaction exempts the operation from
|
||||||
|
* lockup constraints
|
||||||
|
* @param {Pubkey} arg0
|
||||||
|
*/
|
||||||
|
set custodian(arg0) {
|
||||||
|
_assertClass(arg0, Pubkey);
|
||||||
|
var ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
wasm.__wbg_set_lockup_custodian(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get unixTimestamp() {
|
||||||
|
var ret = wasm.lockup_unix_timestamp(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get epoch() {
|
||||||
|
var ret = wasm.lockup_epoch(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Meta {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(Meta.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_meta_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Authorized}
|
||||||
|
*/
|
||||||
|
get authorized() {
|
||||||
|
var ret = wasm.__wbg_get_meta_authorized(this.ptr);
|
||||||
|
return Authorized.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Authorized} arg0
|
||||||
|
*/
|
||||||
|
set authorized(arg0) {
|
||||||
|
_assertClass(arg0, Authorized);
|
||||||
|
var ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
wasm.__wbg_set_meta_authorized(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Lockup}
|
||||||
|
*/
|
||||||
|
get lockup() {
|
||||||
|
var ret = wasm.__wbg_get_meta_lockup(this.ptr);
|
||||||
|
return Lockup.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Lockup} arg0
|
||||||
|
*/
|
||||||
|
set lockup(arg0) {
|
||||||
|
_assertClass(arg0, Lockup);
|
||||||
|
var ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
wasm.__wbg_set_meta_lockup(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get rentExemptReserve() {
|
||||||
|
var ret = wasm.meta_rent_exempt_reserve(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Pubkey {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(Pubkey.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_pubkey_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
toBase58() {
|
||||||
|
try {
|
||||||
|
wasm.pubkey_toBase58(8, this.ptr);
|
||||||
|
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||||
|
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||||
|
return getStringFromWasm0(r0, r1);
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_free(r0, r1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class Stake {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(Stake.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_stake_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Delegation}
|
||||||
|
*/
|
||||||
|
get delegation() {
|
||||||
|
var ret = wasm.__wbg_get_stake_delegation(this.ptr);
|
||||||
|
return Delegation.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Delegation} arg0
|
||||||
|
*/
|
||||||
|
set delegation(arg0) {
|
||||||
|
_assertClass(arg0, Delegation);
|
||||||
|
var ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
wasm.__wbg_set_stake_delegation(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get creditsObserved() {
|
||||||
|
var ret = wasm.stake_credits_observed(this.ptr);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export class StakeAccount {
|
||||||
|
|
||||||
|
static __wrap(ptr) {
|
||||||
|
const obj = Object.create(StakeAccount.prototype);
|
||||||
|
obj.ptr = ptr;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
free() {
|
||||||
|
const ptr = this.ptr;
|
||||||
|
this.ptr = 0;
|
||||||
|
|
||||||
|
wasm.__wbg_stakeaccount_free(ptr);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Meta | undefined}
|
||||||
|
*/
|
||||||
|
get meta() {
|
||||||
|
var ret = wasm.__wbg_get_stakeaccount_meta(this.ptr);
|
||||||
|
return ret === 0 ? undefined : Meta.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Meta | undefined} arg0
|
||||||
|
*/
|
||||||
|
set meta(arg0) {
|
||||||
|
let ptr0 = 0;
|
||||||
|
if (!isLikeNone(arg0)) {
|
||||||
|
_assertClass(arg0, Meta);
|
||||||
|
ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
}
|
||||||
|
wasm.__wbg_set_stakeaccount_meta(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {Stake | undefined}
|
||||||
|
*/
|
||||||
|
get stake() {
|
||||||
|
var ret = wasm.__wbg_get_stakeaccount_stake(this.ptr);
|
||||||
|
return ret === 0 ? undefined : Stake.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Stake | undefined} arg0
|
||||||
|
*/
|
||||||
|
set stake(arg0) {
|
||||||
|
let ptr0 = 0;
|
||||||
|
if (!isLikeNone(arg0)) {
|
||||||
|
_assertClass(arg0, Stake);
|
||||||
|
ptr0 = arg0.ptr;
|
||||||
|
arg0.ptr = 0;
|
||||||
|
}
|
||||||
|
wasm.__wbg_set_stakeaccount_stake(this.ptr, ptr0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
get state() {
|
||||||
|
var ret = wasm.__wbg_get_stakeaccount_state(this.ptr);
|
||||||
|
return ret >>> 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {number} arg0
|
||||||
|
*/
|
||||||
|
set state(arg0) {
|
||||||
|
wasm.__wbg_set_stakeaccount_state(this.ptr, arg0);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {Uint8Array} data
|
||||||
|
* @returns {StakeAccount}
|
||||||
|
*/
|
||||||
|
static fromAccountData(data) {
|
||||||
|
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
var ret = wasm.stakeaccount_fromAccountData(ptr0, len0);
|
||||||
|
return StakeAccount.__wrap(ret);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
displayState() {
|
||||||
|
try {
|
||||||
|
wasm.stakeaccount_displayState(8, this.ptr);
|
||||||
|
var r0 = getInt32Memory0()[8 / 4 + 0];
|
||||||
|
var r1 = getInt32Memory0()[8 / 4 + 1];
|
||||||
|
return getStringFromWasm0(r0, r1);
|
||||||
|
} finally {
|
||||||
|
wasm.__wbindgen_free(r0, r1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const __wbindgen_string_new = function(arg0, arg1) {
|
||||||
|
var ret = getStringFromWasm0(arg0, arg1);
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const __wbindgen_throw = function(arg0, arg1) {
|
||||||
|
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const __wbindgen_rethrow = function(arg0) {
|
||||||
|
throw takeObject(arg0);
|
||||||
|
};
|
||||||
|
|
BIN
explorer/wasm/pkg/solana_sdk_wasm_bg.wasm
Normal file
BIN
explorer/wasm/pkg/solana_sdk_wasm_bg.wasm
Normal file
Binary file not shown.
3
explorer/wasm/src/lib.rs
Normal file
3
explorer/wasm/src/lib.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
mod stake_account;
|
||||||
|
|
||||||
|
pub use stake_account::*;
|
217
explorer/wasm/src/stake_account.rs
Normal file
217
explorer/wasm/src/stake_account.rs
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
pub enum StakeState {
|
||||||
|
Uninitialized,
|
||||||
|
Initialized(Meta),
|
||||||
|
Stake(Meta, Stake),
|
||||||
|
RewardsPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = StakeState)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub enum State {
|
||||||
|
Uninitialized,
|
||||||
|
Initialized,
|
||||||
|
Delegated,
|
||||||
|
RewardsPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub struct StakeAccount {
|
||||||
|
pub meta: Option<Meta>,
|
||||||
|
pub stake: Option<Stake>,
|
||||||
|
pub state: State,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<StakeState> for StakeAccount {
|
||||||
|
fn from(state: StakeState) -> Self {
|
||||||
|
match state {
|
||||||
|
StakeState::Uninitialized => StakeAccount {
|
||||||
|
state: State::Uninitialized,
|
||||||
|
meta: None,
|
||||||
|
stake: None,
|
||||||
|
},
|
||||||
|
StakeState::Initialized(meta) => StakeAccount {
|
||||||
|
state: State::Initialized,
|
||||||
|
meta: Some(meta),
|
||||||
|
stake: None,
|
||||||
|
},
|
||||||
|
StakeState::Stake(meta, stake) => StakeAccount {
|
||||||
|
state: State::Delegated,
|
||||||
|
meta: Some(meta),
|
||||||
|
stake: Some(stake),
|
||||||
|
},
|
||||||
|
StakeState::RewardsPool => StakeAccount {
|
||||||
|
state: State::RewardsPool,
|
||||||
|
meta: None,
|
||||||
|
stake: None,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl StakeAccount {
|
||||||
|
#[wasm_bindgen(js_name = fromAccountData)]
|
||||||
|
pub fn from_account_data(data: &[u8]) -> Result<StakeAccount, JsValue> {
|
||||||
|
let stake_state: StakeState = bincode::deserialize(data)
|
||||||
|
.map_err(|_| JsValue::from_str("invalid stake account data"))?;
|
||||||
|
return Ok(stake_state.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = displayState)]
|
||||||
|
pub fn display_state(&self) -> String {
|
||||||
|
match self.state {
|
||||||
|
State::Uninitialized => "Uninitialized".to_string(),
|
||||||
|
State::Initialized => "Initialized".to_string(),
|
||||||
|
State::Delegated => "Delegated".to_string(),
|
||||||
|
State::RewardsPool => "RewardsPool".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// UnixTimestamp is an approximate measure of real-world time,
|
||||||
|
/// expressed as Unix time (ie. seconds since the Unix epoch)
|
||||||
|
pub type UnixTimestamp = i64;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
pub struct Lockup {
|
||||||
|
/// UnixTimestamp at which this stake will allow withdrawal, or
|
||||||
|
/// changes to authorized staker or withdrawer, unless the
|
||||||
|
/// transaction is signed by the custodian
|
||||||
|
unix_timestamp: UnixTimestamp,
|
||||||
|
/// epoch height at which this stake will allow withdrawal, or
|
||||||
|
/// changes to authorized staker or withdrawer, unless the
|
||||||
|
/// transaction is signed by the custodian
|
||||||
|
/// to the custodian
|
||||||
|
epoch: Epoch,
|
||||||
|
/// custodian signature on a transaction exempts the operation from
|
||||||
|
/// lockup constraints
|
||||||
|
pub custodian: Pubkey,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Lockup {
|
||||||
|
#[wasm_bindgen(getter = unixTimestamp)]
|
||||||
|
pub fn unix_timestamp(&self) -> f64 {
|
||||||
|
self.unix_timestamp as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(getter)]
|
||||||
|
pub fn epoch(&self) -> f64 {
|
||||||
|
self.epoch as f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Epoch is a unit of time a given leader schedule is honored,
|
||||||
|
/// some number of Slots.
|
||||||
|
pub type Epoch = u64;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
pub struct Pubkey([u8; 32]);
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Pubkey {
|
||||||
|
#[wasm_bindgen(js_name = toBase58)]
|
||||||
|
pub fn to_base_58(&self) -> String {
|
||||||
|
bs58::encode(&self.0).into_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
pub struct Authorized {
|
||||||
|
pub staker: Pubkey,
|
||||||
|
pub withdrawer: Pubkey,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
pub struct Meta {
|
||||||
|
rent_exempt_reserve: u64,
|
||||||
|
pub authorized: Authorized,
|
||||||
|
pub lockup: Lockup,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Meta {
|
||||||
|
#[wasm_bindgen(getter = rentExemptReserve)]
|
||||||
|
pub fn rent_exempt_reserve(&self) -> f64 {
|
||||||
|
self.rent_exempt_reserve as f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
pub struct Stake {
|
||||||
|
pub delegation: Delegation,
|
||||||
|
/// credits observed is credits from vote account state when delegated or redeemed
|
||||||
|
credits_observed: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Stake {
|
||||||
|
#[wasm_bindgen(getter = creditsObserved)]
|
||||||
|
pub fn credits_observed(&self) -> f64 {
|
||||||
|
self.credits_observed as f64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Clone, Copy)]
|
||||||
|
pub struct Delegation {
|
||||||
|
/// to whom the stake is delegated
|
||||||
|
voter_pubkey: Pubkey,
|
||||||
|
/// activated stake amount, set at delegate() time
|
||||||
|
stake: u64,
|
||||||
|
/// epoch at which this stake was activated, std::Epoch::MAX if is a bootstrap stake
|
||||||
|
activation_epoch: Epoch,
|
||||||
|
/// epoch the stake was deactivated, std::Epoch::MAX if not deactivated
|
||||||
|
deactivation_epoch: Epoch,
|
||||||
|
/// how much stake we can activate per-epoch as a fraction of currently effective stake
|
||||||
|
warmup_cooldown_rate: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Delegation {
|
||||||
|
#[wasm_bindgen(getter = voterPubkey)]
|
||||||
|
pub fn voter_pubkey(&self) -> Pubkey {
|
||||||
|
self.voter_pubkey
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(getter)]
|
||||||
|
pub fn stake(&self) -> f64 {
|
||||||
|
self.stake as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = isBootstrapStake)]
|
||||||
|
pub fn is_bootstrap_stake(&self) -> bool {
|
||||||
|
self.activation_epoch == Epoch::MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(js_name = isDeactivated)]
|
||||||
|
pub fn is_deactivated(&self) -> bool {
|
||||||
|
self.deactivation_epoch != Epoch::MAX
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(getter = activationEpoch)]
|
||||||
|
pub fn activation_epoch(&self) -> f64 {
|
||||||
|
self.activation_epoch as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(getter = deactivationEpoch)]
|
||||||
|
pub fn deactivation_epoch(&self) -> f64 {
|
||||||
|
self.deactivation_epoch as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(getter = warmupCooldownRate)]
|
||||||
|
pub fn warmup_cooldown_rate(&self) -> f64 {
|
||||||
|
self.warmup_cooldown_rate
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user