diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..ba79046 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Run Yarn Test", + "runtimeExecutable": "yarn", + "runtimeArgs": [ + "test" + ], + "cwd": "${workspaceFolder}/ethdk", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..555f47e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "editor.rulers": [80], + "editor.tabSize": 2, + "editor.codeActionsOnSave": { + "source.fixAll": true + }, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true +} diff --git a/ethdk/.vscode/settings.json b/ethdk/.vscode/settings.json new file mode 100644 index 0000000..de0b8d9 --- /dev/null +++ b/ethdk/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "editor.rulers": [80], + "editor.tabSize": 2, + "editor.codeActionsOnSave": { + "source.fixAll": true + } + } + \ No newline at end of file diff --git a/ethdk/package.json b/ethdk/package.json index bf3c1af..3c4626a 100644 --- a/ethdk/package.json +++ b/ethdk/package.json @@ -19,8 +19,6 @@ "docs": "typedoc && cp ../documentation-site/misc/_category_.json ../documentation-site/docs/sdk/" }, "dependencies": { - "@account-abstraction/sdk": "^0.5.0", - "bls-wallet-clients": "0.9.0", "ethers": "^5.7.2" }, "devDependencies": { diff --git a/ethdk/src/AccountAbstraction/AccountAbstractionAccount.ts b/ethdk/src/AccountAbstraction/AccountAbstractionAccount.ts deleted file mode 100644 index 313bd27..0000000 --- a/ethdk/src/AccountAbstraction/AccountAbstractionAccount.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { - wrapProvider, - type ERC4337EthersProvider, - type ERC4337EthersSigner, -} from '@account-abstraction/sdk' -import { ethers, Wallet } from 'ethers' - -import type Account from '../interfaces/Account' -import { type Deferrable } from 'ethers/lib/utils' -import type Transaction from '../interfaces/Transaction' -import { - type Network, - type AccountAbstractionNetwork, -} from '../interfaces/Network' -import { getNetwork } from './AccountAbstractionNetworks' -import AccountAbstractionTransaction from './AccountAbstractionTransaction' -import isNullOrUndefined from '../utils/isNullOrUndefined' - -export default class AccountAbstractionAccount implements Account { - accountType: string = 'aa' - - address: string - private readonly privateKey: string - private readonly networkConfig: AccountAbstractionNetwork - private readonly aaProvider: ERC4337EthersProvider - private readonly aaSigner: ERC4337EthersSigner - - private constructor({ - address, - privateKey, - network, - provider, - signer, - }: { - address: string - privateKey: string - network: AccountAbstractionNetwork - provider: ERC4337EthersProvider - signer: ERC4337EthersSigner - }) { - this.address = address - this.privateKey = privateKey - this.networkConfig = network - this.aaProvider = provider - this.aaSigner = signer - } - - static async createAccount({ - privateKey, - network, - }: { - privateKey?: string - network?: Network - } = {}): Promise { - const networkConfig = getNetwork(network) - - const provider = new ethers.providers.JsonRpcProvider( - networkConfig.rpcUrl, - { - name: networkConfig.name, - chainId: networkConfig.chainId, - }, - ) - const signer = isNullOrUndefined(privateKey) - ? Wallet.createRandom() - : new Wallet(privateKey, provider) - - const aaProvider = await this.getAaProvider(provider, signer, networkConfig) - - return new AccountAbstractionAccount({ - address: await aaProvider.getSigner().getAddress(), - privateKey: privateKey ?? signer.privateKey, - network: networkConfig, - provider: aaProvider, - signer: aaProvider.getSigner(), - }) - } - - async sendTransaction( - transaction: Deferrable, - ): Promise { - const response = await this.aaSigner.sendTransaction(transaction) - return new AccountAbstractionTransaction({ - hash: response.hash, - network: this.networkConfig, - }) - } - - static async generatePrivateKey(): Promise { - return Wallet.createRandom().privateKey - } - - /** - * Get the balance of this account - * @returns The balance of this account formated in ether (instead of wei) - */ - async getBalance(): Promise { - const balance = await this.aaProvider.getBalance(this.address) - return ethers.utils.formatEther(balance) - } - - // Creating a helper function to get the provider - // so we can mock the provider for testing - static async getAaProvider( - provider: ethers.providers.JsonRpcProvider, - signer: ethers.Signer, - networkConfig: AccountAbstractionNetwork, - ): Promise { - return await wrapProvider( - provider, - { - entryPointAddress: networkConfig.entryPointAddress, - bundlerUrl: networkConfig.bundlerUrl, - }, - signer, - ) - } -} diff --git a/ethdk/src/AccountAbstraction/AccountAbstractionNetworks.ts b/ethdk/src/AccountAbstraction/AccountAbstractionNetworks.ts deleted file mode 100644 index 7eef24b..0000000 --- a/ethdk/src/AccountAbstraction/AccountAbstractionNetworks.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - type Network, - type AccountAbstractionNetwork, -} from '../interfaces/Network' -import isNullOrUndefined from '../utils/isNullOrUndefined' - -export const localhost: AccountAbstractionNetwork = { - type: 'aa', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - bundlerUrl: 'http://localhost:3000/rpc', - entryPointAddress: '0x0576a174d229e3cfa37253523e645a78a0c91b57', -} - -export function getNetwork(network?: Network): AccountAbstractionNetwork { - if (isNullOrUndefined(network)) { - // Return default network - return localhost - } - - if (network.type === 'aa') { - return network as AccountAbstractionNetwork - } - throw new Error('Unsupported network') -} diff --git a/ethdk/src/AccountAbstraction/AccountAbstractionTransaction.ts b/ethdk/src/AccountAbstraction/AccountAbstractionTransaction.ts deleted file mode 100644 index 83716fc..0000000 --- a/ethdk/src/AccountAbstraction/AccountAbstractionTransaction.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ethers } from 'ethers' -import type Transaction from '../interfaces/Transaction' -import { - type AccountAbstractionNetwork, - type Network, -} from '../interfaces/Network' -import { getNetwork } from './AccountAbstractionNetworks' - -type ReceiptResponse = ethers.providers.TransactionReceipt - -export default class AccountAbstractionTransaction implements Transaction { - hash: string - network: AccountAbstractionNetwork - - constructor({ hash, network }: { hash: string; network: Network }) { - this.network = getNetwork(network) - this.hash = hash - } - - async getTransactionReceipt(): Promise { - const provider = new ethers.providers.JsonRpcProvider(this.network.rpcUrl) - return await provider.getTransactionReceipt(this.hash) - } -} diff --git a/ethdk/src/Bls/BlsAccount.ts b/ethdk/src/Bls/BlsAccount.ts deleted file mode 100644 index 32386c2..0000000 --- a/ethdk/src/Bls/BlsAccount.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { - BlsProvider, - BlsSigner, - BlsWalletWrapper, - Aggregator, - VerificationGatewayFactory, - type Bundle, -} from 'bls-wallet-clients' -import { ethers } from 'ethers' -import { type Deferrable } from 'ethers/lib/utils' -import BlsTransaction from './BlsTransaction' -import type Transaction from '../interfaces/Transaction' -import type Account from '../interfaces/Account' -import { type BlsNetwork, type Network } from '../interfaces/Network' -import { getNetwork } from './BlsNetworks' - -export default class BlsAccount implements Account { - accountType: string = 'bls' - - address: string - private readonly privateKey: string - private readonly networkConfig: BlsNetwork - private readonly blsProvider: BlsProvider - private readonly blsSigner: BlsSigner - - private constructor({ - address, - privateKey, - network, - provider, - signer, - }: { - address: string - privateKey: string - network: BlsNetwork - provider: BlsProvider - signer: BlsSigner - }) { - this.address = address - this.privateKey = privateKey - this.networkConfig = network - this.blsProvider = provider - this.blsSigner = signer - } - - static async createAccount({ - privateKey: pk, - network, - }: { - privateKey?: string - network?: Network - } = {}): Promise { - const privateKey = pk ?? (await BlsSigner.getRandomBlsPrivateKey()) - const networkConfig = getNetwork(network) - - const provider = new BlsProvider( - networkConfig.aggregatorUrl, - networkConfig.verificationGateway, - networkConfig.aggregatorUtilities, - networkConfig.rpcUrl, - { - name: networkConfig.name, - chainId: networkConfig.chainId, - }, - ) - const signer = provider.getSigner(privateKey) - - return new BlsAccount({ - privateKey, - network: networkConfig, - address: await signer.getAddress(), - provider, - signer, - }) - } - - static async generatePrivateKey(): Promise { - return await BlsWalletWrapper.getRandomBlsPrivateKey() - } - - /** - * Sends a transaction to the aggregator to be bundled and submitted to the L2 - * @param params Array of transactions - * @returns Transaction hash of the transaction that was sent to the aggregator - */ - async sendTransaction( - transaction: Deferrable, - ): Promise { - const response = await this.blsSigner.sendTransaction(transaction) - return new BlsTransaction({ - network: this.networkConfig, - bundleHash: response.hash, - }) - } - - /** - * Sets the trusted account for this account. The trusted account will be able to reset this accounts private key - * by calling the recoverWallet function using this accounts address and the recovery phrase. - * @param recoveryPhrase String that is used as salt to generate the recovery hash - * @param trustedAccountAddress Address of the account that will be able to reset this accounts private key - * @returns Transaction hash of the transaction that was sent to the aggregator - */ - async setTrustedAccount( - recoveryPhrase: string, - trustedAccountAddress: string, - ): Promise { - const wallet = await BlsWalletWrapper.connect( - this.privateKey, - this.networkConfig.verificationGateway, - this.blsProvider, - ) - const bundle = await wallet.getSetRecoveryHashBundle( - recoveryPhrase, - trustedAccountAddress, - ) - - return await addBundleToAggregator( - this.getAggregator(), - bundle, - this.networkConfig, - ) - } - - /** - * Recovers a compromised BLS wallet by assigning it a new private key. This function - * must be called from the trusted account that was previously set by the compromised wallet. - * - * @param compromisedAccountAddress The address of the compromised BLS wallet. - * @param recoveryPhrase The recovery phrase associated with the compromised wallet. - * @param newPrivateKey The new private key to be assigned to the compromised wallet. - * @returns Transaction hash of the transaction that was sent to the aggregator - */ - async resetAccountPrivateKey( - compromisedAccountAddress: string, - recoveryPhrase: string, - newPrivateKey: string, - ): Promise { - const wallet = await BlsWalletWrapper.connect( - this.privateKey, - this.networkConfig.verificationGateway, - this.blsProvider, - ) - const verificationGateway = VerificationGatewayFactory.connect( - this.networkConfig.verificationGateway, - this.blsProvider, - ) - const latestBlock = await this.blsProvider.getBlock('latest') - const signatureExpiryOffsetSeconds = 20 * 60 // 20 minutes - const safetyDelaySeconds = 7 * 24 * 60 * 60 // one week - - const signatureExpiryTimestamp = - latestBlock.timestamp + safetyDelaySeconds + signatureExpiryOffsetSeconds - - const bundle = await wallet.getRecoverWalletBundle( - compromisedAccountAddress, - newPrivateKey, - recoveryPhrase, - verificationGateway, - signatureExpiryTimestamp, - ) - - return await addBundleToAggregator( - this.getAggregator(), - bundle, - this.networkConfig, - ) - } - - /** - * Get the balance of this account - * @returns The balance of this account formated in ether (instead of wei) - */ - async getBalance(): Promise { - const balance = await this.blsProvider.getBalance(this.address) - return ethers.utils.formatEther(balance) - } - - private getAggregator(): Aggregator { - return new Aggregator(this.networkConfig.aggregatorUrl) - } -} - -async function addBundleToAggregator( - agg: Aggregator, - bundle: Bundle, - network: BlsNetwork, -): Promise { - const result = await agg.add(bundle) - - if ('failures' in result) { - throw new Error(JSON.stringify(result)) - } - - return new BlsTransaction({ network, bundleHash: result.hash }) -} diff --git a/ethdk/src/Bls/BlsNetworks.ts b/ethdk/src/Bls/BlsNetworks.ts deleted file mode 100644 index 103fe5b..0000000 --- a/ethdk/src/Bls/BlsNetworks.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { type Network, type BlsNetwork } from '../interfaces/Network' -import isNullOrUndefined from '../utils/isNullOrUndefined' - -export const optimismGoerli: BlsNetwork = { - type: 'bls', - name: 'Optimism Goerli', - chainId: 420, - rpcUrl: 'https://goerli.optimism.io', - aggregatorUrl: 'https://optimism-goerli.blswallet.org/', - aggregatorUtilities: '0x4bD2E4e99B50A2a9e6b9dABfA3C8dCD1f885F008', - verificationGateway: '0xE25229F29BAD62B1198F05F32169B70a9edc84b8', -} - -export const arbitrumGoerli: BlsNetwork = { - type: 'bls', - name: 'Arbitrum Goerli', - chainId: 421613, - rpcUrl: 'https://goerli-rollup.arbitrum.io/rpc', - aggregatorUrl: 'https://arbitrum-goerli.blswallet.org/', - aggregatorUtilities: '0x4bD2E4e99B50A2a9e6b9dABfA3C8dCD1f885F008', - verificationGateway: '0xE25229F29BAD62B1198F05F32169B70a9edc84b8', -} - -export function getNetwork(network?: Network): BlsNetwork { - if (isNullOrUndefined(network)) { - // Return default network - return arbitrumGoerli - } - - if (network.type === 'bls') { - return network as BlsNetwork - } - throw new Error('Unsupported network') -} diff --git a/ethdk/src/Bls/BlsTransaction.ts b/ethdk/src/Bls/BlsTransaction.ts deleted file mode 100644 index 2aff5c7..0000000 --- a/ethdk/src/Bls/BlsTransaction.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Aggregator } from 'bls-wallet-clients' -import { - type BundleReceipt, - type BundleReceiptError, -} from 'bls-wallet-clients/dist/src/Aggregator' -import type Transaction from '../interfaces/Transaction' -import { type BlsNetwork, type Network } from '../interfaces/Network' -import { getNetwork } from './BlsNetworks' - -type ReceiptResponse = BundleReceipt | BundleReceiptError - -export default class BlsTransaction implements Transaction { - hash: string - network: BlsNetwork - - constructor({ - bundleHash, - network, - }: { - bundleHash: string - network: Network - }) { - this.network = getNetwork(network) - this.hash = bundleHash - } - - async getTransactionReceipt(): Promise { - const aggregator = this.getAggregator() - return await aggregator.lookupReceipt(this.hash) - } - - private getAggregator(): Aggregator { - return new Aggregator(this.network.aggregatorUrl) - } - - /** - * TODO (ethdk #11) Add in the BLS provider for better transaction functionality - * eg: polling for transaction receipt - */ -} diff --git a/ethdk/src/Ethdk.ts b/ethdk/src/Ethdk.ts deleted file mode 100644 index 8457b37..0000000 --- a/ethdk/src/Ethdk.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { type Network } from './interfaces/Network' -import BlsAccount from './Bls/BlsAccount' -import AccountAbstractionAccount from './AccountAbstraction/AccountAbstractionAccount' -import ExternallyOwnedAccount from './ExternallyOwnedAccount/ExternallyOwnedAccount' - -interface AccountConfig { - accountType: 'bls' | 'eoa' | 'aa' - privateKey?: string - network?: Network -} - -interface AccountTypeMap { - bls: BlsAccount - aa: AccountAbstractionAccount - eoa: ExternallyOwnedAccount - // Add more types as needed -} - -type AccountTypeToReturnType = AccountTypeMap[T] - -/** - * Creates an account of the specified type - * @param accountType The type of account to create ('bls', 'eoa', etc.) - * @param privateKey Optional private key to use for the account - * @returns An account of the specified type - */ -export async function createAccount({ - accountType, - privateKey, - network, -}: AccountConfig & { accountType: T }): Promise> { - if (accountType === 'bls') { - const account = await BlsAccount.createAccount({ - privateKey, - network, - }) - return account as AccountTypeToReturnType - } - if (accountType === 'aa') { - const account = await AccountAbstractionAccount.createAccount({ - privateKey, - network, - }) - return account as AccountTypeToReturnType - } - if (accountType === 'eoa') { - const account = ExternallyOwnedAccount.createAccount({ - privateKey, - network, - }) - return account as AccountTypeToReturnType - } - throw new Error('Unsupported account type') -} diff --git a/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccount.ts b/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccount.ts deleted file mode 100644 index 258d3b9..0000000 --- a/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccount.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { ethers, Wallet } from 'ethers' -import { type Deferrable } from 'ethers/lib/utils' -import type Account from '../interfaces/Account' -import { - type ExternallyOwnedAccountNetwork, - type Network, -} from '../interfaces/Network' -import type Transaction from '../interfaces/Transaction' -import { getNetwork } from './ExternallyOwnedAccountNetworks' -import ExternallyOwnedAccountTransaction from './ExternallyOwnedAccountTransaction' -import isNullOrUndefined from '../utils/isNullOrUndefined' -import validatePrivateKey from '../utils/validatePrivateKey' -import validateSeedPhrase from '../utils/validateSeedPhrase' - -export default class ExternallyOwnedAccount implements Account { - accountType: string = 'eoa' - - address: string - private readonly privateKey: string - private readonly seedPhrase: string - private readonly networkConfig: ExternallyOwnedAccountNetwork - private readonly provider: ethers.providers.JsonRpcProvider - private readonly signer: Wallet - - private constructor({ - address, - privateKey, - seedPhrase, - network, - provider, - signer, - }: { - address: string - privateKey: string - seedPhrase: string - network: ExternallyOwnedAccountNetwork - provider: ethers.providers.JsonRpcProvider - signer: Wallet - }) { - this.address = address - this.privateKey = privateKey - this.seedPhrase = seedPhrase - this.networkConfig = network - this.provider = provider - this.signer = signer - } - - static createAccount({ - privateKey, - network, - }: { - privateKey?: string - network?: Network - } = {}): ExternallyOwnedAccount { - if (isNullOrUndefined(privateKey)) { - return this.createAccountFromPrivateKey({ - privateKey: Wallet.createRandom().privateKey, - }) - } - - return this.createAccountFromPrivateKey({ - privateKey, - network, - }) - } - - static createAccountFromPrivateKey({ - privateKey, - network, - }: { - privateKey: string - network?: Network - }): ExternallyOwnedAccount { - const validatedPrivateKey = validatePrivateKey(privateKey) - if (validatedPrivateKey.success === false) { - throw new Error(`Invalid private key: ${validatedPrivateKey.error}`) - } - - const signer = Wallet.createRandom(privateKey) - - const networkConfig = getNetwork(network) - - const provider = new ethers.providers.JsonRpcProvider( - networkConfig.rpcUrl, - { - name: networkConfig.name, - chainId: networkConfig.chainId, - }, - ) - - return new ExternallyOwnedAccount({ - address: signer.address, - privateKey: signer.privateKey, - seedPhrase: signer.mnemonic.phrase, - network: networkConfig, - provider, - signer, - }) - } - - static createAccountFromSeedPhrase({ - seedPhrase, - network, - }: { - seedPhrase: string - network?: Network - }): ExternallyOwnedAccount { - const validatedSeedPhrase = validateSeedPhrase(seedPhrase) - if (validatedSeedPhrase.success === false) { - throw new Error(`Invalid seed phrase: ${validatedSeedPhrase.error}`) - } - - const signer = Wallet.fromMnemonic(seedPhrase) - - const networkConfig = getNetwork(network) - - const provider = new ethers.providers.JsonRpcProvider( - networkConfig.rpcUrl, - { - name: networkConfig.name, - chainId: networkConfig.chainId, - }, - ) - - return new ExternallyOwnedAccount({ - address: signer.address, - privateKey: signer.privateKey, - seedPhrase: signer.mnemonic.phrase, - network: networkConfig, - provider, - signer, - }) - } - - static generatePrivateKey(): string { - return Wallet.createRandom().privateKey - } - - async sendTransaction( - transaction: Deferrable, - ): Promise { - const response = await this.signer.sendTransaction(transaction) - return new ExternallyOwnedAccountTransaction({ - network: this.networkConfig, - hash: response.hash, - }) - } - - async getBalance(): Promise { - const balance = await this.provider.getBalance(this.address) - return ethers.utils.formatEther(balance) - } -} diff --git a/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks.ts b/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks.ts deleted file mode 100644 index 9c11520..0000000 --- a/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { - type Network, - type ExternallyOwnedAccountNetwork, -} from '../interfaces/Network' -import isNullOrUndefined from '../utils/isNullOrUndefined' - -export const localhost: ExternallyOwnedAccountNetwork = { - type: 'eoa', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', -} - -const defaultNetwork = localhost - -export function getNetwork(network?: Network): ExternallyOwnedAccountNetwork { - if (isNullOrUndefined(network)) { - return defaultNetwork - } - - if (network.type === 'eoa') { - return network as ExternallyOwnedAccountNetwork - } - throw new Error('Unsupported network') -} diff --git a/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction.ts b/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction.ts deleted file mode 100644 index 9730092..0000000 --- a/ethdk/src/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ethers } from 'ethers' -import { - type ExternallyOwnedAccountNetwork, - type Network, -} from '../interfaces/Network' -import type Transaction from '../interfaces/Transaction' -import { getNetwork } from './ExternallyOwnedAccountNetworks' - -type ReceiptResponse = ethers.providers.TransactionReceipt - -export default class ExternallyOwnedAccountTransaction implements Transaction { - hash: string - network: ExternallyOwnedAccountNetwork - - constructor({ hash, network }: { hash: string; network: Network }) { - this.network = getNetwork(network) - this.hash = hash - } - - async getTransactionReceipt(): Promise { - const provider = new ethers.providers.JsonRpcProvider(this.network.rpcUrl) - return await provider.getTransactionReceipt(this.hash) - } -} diff --git a/ethdk/src/Networks/index.ts b/ethdk/src/Networks/index.ts deleted file mode 100644 index 4eff742..0000000 --- a/ethdk/src/Networks/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { optimismGoerli, arbitrumGoerli } from '../Bls/BlsNetworks' -import { localhost as eoaLocalhost } from '../ExternallyOwnedAccount/ExternallyOwnedAccountNetworks' -import { localhost as aaLocalhost } from '../AccountAbstraction/AccountAbstractionNetworks' - -export const BLS_NETWORKS = { - optimismGoerli, - arbitrumGoerli, -} - -export const EOA_NETWORKS = { - localhost: eoaLocalhost, -} - -export const AA_NETWORKS = { - localhost: aaLocalhost, -} diff --git a/ethdk/src/UserOp.ts b/ethdk/src/UserOp.ts new file mode 100644 index 0000000..e69de29 diff --git a/ethdk/src/index.ts b/ethdk/src/index.ts index 4950a4b..336ce12 100644 --- a/ethdk/src/index.ts +++ b/ethdk/src/index.ts @@ -1,19 +1 @@ -import { createAccount } from './Ethdk' -import BlsAccount from './Bls/BlsAccount' -import BlsTransaction from './Bls/BlsTransaction' -import AccountAbstractionAccount from './AccountAbstraction/AccountAbstractionAccount' -import AccountAbstractionTransaction from './AccountAbstraction/AccountAbstractionTransaction' -import ExternallyOwnedAccount from './ExternallyOwnedAccount/ExternallyOwnedAccount' -import ExternallyOwnedAccountTransaction from './ExternallyOwnedAccount/ExternallyOwnedAccountTransaction' -import * as networks from './Networks' - -export { - createAccount, - BlsAccount, - BlsTransaction, - networks, - AccountAbstractionAccount, - AccountAbstractionTransaction, - ExternallyOwnedAccount, - ExternallyOwnedAccountTransaction, -} +export {} diff --git a/ethdk/src/interfaces/Account.ts b/ethdk/src/interfaces/Account.ts deleted file mode 100644 index 4201880..0000000 --- a/ethdk/src/interfaces/Account.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { type Deferrable } from 'ethers/lib/utils' -import { type ethers } from 'ethers' -import type Transaction from './Transaction' - -export default interface Account { - accountType: string - address: string - sendTransaction: ( - transaction: Deferrable, - ) => Promise -} diff --git a/ethdk/src/interfaces/Network.ts b/ethdk/src/interfaces/Network.ts deleted file mode 100644 index 68e3921..0000000 --- a/ethdk/src/interfaces/Network.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface Network { - type: string - name: string - chainId: number - rpcUrl: string -} - -export interface BlsNetwork extends Network { - type: 'bls' - aggregatorUrl: string - verificationGateway: string - aggregatorUtilities: string -} - -export interface AccountAbstractionNetwork extends Network { - type: 'aa' - entryPointAddress: string - bundlerUrl: string -} - -export interface ExternallyOwnedAccountNetwork extends Network { - type: 'eoa' -} diff --git a/ethdk/src/interfaces/SendTransactionParams.ts b/ethdk/src/interfaces/SendTransactionParams.ts deleted file mode 100644 index e13a846..0000000 --- a/ethdk/src/interfaces/SendTransactionParams.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default interface SendTransactionParams { - to: string - from?: string - gas?: string - gasPrice?: string - value?: string - data?: string -} diff --git a/ethdk/src/interfaces/Transaction.ts b/ethdk/src/interfaces/Transaction.ts deleted file mode 100644 index 75d88a7..0000000 --- a/ethdk/src/interfaces/Transaction.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default interface Transaction { - hash: string -} diff --git a/ethdk/test/AccountAbstraction/AccountAbstractionAccount.test.ts b/ethdk/test/AccountAbstraction/AccountAbstractionAccount.test.ts deleted file mode 100644 index c2d110c..0000000 --- a/ethdk/test/AccountAbstraction/AccountAbstractionAccount.test.ts +++ /dev/null @@ -1,159 +0,0 @@ -import { expect } from 'chai' -import { describe, it, afterEach } from 'mocha' -import sinon from 'sinon' - -import { ethers, Wallet } from 'ethers' -import AccountAbstractionAccount from '../../src/AccountAbstraction/AccountAbstractionAccount' -import { localhost } from '../../src/AccountAbstraction/AccountAbstractionNetworks' -import AccountAbstractionTransaction from '../../src/AccountAbstraction/AccountAbstractionTransaction' -import * as networkModule from '../../src/AccountAbstraction/AccountAbstractionNetworks' - -describe('AccountAbstractionAccount', () => { - afterEach(() => { - sinon.restore() - }) - - describe('createAccount', () => { - it('should create an account with a given private key', async () => { - // Arrange - const privateKey = - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' - const smartContractAddress = '0xabcd6Ef563a5c06d6755849c3e27116fcCa4B33f' - sinon.createStubInstance(Wallet) - const mockAaProvider = { - getSigner: sinon.stub().returns({ - getAddress: sinon.stub().resolves(smartContractAddress), - }), - } - sinon - .stub(AccountAbstractionAccount, 'getAaProvider') - .resolves(mockAaProvider as any) - const getNetworkSpy = sinon.spy(networkModule, 'getNetwork') - - // Act - const accountConfig = { - privateKey, - network: localhost, - } - const account = await AccountAbstractionAccount.createAccount( - accountConfig, - ) - - // Assert - expect(account).to.be.instanceOf(AccountAbstractionAccount) - expect(account.address).to.equal(smartContractAddress) - expect(getNetworkSpy.calledOnceWith(localhost)).to.equal(true) - }) - - it('should create an account with a generated private key', async () => { - // Arrange - const privateKey = - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' - const smartContractAddress = '0x12346Ef563a5c06d6755849c3e27116fcCa4B33f' - sinon.createStubInstance(Wallet) - const mockAaProvider = { - getSigner: sinon.stub().returns({ - getAddress: sinon.stub().resolves(smartContractAddress), - }), - } - sinon - .stub(AccountAbstractionAccount, 'getAaProvider') - .resolves(mockAaProvider as any) - - const walletStub = sinon - .stub(Wallet, 'createRandom') - .returns(new Wallet(privateKey)) - - // Act - const account = await AccountAbstractionAccount.createAccount() - - // Assert - expect(account).to.be.instanceOf(AccountAbstractionAccount) - expect(account.address).to.equal(smartContractAddress) - expect(walletStub.calledOnce).to.equal(true) - }) - }) - - describe('generatePrivateKey', () => { - it('should return a generated private key', async () => { - // Arrange - const privateKey = - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' - - sinon.stub(Wallet, 'createRandom').returns(new Wallet(privateKey)) - - // Act - const result = await AccountAbstractionAccount.generatePrivateKey() - - // Assert - expect(result).to.equal(privateKey) - }) - }) - - it('should send a transaction successfully', async () => { - // Arrange - const mockTransactionResponse = { hash: '0x67890' } - const smartContractAddress = '0x12346Ef563a5c06d6755849c3e27116fcCa4B33f' - sinon.createStubInstance(Wallet) - const mockAaProvider = { - getSigner: sinon.stub().returns({ - getAddress: sinon.stub().resolves(smartContractAddress), - sendTransaction: sinon.stub().resolves(mockTransactionResponse), - }), - } - sinon - .stub(AccountAbstractionAccount, 'getAaProvider') - .resolves(mockAaProvider as any) - - const accountConfig = { - privateKey: - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', - network: localhost, - } - const account = await AccountAbstractionAccount.createAccount(accountConfig) - - // Act - const transactionParams = { - to: '0x12345', - value: '0', - data: '0x', - } - const transaction = await account.sendTransaction(transactionParams) - - // Assert - expect(transaction).to.be.instanceOf(AccountAbstractionTransaction) - expect(transaction.hash).to.equal(mockTransactionResponse.hash) - }) - - describe('getBalance', () => { - it('should get the balance of an account successfully', async () => { - // Arrange - const balance = ethers.utils.parseEther('1.23') - const smartContractAddress = '0x12346Ef563a5c06d6755849c3e27116fcCa4B33f' - sinon.createStubInstance(Wallet) - const mockAaProvider = { - getSigner: sinon.stub().returns({ - getAddress: sinon.stub().resolves(smartContractAddress), - }), - getBalance: sinon.stub().resolves(balance), - } - sinon - .stub(AccountAbstractionAccount, 'getAaProvider') - .resolves(mockAaProvider as any) - const accountConfig = { - privateKey: - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80', - network: localhost, - } - const account = await AccountAbstractionAccount.createAccount( - accountConfig, - ) - - // Act - const result = await account.getBalance() - - // Assert - expect(result).to.equal('1.23') - }) - }) -}) diff --git a/ethdk/test/AccountAbstraction/AccountAbstractionNetwork.test.ts b/ethdk/test/AccountAbstraction/AccountAbstractionNetwork.test.ts deleted file mode 100644 index 517ebf7..0000000 --- a/ethdk/test/AccountAbstraction/AccountAbstractionNetwork.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { expect } from 'chai' -import sinon from 'sinon' -import { AA_NETWORKS } from '../../src/Networks' -import { getNetwork } from '../../src/AccountAbstraction/AccountAbstractionNetworks' - -describe('getNetwork', () => { - afterEach(() => { - sinon.restore() - }) - - it('should return the default network when network is undefined', () => { - // Arrange - const expectedNetwork = AA_NETWORKS.localhost - - // Act - const resultNetwork = getNetwork(undefined) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should return the default network when network is null', () => { - // Arrange - const expectedNetwork = AA_NETWORKS.localhost - - // Act - const resultNetwork = getNetwork(null as any) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should return the AccountAbstractionNework when network type is aa', () => { - // Arrange - const expectedNetwork = { - type: 'aa', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - bundlerUrl: 'http://localhost:3000/rpc', - entryPointAddress: '0x0576a174d229e3cfa37253523e645a78a0c91b57', - } - - // Act - const resultNetwork = getNetwork(AA_NETWORKS.localhost) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should throw an error when network type is not aa', () => { - // Arrange - const network = { - type: 'unsupported', - name: 'testnet', - chainId: 1234, - rpcUrl: 'http://localhost:1234', - } - - // Act & Assert - expect(() => getNetwork(network)).to.throw('Unsupported network') - }) -}) diff --git a/ethdk/test/AccountAbstraction/AccountAbstractionTransaction.test.ts b/ethdk/test/AccountAbstraction/AccountAbstractionTransaction.test.ts deleted file mode 100644 index cab33b6..0000000 --- a/ethdk/test/AccountAbstraction/AccountAbstractionTransaction.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { expect } from 'chai' -import { ethers } from 'ethers' -import sinon from 'sinon' -import AccountAbstractionTransaction from '../../src/AccountAbstraction/AccountAbstractionTransaction' -import { AA_NETWORKS } from '../../src/Networks' - -describe('AccountAbstractionTransaction', () => { - afterEach(() => { - sinon.restore() - }) - - describe('getTransactionReceipt', () => { - it('should return the transaction receipt', async () => { - // Arrange - const hash = 'testHash' - const mockReceipt: any = { - hash, - } - - const getTransactionReceiptStub = sinon.stub( - ethers.providers.JsonRpcProvider.prototype, - 'getTransactionReceipt', - ) - - getTransactionReceiptStub.resolves(mockReceipt) - - const transaction = new AccountAbstractionTransaction({ - network: AA_NETWORKS.localhost, - hash, - }) - - // Act - const receipt = await transaction.getTransactionReceipt() - - // Assert - expect(receipt).to.deep.equal(mockReceipt) - expect(getTransactionReceiptStub.calledOnceWith(hash)).to.equal(true) - }) - }) -}) diff --git a/ethdk/test/Bls/BlsAccount.test.ts b/ethdk/test/Bls/BlsAccount.test.ts deleted file mode 100644 index e544119..0000000 --- a/ethdk/test/Bls/BlsAccount.test.ts +++ /dev/null @@ -1,228 +0,0 @@ -import { expect } from 'chai' -import { describe, it, afterEach } from 'mocha' -import BlsAccount from '../../src/Bls/BlsAccount' -import BlsTransaction from '../../src/Bls/BlsTransaction' -import sinon from 'sinon' - -import { ethers } from 'ethers' -import { - BlsWalletWrapper, - Aggregator, - BlsProvider, - BlsSigner, -} from 'bls-wallet-clients' - -const network = { - type: 'bls', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - aggregatorUrl: 'http://localhost:3000', - aggregatorUtilities: '0x76cE3c1F2E6d87c355560fCbd28ccAcAe03f95F6', - verificationGateway: '0x689A095B4507Bfa302eef8551F90fB322B3451c6', -} - -describe('BlsAccount', () => { - afterEach(() => { - sinon.restore() - }) - - describe('createAccount', () => { - it('should create an account with a given private key', async () => { - // Arrange - const privateKey = '0x123' - const mockAddress = '0x12345' - - sinon.stub(BlsSigner.prototype, 'getAddress').resolves(mockAddress) - - // Act - const accountConfig = { - privateKey, - network, - } - const account = await BlsAccount.createAccount(accountConfig) - - // Assert - expect(account).to.be.instanceOf(BlsAccount) - expect(account.address).to.equal(mockAddress) - }) - - it('should create an account with a generated private key', async () => { - // Arrange - const privateKey = '0x123' - const mockAddress = '0x12345' - - sinon.stub(BlsSigner.prototype, 'getAddress').resolves(mockAddress) - sinon - .stub(BlsWalletWrapper, 'getRandomBlsPrivateKey') - .resolves(privateKey) - - // Act - const account = await BlsAccount.createAccount() - - // Assert - expect(account).to.be.instanceOf(BlsAccount) - expect(account.address).to.equal(mockAddress) - }) - }) - - describe('generatePrivateKey', () => { - it('should return a generated private key', async () => { - // Arrange - const privateKey = '0x123' - - sinon - .stub(BlsWalletWrapper, 'getRandomBlsPrivateKey') - .resolves(privateKey) - - // Act - const result = await BlsAccount.generatePrivateKey() - - // Assert - expect(result).to.equal(privateKey) - }) - }) - - it('should send a transaction successfully', async () => { - // Arrange - const mockTransactionResponse = { hash: '0x67890' } - const mockAddress = '0x12345' - sinon - .stub(BlsSigner.prototype, 'sendTransaction') - .resolves(mockTransactionResponse as any) - - sinon.stub(BlsSigner.prototype, 'getAddress').resolves(mockAddress) - - const accountConfig = { - privateKey: '0x123', - network, - } - const account = await BlsAccount.createAccount(accountConfig) - - // Act - const transactionParams = { - to: '0x12345', - value: '0', - data: '0x', - } - const transaction = await account.sendTransaction(transactionParams) - - // Assert - expect(transaction).to.be.instanceOf(BlsTransaction) - expect(transaction.hash).to.equal(mockTransactionResponse.hash) - }) - - describe('setTrustedAccount', () => { - it('should set a trusted account successfully', async () => { - // Arrange - const mockBundle = { some: 'bundle' } - const mockGetSetRecoveryHashBundle = sinon.stub().resolves(mockBundle) - const mockWallet: any = { - getSetRecoveryHashBundle: mockGetSetRecoveryHashBundle, - } - sinon.stub(BlsWalletWrapper, 'connect').resolves(mockWallet) - - const mockResult = { hash: '0x67890' } - const mockAggregator = sinon.createStubInstance(Aggregator) - mockAggregator.add.resolves(mockResult) - - sinon - .stub(BlsAccount.prototype, 'getAggregator' as any) - .returns(mockAggregator) - const accountConfig = { - privateKey: '0x123', - network, - } - const account = await BlsAccount.createAccount(accountConfig) - - // Act - const recoveryPhrase = 'some phrase' - const trustedAccountAddress = '0x12345' - const transaction = await account.setTrustedAccount( - recoveryPhrase, - trustedAccountAddress, - ) - - // Assert - expect(transaction).to.be.instanceOf(BlsTransaction) - expect(transaction.hash).to.equal(mockResult.hash) - expect( - mockGetSetRecoveryHashBundle.calledWith( - recoveryPhrase, - trustedAccountAddress, - ), - ).to.equal(true) - }) - }) - - describe.skip('resetAccountPrivateKey', () => { - it('should reset the account private key successfully', async () => { - // Arrange - const mockBundle = { some: 'bundle' } - const mockGetRecoverWalletBundle = sinon.stub().resolves(mockBundle) - const mockWallet: any = { - address: '0x12345', - getRecoverWalletBundle: mockGetRecoverWalletBundle, - } - sinon.stub(BlsWalletWrapper, 'connect').resolves(mockWallet) - - const mockResult = { hash: '0x67890' } - const mockAggregator = sinon.createStubInstance(Aggregator) - mockAggregator.add.resolves(mockResult) - - sinon - .stub(BlsAccount.prototype, 'getAggregator' as any) - .returns(mockAggregator) - - const accountConfig = { - privateKey: '0x123', - network, - } - const account = await BlsAccount.createAccount(accountConfig) - - // Act - const compromisedAccountAddress = '0x98765' - const recoveryPhrase = 'some_recovery_phrase' - const newPrivateKey = '0x456' - const transaction = await account.resetAccountPrivateKey( - compromisedAccountAddress, - recoveryPhrase, - newPrivateKey, - ) - - // Assert - expect(transaction).to.be.instanceOf(BlsTransaction) - expect(transaction.hash).to.equal(mockResult.hash) - expect( - mockGetRecoverWalletBundle.calledWith( - compromisedAccountAddress, - newPrivateKey, - recoveryPhrase, - ), - ).to.equal(true) - }) - }) - - describe('getBalance', () => { - it('should get the balance of an account successfully', async () => { - // Arrange - const balance = ethers.utils.parseEther('1.23') - const mockAddress = '0x12345' - - sinon.stub(BlsProvider.prototype, 'getBalance').resolves(balance) - - sinon.stub(BlsSigner.prototype, 'getAddress').resolves(mockAddress) - const accountConfig = { - privateKey: '0x123', - network, - } - const account = await BlsAccount.createAccount(accountConfig) - - // Act - const result = await account.getBalance() - - // Assert - expect(result).to.equal('1.23') - }) - }) -}) diff --git a/ethdk/test/Bls/BlsNetworks.test.ts b/ethdk/test/Bls/BlsNetworks.test.ts deleted file mode 100644 index 6202cbc..0000000 --- a/ethdk/test/Bls/BlsNetworks.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { expect } from 'chai' -import sinon from 'sinon' -import { BLS_NETWORKS } from '../../src/Networks' -import { getNetwork } from '../../src/Bls/BlsNetworks' - -const network = { - type: 'bls', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - aggregatorUrl: 'http://localhost:3000', - aggregatorUtilities: '0x76cE3c1F2E6d87c355560fCbd28ccAcAe03f95F6', - verificationGateway: '0x689A095B4507Bfa302eef8551F90fB322B3451c6', -} - -describe('getNetwork', () => { - afterEach(() => { - sinon.restore() - }) - - it('should return the default network when network is undefined', () => { - // Arrange - const expectedNetwork = BLS_NETWORKS.arbitrumGoerli - - // Act - const resultNetwork = getNetwork(undefined) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should return the default network when network is null', () => { - // Arrange - const expectedNetwork = BLS_NETWORKS.arbitrumGoerli - - // Act - const resultNetwork = getNetwork(null as any) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should return the BlsNetwork when network type is bls', () => { - // Arrange - const expectedNetwork = { - type: 'bls', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - aggregatorUrl: 'http://localhost:3000', - aggregatorUtilities: '0x76cE3c1F2E6d87c355560fCbd28ccAcAe03f95F6', - verificationGateway: '0x689A095B4507Bfa302eef8551F90fB322B3451c6', - } - - // Act - const resultNetwork = getNetwork(network) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should throw an error when network type is not bls', () => { - // Arrange - const network = { - type: 'unsupported', - name: 'testnet', - chainId: 1234, - rpcUrl: 'http://localhost:1234', - } - - // Act & Assert - expect(() => getNetwork(network)).to.throw('Unsupported network') - }) -}) diff --git a/ethdk/test/Bls/BlsTransaction.test.ts b/ethdk/test/Bls/BlsTransaction.test.ts deleted file mode 100644 index 7ff838a..0000000 --- a/ethdk/test/Bls/BlsTransaction.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { expect } from 'chai' -import sinon from 'sinon' -import { Aggregator } from 'bls-wallet-clients' -import BlsTransaction from '../../src/Bls/BlsTransaction' - -const network = { - type: 'bls', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - aggregatorUrl: 'http://localhost:3000', - aggregatorUtilities: '0x76cE3c1F2E6d87c355560fCbd28ccAcAe03f95F6', - verificationGateway: '0x689A095B4507Bfa302eef8551F90fB322B3451c6', -} - -describe('BlsTransaction', () => { - afterEach(() => { - sinon.restore() - }) - - describe('getTransactionReceipt', () => { - it('should return the transaction receipt', async () => { - // Arrange - const bundleHash = 'testBundleHash' - const mockReceipt: any = { - bundleHash, - } - - const mockAggregator = sinon.createStubInstance(Aggregator) - mockAggregator.lookupReceipt.resolves(mockReceipt) - - // Stub the getAggregator function to return the mockAggregator - sinon - .stub(BlsTransaction.prototype, 'getAggregator' as any) - .returns(mockAggregator as any) - - const transaction = new BlsTransaction({ - network, - bundleHash, - }) - - // Act - const receipt = await transaction.getTransactionReceipt() - - // Assert - expect(receipt).to.deep.equal(mockReceipt) - expect(mockAggregator.lookupReceipt.calledOnceWith(bundleHash)).to.equal( - true, - ) - }) - }) -}) diff --git a/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccount.test.ts b/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccount.test.ts deleted file mode 100644 index c45169a..0000000 --- a/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccount.test.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { expect } from 'chai' -import { ethers, Wallet } from 'ethers' -import { describe, it, afterEach } from 'mocha' -import sinon from 'sinon' -import ExternallyOwnedAccount from '../../src/ExternallyOwnedAccount/ExternallyOwnedAccount' -import ExternallyOwnedAccountTransaction from '../../src/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction' -import { EOA_NETWORKS } from '../../src/Networks' -import * as networkModule from '../../src/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks' - -describe('ExternallyOwnedAccount', () => { - afterEach(() => { - sinon.restore() - }) - - describe('createAccount', () => { - it('should create an account with a given private key', () => { - // Arrange - const privateKey = - '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' - const expectedWallet = Wallet.createRandom(privateKey) - - const walletStub = sinon - .stub(Wallet, 'createRandom') - .returns(expectedWallet) - - const getNetworkSpy = sinon.spy(networkModule, 'getNetwork') - - const accountConfig = { - privateKey, - network: EOA_NETWORKS.localhost, - } - - // Act - const account = ExternallyOwnedAccount.createAccount(accountConfig) - - // Assert - expect(account).to.be.instanceOf(ExternallyOwnedAccount) - expect(account.address).to.equal(expectedWallet.address) - expect(walletStub.calledOnceWith(privateKey)).to.equal(true) - expect(getNetworkSpy.calledOnceWith(EOA_NETWORKS.localhost)).to.equal( - true, - ) - }) - - it('should create an account with a generated private key', () => { - // Arrange - const expectedWallet = Wallet.createRandom() - - const walletStub = sinon - .stub(Wallet, 'createRandom') - .returns(expectedWallet) - - const getNetworkSpy = sinon.spy(networkModule, 'getNetwork') - - // Act - const account = ExternallyOwnedAccount.createAccount() - - // Assert - expect(account).to.be.instanceOf(ExternallyOwnedAccount) - expect(account.address).to.equal(expectedWallet.address) - expect(walletStub.calledTwice).to.equal(true) - expect(walletStub.calledWithExactly(/* nothing */)).to.equal(true) - expect(walletStub.calledWithExactly(expectedWallet.privateKey)).to.equal( - true, - ) - expect(getNetworkSpy.calledOnceWith(undefined)).to.equal(true) - }) - - it('should create an account with a seed phrase and no network', () => { - // Arrange - const seedPhrase = - 'test test test test test test test test test test test junk' - const expectedWallet = Wallet.fromMnemonic(seedPhrase) - - const walletStub = sinon - .stub(Wallet, 'fromMnemonic') - .returns(expectedWallet) - - const getNetworkSpy = sinon.spy(networkModule, 'getNetwork') - - // Act - const account = ExternallyOwnedAccount.createAccountFromSeedPhrase({ - seedPhrase, - }) - - // Assert - expect(account).to.be.instanceOf(ExternallyOwnedAccount) - expect(account.address).to.equal(expectedWallet.address) - expect(walletStub.calledOnceWithExactly(seedPhrase)).to.equal(true) - expect(getNetworkSpy.calledOnceWith(undefined)).to.equal(true) - }) - - it('should create an account with a seed phrase and network', () => { - // Arrange - const seedPhrase = - 'test test test test test test test test test test test junk' - const expectedWallet = Wallet.fromMnemonic(seedPhrase) - - const walletStub = sinon - .stub(Wallet, 'fromMnemonic') - .returns(expectedWallet) - - const getNetworkSpy = sinon.spy(networkModule, 'getNetwork') - - // Act - const account = ExternallyOwnedAccount.createAccountFromSeedPhrase({ - seedPhrase, - network: EOA_NETWORKS.localhost, - }) - - // Assert - expect(account).to.be.instanceOf(ExternallyOwnedAccount) - expect(account.address).to.equal(expectedWallet.address) - expect(walletStub.calledOnceWithExactly(seedPhrase)).to.equal(true) - expect(getNetworkSpy.calledOnceWith(EOA_NETWORKS.localhost)).to.equal( - true, - ) - }) - }) - - describe('generatePrivateKey', () => { - it('should return a generated private key', () => { - // Arrange - const expectedWallet = Wallet.createRandom() - sinon.stub(Wallet, 'createRandom').returns(expectedWallet) - - // Act - const result = ExternallyOwnedAccount.generatePrivateKey() - - // Assert - expect(result).to.equal(expectedWallet.privateKey) - }) - }) - - describe('sendTransaction', () => { - it('should send a transaction successfully', async () => { - // Arrange - const mockTransactionResponse = { hash: '0x67890' } - sinon - .stub(Wallet.prototype, 'sendTransaction') - .resolves(mockTransactionResponse as any) - const transactionParams = { - to: '0x12345', - value: '1', - data: '0x', - } - - const account = ExternallyOwnedAccount.createAccount() - - // Act - const transaction = await account.sendTransaction(transactionParams) - - // Assert - expect(transaction).to.be.instanceOf(ExternallyOwnedAccountTransaction) - expect(transaction.hash).to.equal(mockTransactionResponse.hash) - }) - }) - - describe('getBalance', () => { - it('should get the balance of an account successfully', async () => { - // Arrange - const balance = ethers.utils.parseEther('1.23') - const getBalanceStub = sinon.stub( - ethers.providers.JsonRpcProvider.prototype, - 'getBalance', - ) - getBalanceStub.resolves(balance) - - const account = ExternallyOwnedAccount.createAccount() - - // Act - const result = await account.getBalance() - - // Assert - expect(result).to.equal('1.23') - }) - }) -}) diff --git a/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks.test.ts b/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks.test.ts deleted file mode 100644 index c4ab2d9..0000000 --- a/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { expect } from 'chai' -import sinon from 'sinon' -import { EOA_NETWORKS } from '../../src/Networks' -import { getNetwork } from '../../src/ExternallyOwnedAccount/ExternallyOwnedAccountNetworks' - -describe('getNetwork', () => { - afterEach(() => { - sinon.restore() - }) - - it('should return the default network when network is undefined', () => { - // Arrange - const expectedNetwork = EOA_NETWORKS.localhost - - // Act - const resultNetwork = getNetwork(undefined) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should return the default network when network is null', () => { - // Arrange - const expectedNetwork = EOA_NETWORKS.localhost - - // Act - const resultNetwork = getNetwork(null as any) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should return the ExternallyOwnedAccountNetwork when network type is eoa', () => { - // Arrange - const expectedNetwork = { - type: 'eoa', - name: 'localhost', - chainId: 1337, - rpcUrl: 'http://localhost:8545', - } - - // Act - const resultNetwork = getNetwork(EOA_NETWORKS.localhost) - - // Assert - expect(resultNetwork).to.deep.equal(expectedNetwork) - }) - - it('should throw an error when network type is not eoa', () => { - // Arrange - const network = { - type: 'unsupported', - name: 'testnet', - chainId: 1234, - rpcUrl: 'http://localhost:1234', - } - - // Act & Assert - expect(() => getNetwork(network)).to.throw('Unsupported network') - }) -}) diff --git a/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction.test.ts b/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction.test.ts deleted file mode 100644 index f601658..0000000 --- a/ethdk/test/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { expect } from 'chai' -import { ethers } from 'ethers' -import sinon from 'sinon' -import ExternallyOwnedAccountTransaction from '../../src/ExternallyOwnedAccount/ExternallyOwnedAccountTransaction' -import { EOA_NETWORKS } from '../../src/Networks' - -describe('ExternallyOwnedAccountTransaction', () => { - afterEach(() => { - sinon.restore() - }) - - describe('getTransactionReceipt', () => { - it('should return the transaction receipt', async () => { - // Arrange - const hash = 'testHash' - const mockReceipt: any = { - hash, - } - - const getTransactionReceiptStub = sinon.stub( - ethers.providers.JsonRpcProvider.prototype, - 'getTransactionReceipt', - ) - - getTransactionReceiptStub.resolves(mockReceipt) - - const transaction = new ExternallyOwnedAccountTransaction({ - network: EOA_NETWORKS.localhost, - hash, - }) - - // Act - const receipt = await transaction.getTransactionReceipt() - - // Assert - expect(receipt).to.deep.equal(mockReceipt) - expect(getTransactionReceiptStub.calledOnceWith(hash)).to.equal(true) - }) - }) -}) diff --git a/ethdk/yarn.lock b/ethdk/yarn.lock index 065d646..708f0e3 100644 --- a/ethdk/yarn.lock +++ b/ethdk/yarn.lock @@ -2,39 +2,6 @@ # yarn lockfile v1 -"@account-abstraction/contracts@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@account-abstraction/contracts/-/contracts-0.5.0.tgz#a089aee7b4c446251fbbce7df315bbf8f659e37f" - integrity sha512-CKyS9Zh5rcYUM+4B6TlaB9+THHzJ+6TY3tWF5QofqvFpqGNvIhF8ddy6wyCmqZw6TB74/yYv7cYD/RarVudfDg== - -"@account-abstraction/sdk@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@account-abstraction/sdk/-/sdk-0.5.0.tgz#fb306ecb1dba82e10a0277ab716890acf1d2d1ed" - integrity sha512-KuEG9UVl2kEhamevFmPJfqY5AQH4fRLnFhfWAdoqwxIZIuSyA8wfyzM9WKnDPSCaiApLvSzckjRwbs4dVoOp2Q== - dependencies: - "@account-abstraction/contracts" "^0.5.0" - "@account-abstraction/utils" "^0.5.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/providers" "^5.7.0" - "@types/debug" "^4.1.7" - debug "^4.3.4" - ethers "^5.7.0" - -"@account-abstraction/utils@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@account-abstraction/utils/-/utils-0.5.0.tgz#aa7925741048b1657a71d7f98ccaf3c187f99b4a" - integrity sha512-dgXguTn5WgFMmr3wQMdLGEoIMDcIJgzAv74YlHeb2D3Nyy1pByPArSb3eLOOcgxCJSJeqTscpO9P57uhNkkC4A== - dependencies: - "@account-abstraction/contracts" "^0.5.0" - "@ethersproject/abi" "^5.7.0" - "@ethersproject/providers" "^5.7.0" - "@openzeppelin/contracts" "^4.7.3" - debug "^4.3.4" - ethers "^5.7.0" - "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -265,7 +232,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.0": +"@ethersproject/providers@5.7.2": version "5.7.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== @@ -474,11 +441,6 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@openzeppelin/contracts@^4.7.3": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.2.tgz#d815ade0027b50beb9bcca67143c6bcc3e3923d6" - integrity sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g== - "@sinonjs/commons@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" @@ -514,14 +476,6 @@ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== -"@thehubbleproject/bls@^0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@thehubbleproject/bls/-/bls-0.5.1.tgz#6b0565f56fc9c8896dcf3c8f0e2214b69a06167f" - integrity sha512-g5zeMZ8js/yg6MjFoC+pt0eqfCL2jC46yLY1LbKNriyqftB1tE3jpG/FMMDIW3x9/yRg/AgUb8Nluqj15tQs+A== - dependencies: - ethers "^5.5.3" - mcl-wasm "^1.0.0" - "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -554,13 +508,6 @@ resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== -"@types/debug@^4.1.7": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -576,11 +523,6 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== -"@types/ms@*": - version "0.7.31" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - "@types/semver@^7.3.12": version "7.3.13" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" @@ -821,15 +763,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bls-wallet-clients@0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/bls-wallet-clients/-/bls-wallet-clients-0.9.0.tgz#edfbdb24011856b52d9b438af174b6acbeda27ec" - integrity sha512-ebEifAPkGfTft6xdVVgQfC6HEXzgw+wX2d76w2K1OUsB4FeKiAYRLMXtnKtl7tdQoMknHElD6xrLChKaCACYLQ== - dependencies: - "@thehubbleproject/bls" "^0.5.1" - ethers "^5.7.2" - node-fetch "2.6.7" - bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" @@ -1376,7 +1309,7 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -ethers@^5.5.3, ethers@^5.7.0, ethers@^5.7.2: +ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -2007,11 +1940,6 @@ marked@^4.3.0: resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== -mcl-wasm@^1.0.0: - version "1.0.6" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-1.0.6.tgz#834420a38aa7c7eab789d08b2834f75fb375f6eb" - integrity sha512-/KYSug255SQoOcrQBxkHeAub9qOcJD3B/n5livcsGKsbv4TOiefNmUAwpMP0Vea5AVBUApolr+iF0GqZixns1w== - merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" @@ -2129,13 +2057,6 @@ nise@^5.1.4: just-extend "^4.0.2" path-to-regexp "^1.7.0" -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -2528,11 +2449,6 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -2659,19 +2575,6 @@ vscode-textmate@^8.0.0: resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" diff --git a/node_modules/.yarn-integrity b/node_modules/.yarn-integrity new file mode 100644 index 0000000..63956c9 --- /dev/null +++ b/node_modules/.yarn-integrity @@ -0,0 +1,14 @@ +{ + "systemParams": "darwin-arm64-108", + "modulesFolders": [], + "flags": [], + "linkedModules": [ + "@account-abstraction/sdk", + "bls-wallet-website", + "ethdk" + ], + "topLevelPatterns": [], + "lockfileEntries": {}, + "files": [], + "artifacts": {} +} \ No newline at end of file