mirror of
https://github.com/getwax/ethdk.git
synced 2026-01-07 19:43:52 -05:00
Removing old code
This commit is contained in:
17
.vscode/launch.json
vendored
Normal file
17
.vscode/launch.json
vendored
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
9
.vscode/settings.json
vendored
Normal file
9
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"editor.rulers": [80],
|
||||
"editor.tabSize": 2,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true
|
||||
},
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
8
ethdk/.vscode/settings.json
vendored
Normal file
8
ethdk/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"editor.rulers": [80],
|
||||
"editor.tabSize": 2,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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<AccountAbstractionAccount> {
|
||||
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<ethers.providers.TransactionRequest>,
|
||||
): Promise<Transaction> {
|
||||
const response = await this.aaSigner.sendTransaction(transaction)
|
||||
return new AccountAbstractionTransaction({
|
||||
hash: response.hash,
|
||||
network: this.networkConfig,
|
||||
})
|
||||
}
|
||||
|
||||
static async generatePrivateKey(): Promise<string> {
|
||||
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<string> {
|
||||
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<ERC4337EthersProvider> {
|
||||
return await wrapProvider(
|
||||
provider,
|
||||
{
|
||||
entryPointAddress: networkConfig.entryPointAddress,
|
||||
bundlerUrl: networkConfig.bundlerUrl,
|
||||
},
|
||||
signer,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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')
|
||||
}
|
||||
@@ -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<ReceiptResponse | undefined> {
|
||||
const provider = new ethers.providers.JsonRpcProvider(this.network.rpcUrl)
|
||||
return await provider.getTransactionReceipt(this.hash)
|
||||
}
|
||||
}
|
||||
@@ -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<BlsAccount> {
|
||||
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<string> {
|
||||
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<ethers.providers.TransactionRequest>,
|
||||
): Promise<Transaction> {
|
||||
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<Transaction> {
|
||||
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<Transaction> {
|
||||
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<string> {
|
||||
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<Transaction> {
|
||||
const result = await agg.add(bundle)
|
||||
|
||||
if ('failures' in result) {
|
||||
throw new Error(JSON.stringify(result))
|
||||
}
|
||||
|
||||
return new BlsTransaction({ network, bundleHash: result.hash })
|
||||
}
|
||||
@@ -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')
|
||||
}
|
||||
@@ -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<ReceiptResponse | undefined> {
|
||||
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
|
||||
*/
|
||||
}
|
||||
@@ -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<T extends keyof AccountTypeMap> = 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<T extends keyof AccountTypeMap>({
|
||||
accountType,
|
||||
privateKey,
|
||||
network,
|
||||
}: AccountConfig & { accountType: T }): Promise<AccountTypeToReturnType<T>> {
|
||||
if (accountType === 'bls') {
|
||||
const account = await BlsAccount.createAccount({
|
||||
privateKey,
|
||||
network,
|
||||
})
|
||||
return account as AccountTypeToReturnType<T>
|
||||
}
|
||||
if (accountType === 'aa') {
|
||||
const account = await AccountAbstractionAccount.createAccount({
|
||||
privateKey,
|
||||
network,
|
||||
})
|
||||
return account as AccountTypeToReturnType<T>
|
||||
}
|
||||
if (accountType === 'eoa') {
|
||||
const account = ExternallyOwnedAccount.createAccount({
|
||||
privateKey,
|
||||
network,
|
||||
})
|
||||
return account as AccountTypeToReturnType<T>
|
||||
}
|
||||
throw new Error('Unsupported account type')
|
||||
}
|
||||
@@ -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<ethers.providers.TransactionRequest>,
|
||||
): Promise<Transaction> {
|
||||
const response = await this.signer.sendTransaction(transaction)
|
||||
return new ExternallyOwnedAccountTransaction({
|
||||
network: this.networkConfig,
|
||||
hash: response.hash,
|
||||
})
|
||||
}
|
||||
|
||||
async getBalance(): Promise<string> {
|
||||
const balance = await this.provider.getBalance(this.address)
|
||||
return ethers.utils.formatEther(balance)
|
||||
}
|
||||
}
|
||||
@@ -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')
|
||||
}
|
||||
@@ -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<ReceiptResponse> {
|
||||
const provider = new ethers.providers.JsonRpcProvider(this.network.rpcUrl)
|
||||
return await provider.getTransactionReceipt(this.hash)
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
0
ethdk/src/UserOp.ts
Normal file
0
ethdk/src/UserOp.ts
Normal file
@@ -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 {}
|
||||
|
||||
@@ -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<ethers.providers.TransactionRequest>,
|
||||
) => Promise<Transaction>
|
||||
}
|
||||
@@ -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'
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
export default interface SendTransactionParams {
|
||||
to: string
|
||||
from?: string
|
||||
gas?: string
|
||||
gasPrice?: string
|
||||
value?: string
|
||||
data?: string
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
export default interface Transaction {
|
||||
hash: string
|
||||
}
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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,
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
101
ethdk/yarn.lock
101
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"
|
||||
|
||||
14
node_modules/.yarn-integrity
generated
vendored
Normal file
14
node_modules/.yarn-integrity
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"systemParams": "darwin-arm64-108",
|
||||
"modulesFolders": [],
|
||||
"flags": [],
|
||||
"linkedModules": [
|
||||
"@account-abstraction/sdk",
|
||||
"bls-wallet-website",
|
||||
"ethdk"
|
||||
],
|
||||
"topLevelPatterns": [],
|
||||
"lockfileEntries": {},
|
||||
"files": [],
|
||||
"artifacts": {}
|
||||
}
|
||||
Reference in New Issue
Block a user