Skip to content

Commit

Permalink
feat: privy wallet provider with example
Browse files Browse the repository at this point in the history
  • Loading branch information
azf20 committed Feb 11, 2025
1 parent 1207d04 commit 6d6eb39
Show file tree
Hide file tree
Showing 13 changed files with 3,049 additions and 6 deletions.
373 changes: 369 additions & 4 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"strict": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"moduleResolution": "node",
"moduleResolution": "node16",
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
Expand Down
1 change: 1 addition & 0 deletions typescript/agentkit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"dependencies": {
"@coinbase/coinbase-sdk": "^0.17.0",
"@solana/web3.js": "^1.98.0",
"@privy-io/server-auth": "^1.18.4",
"md5": "^2.3.0",
"reflect-metadata": "^0.2.2",
"twitter-api-v2": "^1.18.2",
Expand Down
1 change: 1 addition & 0 deletions typescript/agentkit/src/wallet-providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./viemWalletProvider";
export * from "./cdpWalletProvider";
export * from "./svmWalletProvider";
export * from "./solanaKeypairWalletProvider";
export * from "./privyWalletProvider";
96 changes: 96 additions & 0 deletions typescript/agentkit/src/wallet-providers/privyWalletProvider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { PrivyClient } from "@privy-io/server-auth";
import { createViemAccount } from "@privy-io/server-auth/viem";
import { ViemWalletProvider } from "./viemWalletProvider";
import { createWalletClient, http, WalletClient } from "viem";
import { NETWORK_ID_TO_VIEM_CHAIN } from "../network/network";

/**
* Configuration options for the Privy wallet provider.
*
* @interface
*/
interface PrivyWalletConfig {
/** The Privy application ID */
appId: string;
/** The Privy application secret */
appSecret: string;
/** The ID of the wallet to use */
walletId: string;
/** Optional network ID to connect to */
networkId?: string;
/** Optional authorization key for the wallet API */
authorizationKey?: string;
}

/**
* A wallet provider that uses Privy's server wallet API.
* This provider extends the ViemWalletProvider to provide Privy-specific wallet functionality
* while maintaining compatibility with the base wallet provider interface.
*/
export class PrivyWalletProvider extends ViemWalletProvider {
/**
* Private constructor to enforce use of factory method.
*
* @param walletClient - The Viem wallet client instance
*/
private constructor(walletClient: WalletClient) {
super(walletClient);
}

/**
* Creates and configures a new PrivyWalletProvider instance.
*
* @param config - The configuration options for the Privy wallet
* @returns A configured PrivyWalletProvider instance
*
* @example
* ```typescript
* const provider = await PrivyWalletProvider.configureWithWallet({
* appId: "your-app-id",
* appSecret: "your-app-secret",
* walletId: "wallet-id",
* networkId: "base-sepolia"
* });
* ```
*/
public static async configureWithWallet(config: PrivyWalletConfig): Promise<PrivyWalletProvider> {
const privy = new PrivyClient(config.appId, config.appSecret, {
walletApi: config.authorizationKey
? {
authorizationPrivateKey: config.authorizationKey,
}
: undefined,
});

// Get wallet details to get the address
const wallet = await privy.walletApi.getWallet({ id: config.walletId });

const account = await createViemAccount({
walletId: config.walletId,
address: wallet.address as `0x${string}`,
privy,
});

const network = {
protocolFamily: "evm" as const,
networkId: config.networkId || "base-sepolia",
};

const chain = NETWORK_ID_TO_VIEM_CHAIN[network.networkId!];
const walletClient = createWalletClient({
account,
chain,
transport: http(),
});
return new PrivyWalletProvider(walletClient);
}

/**
* Gets the name of the wallet provider.
*
* @returns The string identifier for this wallet provider
*/
getName(): string {
return "privy_wallet_provider";
}
}
3 changes: 2 additions & 1 deletion typescript/agentkit/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
"rootDir": "./src",
"module": "Node16"
},
"include": ["src/**/*.ts"],
"exclude": ["src/tests"]
Expand Down
9 changes: 9 additions & 0 deletions typescript/examples/langchain-privy-chatbot/.env-local
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
OPENAI_API_KEY=

# Privy Configuration - get these from your Privy dashboard
PRIVY_APP_ID=
PRIVY_APP_SECRET=
PRIVY_WALLET_ID=

# Optional Authorization Key, if you are using them for your server wallets
PRIVY_WALLET_AUTHORIZATION_KEY=
4 changes: 4 additions & 0 deletions typescript/examples/langchain-privy-chatbot/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"parser": "@typescript-eslint/parser",
"extends": ["../../../.eslintrc.base.json"]
}
48 changes: 48 additions & 0 deletions typescript/examples/langchain-privy-chatbot/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Privy AgentKit LangChain Extension Examples - Chatbot Typescript

This example demonstrates an agent setup as a self-aware terminal style chatbot with a [Privy server wallet](https://docs.privy.io/guide/server-wallets/).

## Ask the chatbot to engage in the Web3 ecosystem!

- "Transfer a portion of your ETH to a random address"
- "What is the price of BTC?"
- "What kind of wallet do you have?"

## Requirements

- Node.js 18+
- [CDP API Key](https://portal.cdp.coinbase.com/access/api)
- [OpenAI API Key](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key)

### Checking Node Version

Before using the example, ensure that you have the correct version of Node.js installed. The example requires Node.js 18 or higher. You can check your Node version by running:

```bash
node --version
npm --version
```

## Installation

```bash
npm install
```

## Run the Chatbot

### Set ENV Vars

- Ensure the following ENV Vars from your Privy dashboard are set in `.env`:
- PRIVY_APP_ID=
- PRIVY_APP_SECRET=
- PRIVY_WALLET_ID=
- PRIVY_WALLET_AUTHORIZATION_KEY=[optional, only if you are using authorization keys for your server wallets]

```bash
npm start
```

## License

Apache-2.0
Loading

0 comments on commit 6d6eb39

Please sign in to comment.