locklift
Version:
Node JS framework for working with Ever contracts. Inspired by Truffle and Hardhat. Helps you to build, test, run and maintain your smart contracts.
130 lines (121 loc) • 4.69 kB
text/typescript
import { ContractData, DeployContractParams, FactoryType, Giver } from "./index";
import { Address, Contract } from "everscale-inpage-provider";
import { CreateAccountOutput, DeployTransaction, WalletTypes } from "../../types";
import {
Account,
EverWalletAccount,
HighloadWalletV2,
MsigAccount,
SimpleAccountsStorage,
WalletV3Account,
} from "everscale-standalone-client/nodejs";
type MSigType = ConstructorParameters<typeof MsigAccount>[0]["type"];
type CreateAccountParams<T extends FactoryType> =
| {
type: WalletTypes.WalletV3 | WalletTypes.HighLoadWalletV2;
publicKey: string;
value: string;
}
| {
type: WalletTypes.EverWallet;
publicKey: string;
value: string;
nonce?: number;
}
| ({ type: WalletTypes.MsigAccount } & DeployContractParams<T, keyof T> & {
mSigType: MSigType;
});
type AddExistingAccountParams =
| { type: WalletTypes.HighLoadWalletV2 | WalletTypes.WalletV3; publicKey: string }
| ({ type: WalletTypes.EverWallet } & ({ address: Address } | { publicKey: string; nonce?: number }))
| { type: WalletTypes.MsigAccount; publicKey?: string; address: Address; mSigType: MSigType };
/*
AccountFactory2 is service based on everscale-standalone-client SimpleAccountsStorage
*/
export class AccountFactory2<T extends FactoryType> {
constructor(
private readonly sourceFactory: {
getContractArtifacts: <key extends keyof T>(name: key) => ContractData<T[key]>;
deployContract: <ContractName extends keyof T>(
args: DeployContractParams<T, ContractName>,
) => Promise<{ contract: Contract<T[ContractName]> } & DeployTransaction>;
},
private readonly sender: Giver["sendTo"],
private readonly accountsStorage: SimpleAccountsStorage,
) {}
/*
* Deploy and add the account to the account storage
*/
public addNewAccount = async (params: CreateAccountParams<T>): Promise<CreateAccountOutput> => {
const { account, tx } = await this.createAccount(params);
this.accountsStorage.addAccount(account);
return { account, tx };
};
private createAccount = async (params: CreateAccountParams<T>): Promise<CreateAccountOutput> => {
switch (params.type) {
case WalletTypes.WalletV3: {
const account = await WalletV3Account.fromPubkey({ publicKey: params.publicKey });
const depositTransaction = await this.sender(account.address, params.value);
return {
account,
tx: depositTransaction,
};
}
case WalletTypes.HighLoadWalletV2: {
const account = await HighloadWalletV2.fromPubkey({ publicKey: params.publicKey });
const depositTransaction = await this.sender(account.address, params.value);
return {
account,
tx: depositTransaction,
};
}
case WalletTypes.MsigAccount: {
const contractWithTx = await this.sourceFactory.deployContract(params);
const account = new MsigAccount({
publicKey: params.publicKey,
address: contractWithTx.contract.address,
type: params.mSigType,
});
return { tx: contractWithTx.tx, account };
}
case WalletTypes.EverWallet: {
const account = await EverWalletAccount.fromPubkey({ publicKey: params.publicKey, nonce: params.nonce });
const depositTransaction = await this.sender(account.address, params.value);
return {
account,
tx: depositTransaction,
};
}
}
};
/*
* Add an existing account to the account storage
*/
public addExistingAccount = async (params: AddExistingAccountParams): Promise<Account> => {
const account = await this.getExistingAccount(params);
this.accountsStorage.addAccount(account);
return account;
};
private getExistingAccount = async (params: AddExistingAccountParams): Promise<Account> => {
switch (params.type) {
case WalletTypes.HighLoadWalletV2:
return HighloadWalletV2.fromPubkey({ publicKey: params.publicKey });
case WalletTypes.WalletV3:
return WalletV3Account.fromPubkey({ publicKey: params.publicKey });
case WalletTypes.MsigAccount:
return new MsigAccount({ publicKey: params.publicKey, address: params.address, type: params.mSigType });
case WalletTypes.EverWallet: {
if ("publicKey" in params) {
return EverWalletAccount.fromPubkey({ publicKey: params.publicKey, nonce: params.nonce });
}
return new EverWalletAccount(params.address);
}
}
};
/*
Access to the account storage
*/
get storage(): SimpleAccountsStorage {
return this.accountsStorage;
}
}