View Source Signet.Solana.PDA (Signet v1.6.0)

Program Derived Addresses (PDAs) for Solana.

A PDA is an address derived from seeds and a program ID that is guaranteed to NOT be on the Ed25519 curve (no private key can sign for it). Only the owning program can "sign" for a PDA via cross-program invocation.

Examples

iex> {:ok, {address, bump}} = Signet.Solana.PDA.find_program_address(["hello"], <<0::256>>)
iex> byte_size(address)
32
iex> bump >= 0 and bump <= 255
true

Summary

Functions

Create a program address from seeds (including bump) and program ID.

Find a program-derived address from seeds and a program ID.

Check if 32 bytes represent a valid Ed25519 public key (on the curve).

Functions

Link to this function

create_program_address(seeds, arg)

View Source
@spec create_program_address([binary()], <<_::256>>) ::
  {:ok, <<_::256>>} | {:error, :on_curve}

Create a program address from seeds (including bump) and program ID.

Returns {:ok, address} if the result is off-curve, or {:error, :on_curve} if the candidate is on the Ed25519 curve.

This is the single-attempt version where the caller provides the bump seed as part of the seeds list.

Examples

iex> {address, bump} = Signet.Solana.PDA.find_program_address!(["test"], <<0::256>>)
iex> {:ok, ^address} = Signet.Solana.PDA.create_program_address(["test", <<bump>>], <<0::256>>)
iex> byte_size(address)
32
Link to this function

find_program_address(seeds, arg)

View Source
@spec find_program_address([binary()], <<_::256>>) ::
  {:ok, {<<_::256>>, non_neg_integer()}} | {:error, :no_valid_pda}

Find a program-derived address from seeds and a program ID.

Tries bump seeds from 255 down to 0, returning the first off-curve result.

Examples

iex> {:ok, {_address, bump}} = Signet.Solana.PDA.find_program_address(["hello"], <<0::256>>)
iex> bump >= 0 and bump <= 255
true
Link to this function

find_program_address!(seeds, program_id)

View Source
@spec find_program_address!([binary()], <<_::256>>) :: {<<_::256>>, non_neg_integer()}

Like find_program_address/2, but raises on failure.

Examples

iex> {_address, bump} = Signet.Solana.PDA.find_program_address!(["hello"], <<0::256>>)
iex> bump >= 0 and bump <= 255
true
@spec on_curve?(<<_::256>>) :: boolean()

Check if 32 bytes represent a valid Ed25519 public key (on the curve).

Uses Ed25519 compressed point decompression: interprets the bytes as a y-coordinate and checks if the corresponding x² is a quadratic residue mod p. Uses :crypto.mod_pow/3 for efficient modular exponentiation.

Examples

iex> valid_pub = Base.decode16!("D75A980182B10AB7D54BFED3C964073A0EE172F3DAA62325AF021A68F707511A")
iex> Signet.Solana.PDA.on_curve?(valid_pub)
true

iex> Signet.Solana.PDA.on_curve?(<<0::256>>)
true