Skip to main content

Overview

The Memory Key Service provides in-memory storage for private keys and signing functionality. It’s designed for development, testing, and scenarios where you manage keys in application memory.
The Memory Key Service stores keys in RAM without persistence. Keys are lost when the application restarts. Do not use for production applications with valuable accounts.

Creating a Memory Key Service

Method Signature

createMemoryKeyService(args: CreateMemoryKeyServiceArgs): MemoryKeyService
safeCreateMemoryKeyService(args: CreateMemoryKeyServiceArgs): Result<MemoryKeyService, Error>

Parameters

keySource
KeySource
Single key source containing a private key
keySources
KeySource[]
Array of key sources for multiple keys (mutually exclusive with keySource)
type KeySource = {
  privateKey: PrivateKey; // Ed25519 or Secp256k1 private key
};

Interface

The Memory Key Service implements the following interface:
interface MemoryKeyService {
  // Sign a transaction with a key from the service
  signTransaction(args: SignTransactionArgs): Promise<SignedTransaction>;
  safeSignTransaction(args: SignTransactionArgs): Promise<Result<SignedTransaction, Error>>;
  
  // Find a key pair by public key
  findKeyPair(args: FindKeyPairArgs): KeyPair;
  safeFindKeyPair(args: FindKeyPairArgs): Result<KeyPair, Error>;
}

Examples

Create with Single Key

import { createMemoryKeyService, randomEd25519KeyPair } from 'near-api-ts';

// Generate a new key pair
const keyPair = randomEd25519KeyPair();

// Create memory key service
const keyService = createMemoryKeyService({
  keySource: { privateKey: keyPair.privateKey }
});

console.log('Key service ready');

Create with Multiple Keys

import { createMemoryKeyService, randomEd25519KeyPair } from 'near-api-ts';

// Generate multiple key pairs
const keyPair1 = randomEd25519KeyPair();
const keyPair2 = randomEd25519KeyPair();
const keyPair3 = randomEd25519KeyPair();

// Create memory key service with multiple keys
const keyService = createMemoryKeyService({
  keySources: [
    { privateKey: keyPair1.privateKey },
    { privateKey: keyPair2.privateKey },
    { privateKey: keyPair3.privateKey }
  ]
});

Find Key Pair

import { createMemoryKeyService, randomEd25519KeyPair } from 'near-api-ts';

const keyPair = randomEd25519KeyPair();
const keyService = createMemoryKeyService({
  keySource: { privateKey: keyPair.privateKey }
});

// Find key pair by public key
const found = keyService.findKeyPair({ 
  publicKey: keyPair.publicKey 
});

console.log('Found key:', found.publicKey);

Safe Find with Error Handling

const result = keyService.safeFindKeyPair({ 
  publicKey: somePublicKey 
});

if (result.ok) {
  console.log('Found key pair:', result.value);
} else {
  if (result.error.kind === 'MemoryKeyService.FindKeyPair.NotFound') {
    console.error('Key not found in service');
  }
}

Sign Transaction

import { createMemoryKeyService, randomEd25519KeyPair, transfer } from 'near-api-ts';

const keyPair = randomEd25519KeyPair();
const keyService = createMemoryKeyService({
  keySource: { privateKey: keyPair.privateKey }
});

// Get recent block hash
const block = await client.getBlock();

// Sign transaction
const signedTx = await keyService.signTransaction({
  transaction: {
    signerAccountId: 'sender.near',
    signerPublicKey: keyPair.publicKey,
    receiverAccountId: 'receiver.near',
    nonce: 1,
    blockHash: block.rawRpcResult.header.hash,
    action: transfer({ amount: { near: '1' } })
  }
});

console.log('Transaction signed:', signedTx);

Safe Sign with Error Handling

const result = await keyService.safeSignTransaction({
  transaction: {
    signerAccountId: 'sender.near',
    signerPublicKey: keyPair.publicKey,
    receiverAccountId: 'receiver.near',
    nonce: 1,
    blockHash: recentBlockHash,
    action: transfer({ amount: { near: '1' } })
  }
});

if (result.ok) {
  console.log('Signed transaction:', result.value);
} else {
  switch (result.error.kind) {
    case 'MemoryKeyService.SignTransaction.SigningKeyPair.NotFound':
      console.error('Signing key not found');
      break;
    case 'MemoryKeyService.SignTransaction.Args.InvalidSchema':
      console.error('Invalid transaction arguments');
      break;
    default:
      console.error('Signing error:', result.error);
  }
}

Use with Client

import { createClient, createMemoryKeyService, randomEd25519KeyPair } from 'near-api-ts';

const keyPair = randomEd25519KeyPair();
const keyService = createMemoryKeyService({
  keySource: { privateKey: keyPair.privateKey }
});

const client = createClient({
  network: 'testnet',
  keyService
});

// Client can now sign transactions automatically
const result = await client.sendTransaction({
  signerAccountId: 'sender.testnet',
  signerPublicKey: keyPair.publicKey,
  receiverAccountId: 'receiver.testnet',
  actions: [/* ... */]
});

Error Types

Creation Errors

  • CreateMemoryKeyService.Args.InvalidSchema - Invalid arguments provided
  • CreateMemoryKeyService.Internal - Internal error during creation

Sign Transaction Errors

  • MemoryKeyService.SignTransaction.Args.InvalidSchema - Invalid transaction arguments
  • MemoryKeyService.SignTransaction.SigningKeyPair.NotFound - Signing key not found in service
  • MemoryKeyService.SignTransaction.Internal - Internal signing error

Find Key Pair Errors

  • MemoryKeyService.FindKeyPair.Args.InvalidSchema - Invalid search arguments
  • MemoryKeyService.FindKeyPair.NotFound - Key pair not found
  • MemoryKeyService.FindKeyPair.Internal - Internal error

Use Cases

Development

Quickly test transaction signing without setting up persistent storage

Testing

Generate and use temporary keys in automated tests

Prototyping

Build proof-of-concepts without key management infrastructure

Short-lived Keys

Applications that create and discard keys within a single session

Best Practices

The Memory Key Service is designed for development and testing. For production applications, use:
Always use safe methods (safeFindKeyPair, safeSignTransaction) in production-like code to handle errors gracefully:
const result = await keyService.safeSignTransaction({ transaction });
if (!result.ok) {
  // Handle error appropriately
  logger.error('Failed to sign transaction:', result.error);
  return;
}
Generate keys using the provided utilities:
import { randomEd25519KeyPair } from 'near-api-ts';

// Ed25519 (recommended)
const ed25519Key = randomEd25519KeyPair();

// Secp256k1 (for Bitcoin-like signatures)
const secp256k1Key = randomSecp256k1KeyPair();

Type Definitions

interface MemoryKeyService {
  signTransaction: SignTransaction;
  safeSignTransaction: SafeSignTransaction;
  findKeyPair: FindKeyPair;
  safeFindKeyPair: SafeFindKeyPair;
}

type KeySource = {
  privateKey: PrivateKey;
};

type CreateMemoryKeyServiceArgs = 
  | { keySource: KeySource; keySources?: never }
  | { keySource?: never; keySources: KeySource[] };

type SignTransactionArgs = {
  transaction: Transaction;
};

type FindKeyPairArgs = {
  publicKey: PublicKey;
};

Source Code

  • Implementation: universal/src/keyServices/memoryKeyService/createMemoryKeyService.ts:35
  • Type definitions: universal/types/keyServices/memoryKeyService/createMemoryKeyService.ts:1
  • Tests: universal/tests/unit/keyService/memoryKeyService/findKeyPair.test.ts:1