-
Notifications
You must be signed in to change notification settings - Fork 0
/
gas_abstract_transfer.ts
142 lines (109 loc) · 4.16 KB
/
gas_abstract_transfer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { config as dotenvConfig } from "dotenv";
import { Client, Presets, UserOperationMiddlewareFn } from "userop";
import { Signer, ethers } from "ethers";
import { SimpleAccount } from "userop/dist/preset/builder";
import { EOASignature, getGasPrice, estimateUserOperationGas } from "userop/dist/preset/middleware";
import { TOKEN_ADDRESS, ENTRY_POINT_ADDRESS, SIMPLE_ACCOUNT_FACTORY_ADDRESS, ERC20_ABI, PAYMASTER_ADDRESS, stackupProvider, config, executeLitAction } from "./paymaster";
dotenvConfig();
const PRIVATE_KEY_1 = process.env.PRIVATE_KEY_1!;
const PRIVATE_KEY_2 = process.env.PRIVATE_KEY_2!;
const AMOUNT = ethers.utils.parseEther("5");
/**
* construct a wallet and send a simple transaction
*/
const provider = stackupProvider;
const testAccounts = [new ethers.Wallet(PRIVATE_KEY_1, provider), new ethers.Wallet(PRIVATE_KEY_2, provider)];
export const getSimpleAccount = (
signer: ethers.Signer,
provider: ethers.providers.JsonRpcProvider,
paymaster?: UserOperationMiddlewareFn,
) => {
return Presets.Builder.SimpleAccount.init(
signer,
provider.connection.url,
ENTRY_POINT_ADDRESS,
SIMPLE_ACCOUNT_FACTORY_ADDRESS,
paymaster,
);
};
const initSimpleAccount = async (signer: Signer) => {
// get simple wallet address
const account = await getSimpleAccount(signer, provider);
const address = account.getSender();
// PAUSE: log simple wallet address and send erc20 to it.
console.log("SimpleAccount address: " + address);
}
const gaslessTransfer = async (signer: Signer, recipient: Signer) => {
try {
const account = await getSimpleAccount(signer, provider);
const recipientAccount = await getSimpleAccount(recipient, provider);
// init client
const client = await Client.init(config.rpcUrl, config.entryPoint);
await transfer(client, account, recipientAccount.getSender(), AMOUNT);
} catch (err) {
console.log(err);
}
};
// initSimpleAccount(testAccounts[0]);
// initSimpleAccount(testAccounts[1]);
// transfer to
gaslessTransfer(testAccounts[0], testAccounts[1]);
// transfer back
// gaslessTransfer(testAccounts[1], testAccounts[0]);
/* HELPER FUNCTIONS */
const buildOps = async (simpleAccount: SimpleAccount, to: string, amount: ethers.BigNumber) => {
if (!simpleAccount) return;
const erc20 = new ethers.Contract(TOKEN_ADDRESS, ERC20_ABI, stackupProvider);
const data = erc20.interface.encodeFunctionData("transfer", [to, amount]);
const hasBeenDeployed = await hasWalletBeenDeployed(provider, simpleAccount.getSender());
if (hasBeenDeployed) {
simpleAccount.executeBatch([erc20.address], [data]);
} else {
// Execute transaction and approve Paymaster to spend tokens to pay gas fees in ECO tokens
simpleAccount.executeBatch(
[erc20.address, erc20.address],
[
erc20.interface.encodeFunctionData("approve", [PAYMASTER_ADDRESS, ethers.constants.MaxUint256]),
data
],
);
}
};
const transfer = async (
client: Client,
simpleAccount: SimpleAccount,
to: string,
amount: ethers.BigNumber
) => {
if (!client || !simpleAccount) return "";
await buildOps(simpleAccount, ethers.utils.getAddress(to), amount);
simpleAccount
.resetMiddleware()
.useMiddleware((simpleAccount as any).resolveAccount)
.useMiddleware(getGasPrice(stackupProvider))
.useMiddleware(executeLitAction)
const userOp = await client.buildUserOperation(simpleAccount)
console.log(userOp);
/*
simpleAccount
.useMiddleware(estimateUserOperationGas(stackupProvider))
.useMiddleware(executeLitAction)
.useMiddleware(EOASignature((simpleAccount as any).signer));
const res = await client.sendUserOperation(simpleAccount);
console.log("Waiting for transaction...");
const ev = await res.wait();
console.log(`Transaction hash: ${ev?.transactionHash ?? null}`);
*/
};
export async function hasWalletBeenDeployed(
provider: ethers.providers.JsonRpcProvider,
address: string,
): Promise<boolean> {
try {
const code = await provider.getCode(address);
return code !== "0x";
} catch (e) {
console.error("Error determining if SWA is already deployed", e);
}
return false;
}