From 228f1731a3c08acd4f067d31dbc9cdc05f867aaa Mon Sep 17 00:00:00 2001 From: Andrew Min Date: Thu, 7 Sep 2023 19:57:15 -0400 Subject: [PATCH] more ergonomic client input --- examples/deployer/src/index.ts | 10 +++--- examples/rebalancer/src/provider.ts | 10 +++--- examples/sweeper/src/provider.ts | 10 +++--- examples/trading-runner/src/provider.ts | 10 +++--- .../src/pages/index.tsx | 10 +++--- examples/with-ethers/src/index.ts | 10 +++--- examples/with-ethers/src/legacySepolia.ts | 10 +++--- examples/with-gnosis/src/index.ts | 30 ++++++++-------- .../src/managedOptimistic.ts | 10 +++--- .../src/simpleSequential.ts | 10 +++--- examples/with-uniswap/src/provider.ts | 10 +++--- packages/ethers/src/__tests__/index-test.ts | 25 ++++++++++--- packages/ethers/src/index.ts | 36 ++++++++++++------- 13 files changed, 109 insertions(+), 82 deletions(-) diff --git a/examples/deployer/src/index.ts b/examples/deployer/src/index.ts index 04f94a9ad..73f05b1d9 100644 --- a/examples/deployer/src/index.ts +++ b/examples/deployer/src/index.ts @@ -29,11 +29,11 @@ async function main() { ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); // Connect it with a Provider (https://docs.ethers.org/v5/api/providers/) const network = "goerli"; diff --git a/examples/rebalancer/src/provider.ts b/examples/rebalancer/src/provider.ts index 50c3cba4d..3c10e57e1 100644 --- a/examples/rebalancer/src/provider.ts +++ b/examples/rebalancer/src/provider.ts @@ -47,11 +47,11 @@ export function getTurnkeySigner( ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - privateKeyId - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId, + }); return turnkeySigner.connect(provider); } diff --git a/examples/sweeper/src/provider.ts b/examples/sweeper/src/provider.ts index 62528c305..7a37c38db 100644 --- a/examples/sweeper/src/provider.ts +++ b/examples/sweeper/src/provider.ts @@ -46,11 +46,11 @@ export function getTurnkeySigner( ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); return turnkeySigner.connect(provider); } diff --git a/examples/trading-runner/src/provider.ts b/examples/trading-runner/src/provider.ts index 50c3cba4d..3c10e57e1 100644 --- a/examples/trading-runner/src/provider.ts +++ b/examples/trading-runner/src/provider.ts @@ -47,11 +47,11 @@ export function getTurnkeySigner( ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - privateKeyId - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId, + }); return turnkeySigner.connect(provider); } diff --git a/examples/with-ethers-and-passkeys/src/pages/index.tsx b/examples/with-ethers-and-passkeys/src/pages/index.tsx index 51b82fade..30fbc54d7 100644 --- a/examples/with-ethers-and-passkeys/src/pages/index.tsx +++ b/examples/with-ethers-and-passkeys/src/pages/index.tsx @@ -105,11 +105,11 @@ export default function Home() { throw new Error("sub-org id or private key not found"); } - const ethersSigner = new TurnkeySigner( - passkeyHttpClient, - subOrgId, - privateKey.id - ); + const ethersSigner = new TurnkeySigner({ + client: passkeyHttpClient, + organizationId: subOrgId, + privateKeyId: privateKey.id, + }); const signedMessage = await ethersSigner.signMessage(data.messageToSign); diff --git a/examples/with-ethers/src/index.ts b/examples/with-ethers/src/index.ts index 21bdb8cd5..c2e04f440 100644 --- a/examples/with-ethers/src/index.ts +++ b/examples/with-ethers/src/index.ts @@ -31,11 +31,11 @@ async function main() { ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); // Bring your own provider (such as Alchemy or Infura: https://docs.ethers.org/v5/api/providers/) const network = "goerli"; diff --git a/examples/with-ethers/src/legacySepolia.ts b/examples/with-ethers/src/legacySepolia.ts index e4de620fb..0d03cee01 100644 --- a/examples/with-ethers/src/legacySepolia.ts +++ b/examples/with-ethers/src/legacySepolia.ts @@ -31,11 +31,11 @@ async function main() { ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); // Bring your own provider (such as Alchemy or Infura: https://docs.ethers.org/v5/api/providers/) const network = "sepolia"; diff --git a/examples/with-gnosis/src/index.ts b/examples/with-gnosis/src/index.ts index 80934f8b3..9f1fe2338 100644 --- a/examples/with-gnosis/src/index.ts +++ b/examples/with-gnosis/src/index.ts @@ -41,23 +41,23 @@ async function main() { ); // Initialize a Turnkey Signer - const turnkeySigner1 = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID_1! - ); + const turnkeySigner1 = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID_1!, + }); - const turnkeySigner2 = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID_2! - ); + const turnkeySigner2 = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID_2!, + }); - const turnkeySigner3 = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID_3! - ); + const turnkeySigner3 = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID_3!, + }); // Bring your own provider (for the sake of this demo, we recommend using Sepolia + Infura) const network = "sepolia"; diff --git a/examples/with-nonce-manager/src/managedOptimistic.ts b/examples/with-nonce-manager/src/managedOptimistic.ts index 191474d72..073ed3189 100644 --- a/examples/with-nonce-manager/src/managedOptimistic.ts +++ b/examples/with-nonce-manager/src/managedOptimistic.ts @@ -152,11 +152,11 @@ async function main() { ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); // Bring your own provider (such as Alchemy or Infura: https://docs.ethers.org/v5/api/providers/) const network = "goerli"; diff --git a/examples/with-nonce-manager/src/simpleSequential.ts b/examples/with-nonce-manager/src/simpleSequential.ts index 953b2406d..4c08497ce 100644 --- a/examples/with-nonce-manager/src/simpleSequential.ts +++ b/examples/with-nonce-manager/src/simpleSequential.ts @@ -29,11 +29,11 @@ async function main() { ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); // Bring your own provider (such as Alchemy or Infura: https://docs.ethers.org/v5/api/providers/) const network = "goerli"; diff --git a/examples/with-uniswap/src/provider.ts b/examples/with-uniswap/src/provider.ts index 91de5b0fd..6ffe78630 100644 --- a/examples/with-uniswap/src/provider.ts +++ b/examples/with-uniswap/src/provider.ts @@ -46,11 +46,11 @@ export function getTurnkeySigner( ); // Initialize a Turnkey Signer - const turnkeySigner = new TurnkeySigner( - turnkeyClient, - process.env.ORGANIZATION_ID!, - process.env.PRIVATE_KEY_ID! - ); + const turnkeySigner = new TurnkeySigner({ + client: turnkeyClient, + organizationId: process.env.ORGANIZATION_ID!, + privateKeyId: process.env.PRIVATE_KEY_ID!, + }); return turnkeySigner.connect(provider); } diff --git a/packages/ethers/src/__tests__/index-test.ts b/packages/ethers/src/__tests__/index-test.ts index b5c34de4e..fec6a5b9a 100644 --- a/packages/ethers/src/__tests__/index-test.ts +++ b/packages/ethers/src/__tests__/index-test.ts @@ -20,6 +20,7 @@ const testCase: typeof test = (...argList) => { describe("TurnkeySigner", () => { let connectedSigner: TurnkeySigner; + let signerWithProvider: TurnkeySigner; let chainId: number; let expectedEthAddress: string; let bannedToAddress: string; @@ -76,11 +77,20 @@ describe("TurnkeySigner", () => { }) ); - connectedSigner = new TurnkeySigner( - turnkeyClient, + connectedSigner = new TurnkeySigner({ + client: turnkeyClient, organizationId, - privateKeyId - ).connect(provider); + privateKeyId, + }).connect(provider); + + signerWithProvider = new TurnkeySigner( + { + client: turnkeyClient, + organizationId, + privateKeyId, + }, + provider + ); chainId = (await connectedSigner.provider!.getNetwork()).chainId; @@ -89,11 +99,16 @@ describe("TurnkeySigner", () => { setBalance(expectedEthAddress, ethers.utils.parseEther("999999")); }); - testCase("basics", async () => { + testCase("basics for connected signer", async () => { expect(ethers.Signer.isSigner(connectedSigner)).toBe(true); expect(await connectedSigner.getAddress()).toBe(expectedEthAddress); }); + testCase("basics for connected signer via constructor", async () => { + expect(ethers.Signer.isSigner(signerWithProvider)).toBe(true); + expect(await signerWithProvider.getAddress()).toBe(expectedEthAddress); + }); + testCase("it signs transactions", async () => { const tx = await connectedSigner.signTransaction({ to: "0x2Ad9eA1E677949a536A270CEC812D6e868C88108", diff --git a/packages/ethers/src/index.ts b/packages/ethers/src/index.ts index 977e11419..17962ca1c 100644 --- a/packages/ethers/src/index.ts +++ b/packages/ethers/src/index.ts @@ -9,32 +9,44 @@ import type { TypedDataField, } from "ethers"; +type TConfig = { + /** + * Turnkey client + */ + client: TurnkeyClient; + /** + * Turnkey organization ID + */ + organizationId: string; + /** + * Turnkey private key ID + */ + privateKeyId: string; +}; + export class TurnkeySigner extends ethers.Signer implements TypedDataSigner { private readonly client: TurnkeyClient; public readonly organizationId: string; public readonly privateKeyId: string; - constructor( - client: TurnkeyClient, - organizationId: string, - privateKeyId: string, - provider?: ethers.providers.Provider - ) { + constructor(config: TConfig, provider?: ethers.providers.Provider) { super(); ethers.utils.defineReadOnly(this, "provider", provider); - this.client = client; + this.client = config.client; - this.organizationId = organizationId; - this.privateKeyId = privateKeyId; + this.organizationId = config.organizationId; + this.privateKeyId = config.privateKeyId; } connect(provider: ethers.providers.Provider): TurnkeySigner { return new TurnkeySigner( - this.client, - this.organizationId, - this.privateKeyId, + { + client: this.client, + organizationId: this.organizationId, + privateKeyId: this.privateKeyId, + }, provider ); }