KeyPair

public final class KeyPair : @unchecked Sendable

Holds a Stellar keypair consisting of a public key and an optional private key.

KeyPair represents an Ed25519 keypair used for signing transactions and verifying signatures on the Stellar network. A keypair can be created with or without a private key:

  • With private key: Used for signing transactions (full keypair)
  • Without private key: Used for verification only (public key only)

The public key is encoded as a Stellar account ID starting with ‘G’ (or ‘M’ for muxed accounts). The private key (seed) is encoded as a secret seed starting with ‘S’.

Security considerations:

  • Never share or expose secret seeds
  • Store secret seeds securely using the iOS Keychain or equivalent secure storage
  • Never commit secret seeds to version control
  • Use KeyPair objects without private keys when only verification is needed
  • Clear sensitive data from memory when no longer needed

Example:

// Generate a random keypair
let keyPair = try KeyPair.generateRandomKeyPair()
print("Account ID: \(keyPair.accountId)")
print("Secret Seed: \(keyPair.secretSeed)")

// Create keypair from existing secret seed
let existingKeyPair = try KeyPair(secretSeed: "SXXX...")

// Create public-only keypair for verification
let publicOnlyKeyPair = try KeyPair(accountId: "GXXX...")

// Sign data
let signature = keyPair.sign(data)

// Verify signature
let isValid = try publicOnlyKeyPair.verify(signature: signature, message: data)

See also:

  • The Ed25519 public key.

    Declaration

    Swift

    public let publicKey: PublicKey
  • The Ed25519 private key. Nil if this is a public-only keypair.

    Declaration

    Swift

    public let privateKey: PrivateKey?
  • The seed used to generate this keypair. Nil if created from raw keys or account ID.

    Declaration

    Swift

    public private(set) var seed: Seed? { get }
  • Human readable Stellar account ID (G-address).

    This is the base32-encoded public key with version byte and checksum.

    Declaration

    Swift

    public var accountId: String { get }
  • Human readable Stellar secret seed (S-address).

    This is the base32-encoded private key with version byte and checksum. Returns nil if this keypair was created without a seed.

    Warning: Keep secret seeds secure. Never expose them in logs or transmit them insecurely.

    Declaration

    Swift

    public var secretSeed: String? { get }
  • Generates a new random Stellar keypair.

    Creates a cryptographically secure random Ed25519 keypair suitable for creating new Stellar accounts. The keypair includes both public and private keys.

    Throws

    An error if random key generation fails

    Example:

    let keyPair = try KeyPair.generateRandomKeyPair()
    print("New account: \(keyPair.accountId)")
    // Securely store keyPair.secretSeed
    

    Warning: Store the secret seed securely immediately after generation.

    Declaration

    Swift

    public static func generateRandomKeyPair() throws -> KeyPair

    Return Value

    A new KeyPair with randomly generated keys

  • Creates a new KeyPair from the given public and private keys.

    Declaration

    Swift

    public init(publicKey: PublicKey, privateKey: PrivateKey?)

    Parameters

    publicKey

    The Ed25519 public key

    privateKey

    The Ed25519 private key. If nil, creates a public-only keypair that cannot sign.

  • Creates a new Stellar KeyPair from a Stellar account ID.

    Creates a public-only keypair that can be used for signature verification but cannot sign transactions. The account ID must be a valid G-address or M-address.

    Throws

    An error if the account ID is invalid

    Declaration

    Swift

    public convenience init(accountId: String) throws

    Parameters

    accountId

    The Stellar account ID (G-address or M-address)

  • Creates a new Stellar keypair from a Stellar secret seed.

    Creates a full keypair with both public and private keys from an existing secret seed (S-address). This keypair can sign transactions.

    Throws

    An error if the secret seed is invalid

    Warning: Handle secret seeds with care. Avoid logging or transmitting them insecurely.

    Declaration

    Swift

    public convenience init(secretSeed: String) throws

    Parameters

    secretSeed

    The Stellar secret seed (S-address)

  • Creates a new KeyPair without a private key. Useful e.g. to simply verify a signature from a given public address

    Declaration

    Swift

    public convenience init(publicKey: PublicKey)

    Parameters

    publicKey

    The public key

  • Creates a new Stellar keypair from a seed object. The new KeyPair contains public and private key.

    Declaration

    Swift

    public convenience init(seed: Seed)

    Parameters

    seed

    the seed object

  • Creates a new Stellar keypair from a public key byte array and a private key byte array.

    Throws

    Throws Ed25519Error.invalidPublicKeyLength if the lenght of the given byte array != 32

    Throws

    Throws Ed25519Error.invalidPrivateKeyLength if the lenght of the given byte array != 64

    Declaration

    Swift

    public convenience init(publicKey: [UInt8], privateKey: [UInt8]) throws

    Parameters

    publicKey

    the public key byte array. Must have a lenght of 32.

    privateKey

    the private key byte array. Must have a lenght of 64.

  • Sign the provided data with the keypair’s private key.

    Uses the Ed25519 signature algorithm to sign the message. If this keypair does not have a private key, returns an empty signature (all zeros).

    Warning: Only sign trusted data. Signatures prove you authorized specific content.

    Declaration

    Swift

    public func sign(_ message: [UInt8]) -> [UInt8]

    Parameters

    message

    The data to sign

    Return Value

    The 64-byte Ed25519 signature, or 64 zero bytes if no private key

  • Sign the provided data with the keypair’s private key and returns the DecoratedSignatureXDR

    Declaration

    Swift

    public func signDecorated(_ message: [UInt8]) -> DecoratedSignatureXDR

    Parameters

    data

    data to be signed

  • Signs payload data and returns a decorated signature with XOR-ed hint per CAP-40.

    Unlike signDecorated(), this method XORs the signature hint with the last 4 bytes of the payload, as required for payload signers per CAP-40 specification. The hint helps identify the signer without revealing the full public key or payload.

    Declaration

    Swift

    public func signPayloadDecorated(_ signerPayload: Data) -> DecoratedSignatureXDR

    Parameters

    signerPayload

    The payload data to sign

    Return Value

    A DecoratedSignatureXDR with XOR-ed hint and Ed25519 signature

  • Verify the provided data and signature match this keypair’s public key.

    Throws

    Ed25519Error.invalidSignatureLength if the signature length is not 64

    Declaration

    Swift

    public func verify(signature: [UInt8], message: [UInt8]) throws -> Bool

    Parameters

    signature

    The signature. Byte array must have a lenght of 64.

    message

    The data that was signed.

    Return Value

    True if they match, false otherwise.

SEP-53 Message Signing and Verification

  • Signs a binary message according to SEP-53.

    The message is prepended with “Stellar Signed Message:\n”, hashed with SHA-256, and the digest is signed with this keypair’s Ed25519 private key.

    Throws

    Ed25519Error.missingPrivateKey if this keypair has no private key.

    Declaration

    Swift

    public func signMessage(_ message: [UInt8]) throws -> [UInt8]

    Parameters

    message

    The raw bytes of the message to sign.

    Return Value

    A 64-byte Ed25519 signature.

  • Signs a UTF-8 string message according to SEP-53.

    Throws

    Ed25519Error.missingPrivateKey if this keypair has no private key.

    Declaration

    Swift

    public func signMessage(_ message: String) throws -> [UInt8]

    Parameters

    message

    The string message to sign (will be UTF-8 encoded).

    Return Value

    A 64-byte Ed25519 signature.

  • Verifies a binary message signature according to SEP-53.

    Throws

    Ed25519Error.invalidSignatureLength if signature is not 64 bytes.

    Declaration

    Swift

    public func verifyMessage(_ message: [UInt8], signature: [UInt8]) throws -> Bool

    Parameters

    message

    The original message bytes.

    signature

    The 64-byte Ed25519 signature to verify.

    Return Value

    true if the signature is valid, false otherwise.

  • Verifies a UTF-8 string message signature according to SEP-53.

    Throws

    Ed25519Error.invalidSignatureLength if signature is not 64 bytes.

    Declaration

    Swift

    public func verifyMessage(_ message: String, signature: [UInt8]) throws -> Bool

    Parameters

    message

    The original string message (will be UTF-8 encoded).

    signature

    The 64-byte Ed25519 signature to verify.

    Return Value

    true if the signature is valid, false otherwise.