Skip to content

Commit

Permalink
add tests, convenience inits
Browse files Browse the repository at this point in the history
  • Loading branch information
ngundotra committed Feb 7, 2025
1 parent 70d2375 commit 72fe206
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 14 deletions.
9 changes: 5 additions & 4 deletions typescript/agentkit/src/network/svm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const SOLANA_PROTOCOL_FAMILY = "svm";
export const SOLANA_MAINNET_GENESIS_BLOCK_HASH = "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d";
export const SOLANA_TESTNET_GENESIS_BLOCK_HASH = "4uhcVJyU9pJkvQyS88uRDiswHXSCkY3zQawwpjk2NsNY";
export const SOLANA_DEVNET_GENESIS_BLOCK_HASH = "EtWTRABZaYq6iMfeYKouRu166VU2xqa1wcaWoxPkrZBG";
export type SOLANA_CLUSTER = typeof SOLANA_MAINNET_GENESIS_BLOCK_HASH | typeof SOLANA_TESTNET_GENESIS_BLOCK_HASH | typeof SOLANA_DEVNET_GENESIS_BLOCK_HASH;

export const SOLANA_MAINNET_NETWORK: Network = {
protocolFamily: SOLANA_PROTOCOL_FAMILY,
Expand All @@ -31,9 +32,9 @@ export const SOLANA_DEVNET_NETWORK: Network = {
networkId: SOLANA_DEVNET_NETWORK_ID,
};

export const SOLANA_NETWORKS = {
[SOLANA_MAINNET_NETWORK_ID]: SOLANA_MAINNET_NETWORK,
[SOLANA_TESTNET_NETWORK_ID]: SOLANA_TESTNET_NETWORK,
[SOLANA_DEVNET_NETWORK_ID]: SOLANA_DEVNET_NETWORK,
export const SOLANA_NETWORKS: Record<SOLANA_CLUSTER, Network> = {
[SOLANA_MAINNET_GENESIS_BLOCK_HASH]: SOLANA_MAINNET_NETWORK,
[SOLANA_TESTNET_GENESIS_BLOCK_HASH]: SOLANA_TESTNET_NETWORK,
[SOLANA_DEVNET_GENESIS_BLOCK_HASH]: SOLANA_DEVNET_NETWORK,
};

2 changes: 1 addition & 1 deletion typescript/agentkit/src/wallet-providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ export * from "./evmWalletProvider";
export * from "./viemWalletProvider";
export * from "./cdpWalletProvider";
export * from "./svmWalletProvider";
export * from "./svmKeypairWalletProvider";
export * from "./solanaKeypairWalletProvider";
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { SvmWalletProvider } from "./svmWalletProvider";
import { Network } from "../network";
import { Connection, Keypair, PublicKey, VersionedTransaction, LAMPORTS_PER_SOL, SystemProgram, MessageV0, ComputeBudgetProgram } from "@solana/web3.js";
import { Connection, Keypair, PublicKey, VersionedTransaction, LAMPORTS_PER_SOL, SystemProgram, MessageV0, ComputeBudgetProgram, clusterApiUrl } from "@solana/web3.js";
import bs58 from "bs58";
import { SOLANA_NETWORKS } from "../network/svm";
import { SOLANA_CLUSTER, SOLANA_DEVNET_GENESIS_BLOCK_HASH, SOLANA_MAINNET_GENESIS_BLOCK_HASH, SOLANA_NETWORKS, SOLANA_TESTNET_GENESIS_BLOCK_HASH } from "../network/svm";

export class SvmKeypairWalletProvider extends SvmWalletProvider {
export class SolanaKeypairWalletProvider extends SvmWalletProvider {
#keypair: Keypair;
#connection: Connection;
#genesisHash: string;
Expand All @@ -27,19 +27,50 @@ export class SvmKeypairWalletProvider extends SvmWalletProvider {

this.#keypair = typeof keypair === "string" ? Keypair.fromSecretKey(bs58.decode(keypair)) : Keypair.fromSecretKey(keypair);
this.#connection = new Connection(rpcUrl);
this.#genesisHash = genesisHash;
if (genesisHash in SOLANA_NETWORKS) {
this.#genesisHash = genesisHash;
} else {
throw new Error(`Unknown network with genesis hash: ${genesisHash}`);
}
}

static urlForCluster(cluster: SOLANA_CLUSTER): string {
if (cluster in SOLANA_NETWORKS) {
switch (cluster) {
case SOLANA_MAINNET_GENESIS_BLOCK_HASH:
return clusterApiUrl('mainnet-beta');
case SOLANA_TESTNET_GENESIS_BLOCK_HASH:
return clusterApiUrl('testnet');
case SOLANA_DEVNET_GENESIS_BLOCK_HASH:
return clusterApiUrl('devnet');
default:
throw new Error(`Unknown cluster: ${cluster}`);
}
} else {
throw new Error(`Unknown cluster: ${cluster}`);
}
}

static async fromRpcUrl<T extends SolanaKeypairWalletProvider>(rpcUrl: string, keypair: Uint8Array | string): Promise<T> {
const connection = new Connection(rpcUrl);
return await this.fromConnection(connection, keypair);
}

static async fromConnection<T extends SolanaKeypairWalletProvider>(connection: Connection, keypair: Uint8Array | string): Promise<T> {
const genesisHash = await connection.getGenesisHash();
return new SolanaKeypairWalletProvider({
keypair,
rpcUrl: connection.rpcEndpoint,
genesisHash: genesisHash,
}) as T;
}

getAddress(): string {
return this.#keypair.publicKey.toBase58();
}

getNetwork(): Network {
if (this.#genesisHash in SOLANA_NETWORKS) {
return SOLANA_NETWORKS[this.#genesisHash];
} else {
throw new Error(`Unknown network with genesis hash: ${this.#genesisHash}`);
}
return SOLANA_NETWORKS[this.#genesisHash];
}

signTransaction(transaction: VersionedTransaction): VersionedTransaction {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { clusterApiUrl, Keypair } from "@solana/web3.js";
import { SolanaKeypairWalletProvider } from "./solanaKeypairWalletProvider";
import { SOLANA_DEVNET_GENESIS_BLOCK_HASH, SOLANA_MAINNET_GENESIS_BLOCK_HASH, SOLANA_NETWORKS, SOLANA_TESTNET_GENESIS_BLOCK_HASH } from "../network/svm";

describe("Solana Keypair Wallet", () => {
it("should initialize correctly via convenience getters", async () => {
const keypair = Keypair.generate();

let wallet = await SolanaKeypairWalletProvider.fromRpcUrl(clusterApiUrl('devnet'), keypair.secretKey);
expect(wallet.getNetwork()).toEqual(SOLANA_NETWORKS[SOLANA_DEVNET_GENESIS_BLOCK_HASH]);

wallet = await SolanaKeypairWalletProvider.fromRpcUrl(clusterApiUrl('testnet'), keypair.secretKey);
expect(wallet.getNetwork()).toEqual(SOLANA_NETWORKS[SOLANA_TESTNET_GENESIS_BLOCK_HASH]);

wallet = await SolanaKeypairWalletProvider.fromRpcUrl(clusterApiUrl('mainnet-beta'), keypair.secretKey);
expect(wallet.getNetwork()).toEqual(SOLANA_NETWORKS[SOLANA_MAINNET_GENESIS_BLOCK_HASH]);
expect(wallet.getAddress()).toEqual(keypair.publicKey.toBase58());
});

it("should error when the network genesis hash is unknown", async () => {
try {
new SolanaKeypairWalletProvider({ keypair: Keypair.generate().secretKey, rpcUrl: clusterApiUrl('mainnet-beta'), genesisHash: "0x123" });
} catch (error) {
expect(error).toBeDefined();
expect(error).toBeInstanceOf(Error);
expect((error as Error).message).toContain("Unknown network with genesis hash");
}
});
});

0 comments on commit 72fe206

Please sign in to comment.