diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f625621b2..5621d908c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ The minor version will be incremented upon a breaking change and the patch versi ### Features +- ts: Re-implement `verifiedBuild` using the OtterSec registry (`verify.osec.io`), replacing the defunct `apr.dev` API ([#4522](https://github.com/solana-foundation/anchor/pull/4522)). - ts: Add `decodeIdlAccountRaw` ([#4375](https://github.com/solana-foundation/anchor/pull/4375)). - cli: Add `--stdout` flag to the `expand` command ([#4400](https://github.com/solana-foundation/anchor/pull/4400)). - client: Add versioned tx support ([#4207](https://github.com/solana-foundation/anchor/pull/4207)). @@ -185,7 +186,7 @@ The minor version will be incremented upon a breaking change and the patch versi - spl: Update SPL dependencies to latest compatible versions ([#3860](https://github.com/solana-foundation/anchor/pull/3860)). - cli: Replace `anchor verify` to use `solana-verify` under the hood, adding automatic installation via AVM, local path support, and future-proof argument passing ([#3768](https://github.com/solana-foundation/anchor/pull/3768)). -- cli: Upload IDL by default with an option to skip ((#3863)[https://github.com/solana-foundation/anchor/pull/3863]). +- cli: Upload IDL by default with an option to skip ([#3863](https://github.com/solana-foundation/anchor/pull/3863)). - lang: remove Solang ([#3824](https://github.com/solana-foundation/anchor/pull/3824)). - cli: remove `anchor publish` command ([#3795](https://github.com/solana-foundation/anchor/pull/3795)). @@ -477,7 +478,7 @@ See the [Anchor 0.30 release notes](https://www.anchor-lang.com/release-notes/0. - spl: Fix not being able to deserialize newer token 2022 extensions ([#2876](https://github.com/solana-foundation/anchor/pull/2876)). - client: Fix erroneous Cluster websocket ports ([#2690](https://github.com/solana-foundation/anchor/pull/2690)). - spl: Remove `solana-program` dependency ([#2900](https://github.com/solana-foundation/anchor/pull/2900)). -- spl: Make `TokenAccount` and ` Mint` `Copy` ([#2904](https://github.com/solana-foundation/anchor/pull/2904)). +- spl: Make `TokenAccount` and `Mint` `Copy` ([#2904](https://github.com/solana-foundation/anchor/pull/2904)). - ts: Add missing errors ([#2906](https://github.com/solana-foundation/anchor/pull/2906)). ### Breaking @@ -822,9 +823,9 @@ See the [Anchor 0.29 release notes](https://www.anchor-lang.com/release-notes/0. - lang: Require doc comments when using AccountInfo or UncheckedAccount types ([#1452](https://github.com/solana-foundation/anchor/pull/1452)). - lang: add [`error!`](https://docs.rs/anchor-lang/latest/anchor_lang/prelude/macro.error.html) and [`err!`](https://docs.rs/anchor-lang/latest/anchor_lang/prelude/macro.err.html) macro and `Result` type ([#1462](https://github.com/solana-foundation/anchor/pull/1462)). This change will break most programs. Do the following to upgrade: - _ change all `ProgramResult`'s to `Result<()>` + _change all `ProgramResult`'s to `Result<()>` _ change `#[error]` to `#[error_code]` - _ change all `Err(MyError::SomeError.into())` to `Err(error!(MyError::SomeError))` and all `Err(ProgramError::SomeProgramError)` to `Err(ProgramError::SomeProgramError.into())` or `Err(Error::from(ProgramError::SomeProgramError).with_source(source!()))` to provide file and line source of the error (`with_source` is most useful with `ProgramError`s. `error!` already adds source information for custom and anchor internal errors). + _change all `Err(MyError::SomeError.into())` to `Err(error!(MyError::SomeError))` and all `Err(ProgramError::SomeProgramError)` to `Err(ProgramError::SomeProgramError.into())` or `Err(Error::from(ProgramError::SomeProgramError).with_source(source!()))` to provide file and line source of the error (`with_source` is most useful with `ProgramError`s. `error!` already adds source information for custom and anchor internal errors). _ change all `solana_program::program::invoke()` to `solana_program::program::invoke().map_err(Into::into)` and `solana_program::program::invoke_signed()` to `solana_program::program::invoke_signed().map_err(Into::into)` ## [0.21.0] - 2022-02-07 diff --git a/Untitled b/Untitled new file mode 100644 index 0000000000..379fa987e5 --- /dev/null +++ b/Untitled @@ -0,0 +1 @@ +ts: Re-implement \ No newline at end of file diff --git a/ts/packages/anchor/src/utils/registry.ts b/ts/packages/anchor/src/utils/registry.ts index 6e389f541d..86ed5676fe 100644 --- a/ts/packages/anchor/src/utils/registry.ts +++ b/ts/packages/anchor/src/utils/registry.ts @@ -1,14 +1,45 @@ import BN from "bn.js"; +import fetch from "cross-fetch"; import * as borsh from "@anchor-lang/borsh"; import { Connection, PublicKey } from "@solana/web3.js"; +const OSEC_REGISTRY_URL = "https://verify.osec.io"; + +export type VerifiedBuild = { + is_verified: boolean; + message: string; + on_chain_hash: string; + executable_hash: string; + repo_url: string; + commit: string; + last_verified_at: string | null; + is_frozen: boolean; + is_closed: boolean; +}; + +/** Returns verified build info from the OtterSec registry, or null if unverified or the request fails. */ +export async function verifiedBuild( + programId: PublicKey, +): Promise { + try { + const resp = await fetch( + `${OSEC_REGISTRY_URL}/status/${programId.toString()}`, + ); + if (!resp.ok) return null; + const build = (await resp.json()) as VerifiedBuild; + return build.is_verified ? build : null; + } catch { + return null; + } +} + /** * Returns the program data account for this program, containing the * metadata for this program, e.g., the upgrade authority. */ export async function fetchData( connection: Connection, - programId: PublicKey + programId: PublicKey, ): Promise { const accountInfo = await connection.getAccountInfo(programId); if (accountInfo === null) { @@ -16,13 +47,13 @@ export async function fetchData( } const { program } = decodeUpgradeableLoaderState(accountInfo.data); const programdataAccountInfo = await connection.getAccountInfo( - program.programdataAddress + program.programdataAddress, ); if (programdataAccountInfo === null) { throw new Error("program data account not found"); } const { programData } = decodeUpgradeableLoaderState( - programdataAccountInfo.data + programdataAccountInfo.data, ); return programData; } @@ -32,7 +63,7 @@ const UPGRADEABLE_LOADER_STATE_LAYOUT = borsh.rustEnum( borsh.struct([], "uninitialized"), borsh.struct( [borsh.option(borsh.publicKey(), "authorityAddress")], - "buffer" + "buffer", ), borsh.struct([borsh.publicKey("programdataAddress")], "program"), borsh.struct( @@ -40,11 +71,11 @@ const UPGRADEABLE_LOADER_STATE_LAYOUT = borsh.rustEnum( borsh.u64("slot"), borsh.option(borsh.publicKey(), "upgradeAuthorityAddress"), ], - "programData" + "programData", ), ], undefined, - borsh.u32() + borsh.u32(), ); export function decodeUpgradeableLoaderState(data: Buffer): any {