diff --git a/CHANGELOG.md b/CHANGELOG.md index 80460fff17..d44a18ed51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ The minor version will be incremented upon a breaking change and the patch versi ### Breaking - lang: Remove `state` and `interface` attributes ([#2285](https://github.com/coral-xyz/anchor/pull/2285)). +- ts: Remove `createProgramAddressSync`, `findProgramAddressSync` (now available in `@solana/web3.js`) and update `associatedAddress` to be synchronous ([#2357](https://github.com/coral-xyz/anchor/pull/2357)). ## [0.26.0] - 2022-12-15 diff --git a/tests/bpf-upgradeable-state/tests/bpf-upgradable-state.ts b/tests/bpf-upgradeable-state/tests/bpf-upgradable-state.ts index 398aca57da..157c8a2ed9 100644 --- a/tests/bpf-upgradeable-state/tests/bpf-upgradable-state.ts +++ b/tests/bpf-upgradeable-state/tests/bpf-upgradable-state.ts @@ -1,6 +1,5 @@ import * as anchor from "@coral-xyz/anchor"; import { AnchorError, Program } from "@coral-xyz/anchor"; -import { findProgramAddressSync } from "@coral-xyz/anchor/dist/cjs/utils/pubkey"; import { PublicKey } from "@solana/web3.js"; import { assert } from "chai"; import { BpfUpgradeableState } from "../target/types/bpf_upgradeable_state"; @@ -12,7 +11,7 @@ describe("bpf_upgradeable_state", () => { const program = anchor.workspace .BpfUpgradeableState as Program; - const programDataAddress = findProgramAddressSync( + const programDataAddress = PublicKey.findProgramAddressSync( [program.programId.toBytes()], new anchor.web3.PublicKey("BPFLoaderUpgradeab1e11111111111111111111111") )[0]; @@ -147,7 +146,7 @@ describe("bpf_upgradeable_state", () => { const secondProgramAddress = new PublicKey( "Fkv67TwmbakfZw2PoW57wYPbqNexAH6vuxpyT8vmrc3B" ); - const secondProgramProgramDataAddress = findProgramAddressSync( + const secondProgramProgramDataAddress = PublicKey.findProgramAddressSync( [secondProgramAddress.toBytes()], new anchor.web3.PublicKey("BPFLoaderUpgradeab1e11111111111111111111111") )[0]; @@ -176,7 +175,7 @@ describe("bpf_upgradeable_state", () => { const secondProgramAddress = new PublicKey( "Fkv67TwmbakfZw2PoW57wYPbqNexAH6vuxpyT8vmrc3B" ); - const secondProgramProgramDataAddress = findProgramAddressSync( + const secondProgramProgramDataAddress = PublicKey.findProgramAddressSync( [secondProgramAddress.toBytes()], new anchor.web3.PublicKey("BPFLoaderUpgradeab1e11111111111111111111111") )[0]; diff --git a/tests/pda-derivation/tests/typescript.spec.ts b/tests/pda-derivation/tests/typescript.spec.ts index f81166c778..7e82343c2e 100644 --- a/tests/pda-derivation/tests/typescript.spec.ts +++ b/tests/pda-derivation/tests/typescript.spec.ts @@ -1,7 +1,6 @@ import * as anchor from "@coral-xyz/anchor"; import BN from "bn.js"; -import { Keypair } from "@solana/web3.js"; -import { findProgramAddressSync } from "@coral-xyz/anchor/dist/cjs/utils/pubkey"; +import { Keypair, PublicKey } from "@solana/web3.js"; import { Program } from "@coral-xyz/anchor"; import { PdaDerivation } from "../target/types/pda_derivation"; import { expect } from "chai"; @@ -43,7 +42,7 @@ describe("typescript", () => { const MY_SEED_U8 = 1; const MY_SEED_U32 = 2; const MY_SEED_U64 = 3; - const expectedPDAKey = findProgramAddressSync( + const expectedPDAKey = PublicKey.findProgramAddressSync( [ Buffer.from([seedA]), encode("another-seed"), diff --git a/ts/packages/anchor/src/utils/pubkey.ts b/ts/packages/anchor/src/utils/pubkey.ts index 04e9b297d8..ff4e286fef 100644 --- a/ts/packages/anchor/src/utils/pubkey.ts +++ b/ts/packages/anchor/src/utils/pubkey.ts @@ -1,8 +1,7 @@ import { Buffer } from "buffer"; -import BN from "bn.js"; -import { sha256 as sha256Sync } from "js-sha256"; import { PublicKey } from "@solana/web3.js"; import { Address, translateAddress } from "../program/common.js"; +import { sha256 as sha256Sync } from "js-sha256"; // Sync version of web3.PublicKey.createWithSeed. export function createWithSeedSync( @@ -19,75 +18,15 @@ export function createWithSeedSync( return new PublicKey(Buffer.from(hash)); } -// Sync version of web3.PublicKey.createProgramAddress. -export function createProgramAddressSync( - seeds: Array, - programId: PublicKey -): PublicKey { - const MAX_SEED_LENGTH = 32; - - let buffer = Buffer.alloc(0); - seeds.forEach(function (seed) { - if (seed.length > MAX_SEED_LENGTH) { - throw new TypeError(`Max seed length exceeded`); - } - buffer = Buffer.concat([buffer, toBuffer(seed)]); - }); - buffer = Buffer.concat([ - buffer, - programId.toBuffer(), - Buffer.from("ProgramDerivedAddress"), - ]); - let hash = sha256Sync(new Uint8Array(buffer)); - let publicKeyBytes = new BN(hash, 16).toArray(undefined, 32); - if (PublicKey.isOnCurve(new Uint8Array(publicKeyBytes))) { - throw new Error(`Invalid seeds, address must fall off the curve`); - } - return new PublicKey(publicKeyBytes); -} - -// Sync version of web3.PublicKey.findProgramAddress. -export function findProgramAddressSync( - seeds: Array, - programId: PublicKey -): [PublicKey, number] { - let nonce = 255; - let address: PublicKey | undefined; - while (nonce != 0) { - try { - const seedsWithNonce = seeds.concat(Buffer.from([nonce])); - address = createProgramAddressSync(seedsWithNonce, programId); - } catch (err) { - if (err instanceof TypeError) { - throw err; - } - nonce--; - continue; - } - return [address, nonce]; - } - throw new Error(`Unable to find a viable program address nonce`); -} - -const toBuffer = (arr: Buffer | Uint8Array | Array): Buffer => { - if (arr instanceof Buffer) { - return arr; - } else if (arr instanceof Uint8Array) { - return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength); - } else { - return Buffer.from(arr); - } -}; - -export async function associated( +export function associated( programId: Address, ...args: Array
-): Promise { +): PublicKey { let seeds = [Buffer.from([97, 110, 99, 104, 111, 114])]; // b"anchor". args.forEach((arg) => { seeds.push(arg instanceof Buffer ? arg : translateAddress(arg).toBuffer()); }); - const [assoc] = await PublicKey.findProgramAddress( + const [assoc] = PublicKey.findProgramAddressSync( seeds, translateAddress(programId) ); diff --git a/ts/packages/anchor/src/utils/rpc.ts b/ts/packages/anchor/src/utils/rpc.ts index 7bd4bd79ef..b13868c8b2 100644 --- a/ts/packages/anchor/src/utils/rpc.ts +++ b/ts/packages/anchor/src/utils/rpc.ts @@ -1,5 +1,4 @@ import { Buffer } from "buffer"; -import assert from "assert"; import { AccountInfo, AccountMeta, @@ -17,7 +16,7 @@ import { } from "@solana/web3.js"; import { chunks } from "../utils/common.js"; import { Address, translateAddress } from "../program/common.js"; -import Provider, { getProvider, Wallet } from "../provider.js"; +import Provider, { getProvider } from "../provider.js"; import { type as pick, number, @@ -25,14 +24,11 @@ import { array, boolean, literal, - record, union, optional, nullable, coerce, - instance, create, - tuple, unknown, any, Struct, diff --git a/ts/packages/anchor/src/utils/token.ts b/ts/packages/anchor/src/utils/token.ts index 0f4d087e5a..e8f72e3892 100644 --- a/ts/packages/anchor/src/utils/token.ts +++ b/ts/packages/anchor/src/utils/token.ts @@ -7,17 +7,15 @@ export const ASSOCIATED_PROGRAM_ID = new PublicKey( "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL" ); -export async function associatedAddress({ +export function associatedAddress({ mint, owner, }: { mint: PublicKey; owner: PublicKey; -}): Promise { - return ( - await PublicKey.findProgramAddress( - [owner.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], - ASSOCIATED_PROGRAM_ID - ) +}): PublicKey { + return PublicKey.findProgramAddressSync( + [owner.toBuffer(), TOKEN_PROGRAM_ID.toBuffer(), mint.toBuffer()], + ASSOCIATED_PROGRAM_ID )[0]; }