near-safe 0.0.5 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -1
- package/dist/cjs/lib/safe.js +17 -2
- package/dist/cjs/tx-manager.d.ts +11 -7
- package/dist/cjs/tx-manager.js +24 -15
- package/dist/esm/lib/safe.js +17 -2
- package/dist/esm/tx-manager.d.ts +11 -7
- package/dist/esm/tx-manager.js +27 -17
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/cjs/lib/safe.js
CHANGED
@@ -19,7 +19,15 @@ class ContractSuite {
|
|
19
19
|
}
|
20
20
|
static async init(provider) {
|
21
21
|
const safeDeployment = (fn) => getDeployment(fn, { provider, version: "1.4.1" });
|
22
|
-
const m4337Deployment = (fn) =>
|
22
|
+
const m4337Deployment = async (fn) => {
|
23
|
+
try {
|
24
|
+
return await getDeployment(fn, { provider, version: "0.3.0" });
|
25
|
+
}
|
26
|
+
catch (error) {
|
27
|
+
console.warn(error.message, "using v0.2.0");
|
28
|
+
return getDeployment(fn, { provider, version: "0.2.0" });
|
29
|
+
}
|
30
|
+
};
|
23
31
|
// Need this first to get entryPoint address
|
24
32
|
const m4337 = await m4337Deployment(safe_modules_deployments_1.getSafe4337ModuleDeployment);
|
25
33
|
const [singleton, proxyFactory, moduleSetup, supportedEntryPoint] = await Promise.all([
|
@@ -29,6 +37,13 @@ class ContractSuite {
|
|
29
37
|
m4337.SUPPORTED_ENTRYPOINT(),
|
30
38
|
]);
|
31
39
|
const entryPoint = new ethers_1.ethers.Contract(supportedEntryPoint, ["function getNonce(address, uint192 key) view returns (uint256 nonce)"], provider);
|
40
|
+
console.log("Initialized ERC4337 & Safe Module Contracts:", {
|
41
|
+
singleton: await singleton.getAddress(),
|
42
|
+
proxyFactory: await proxyFactory.getAddress(),
|
43
|
+
m4337: await m4337.getAddress(),
|
44
|
+
moduleSetup: await moduleSetup.getAddress(),
|
45
|
+
entryPoint: await entryPoint.getAddress(),
|
46
|
+
});
|
32
47
|
return new ContractSuite(provider, singleton, proxyFactory, m4337, moduleSetup, entryPoint);
|
33
48
|
}
|
34
49
|
async addressForSetup(setup, saltNonce) {
|
@@ -102,7 +117,7 @@ async function getDeployment(fn, { provider, version }) {
|
|
102
117
|
const { chainId } = await provider.getNetwork();
|
103
118
|
const deployment = fn({ version });
|
104
119
|
if (!deployment || !deployment.networkAddresses[`${chainId}`]) {
|
105
|
-
throw new Error(`Deployment not found for version ${version}
|
120
|
+
throw new Error(`Deployment not found for ${fn.name} version ${version} on chainId ${chainId}`);
|
106
121
|
}
|
107
122
|
return new ethers_1.ethers.Contract(deployment.networkAddresses[`${chainId}`], deployment.abi, provider);
|
108
123
|
}
|
package/dist/cjs/tx-manager.d.ts
CHANGED
@@ -4,26 +4,30 @@ import { Erc4337Bundler } from "./lib/bundler";
|
|
4
4
|
import { UserOperation, UserOperationReceipt } from "./types";
|
5
5
|
import { MetaTransaction } from "ethers-multisend";
|
6
6
|
import { ContractSuite } from "./lib/safe";
|
7
|
-
import { Account } from "near-api-js";
|
8
7
|
export declare class TransactionManager {
|
9
8
|
readonly provider: ethers.JsonRpcProvider;
|
10
9
|
readonly nearAdapter: NearEthAdapter;
|
11
10
|
private safePack;
|
12
11
|
private bundler;
|
13
12
|
private setup;
|
14
|
-
readonly
|
13
|
+
readonly address: string;
|
14
|
+
readonly chainId: number;
|
15
15
|
private safeSaltNonce;
|
16
16
|
private _safeNotDeployed;
|
17
|
-
constructor(provider: ethers.JsonRpcProvider, nearAdapter: NearEthAdapter, safePack: ContractSuite, bundler: Erc4337Bundler, setup: string, safeAddress: string, safeSaltNonce: string, safeNotDeployed: boolean);
|
17
|
+
constructor(provider: ethers.JsonRpcProvider, nearAdapter: NearEthAdapter, safePack: ContractSuite, bundler: Erc4337Bundler, setup: string, chainId: number, safeAddress: string, safeSaltNonce: string, safeNotDeployed: boolean);
|
18
18
|
static create(config: {
|
19
19
|
ethRpc: string;
|
20
|
-
|
21
|
-
|
22
|
-
mpcContractId: string;
|
20
|
+
pimlicoKey: string;
|
21
|
+
nearAdapter: NearEthAdapter;
|
23
22
|
safeSaltNonce?: string;
|
24
23
|
}): Promise<TransactionManager>;
|
24
|
+
static fromChainId(args: {
|
25
|
+
chainId: number;
|
26
|
+
nearAdapter: NearEthAdapter;
|
27
|
+
pimlicoKey: string;
|
28
|
+
}): Promise<TransactionManager>;
|
25
29
|
get safeNotDeployed(): boolean;
|
26
|
-
get
|
30
|
+
get mpcAddress(): `0x${string}`;
|
27
31
|
getSafeBalance(): Promise<bigint>;
|
28
32
|
buildTransaction(args: {
|
29
33
|
transactions: MetaTransaction[];
|
package/dist/cjs/tx-manager.js
CHANGED
@@ -9,40 +9,46 @@ const near_1 = require("./lib/near");
|
|
9
9
|
const ethers_multisend_1 = require("ethers-multisend");
|
10
10
|
const safe_1 = require("./lib/safe");
|
11
11
|
class TransactionManager {
|
12
|
-
constructor(provider, nearAdapter, safePack, bundler, setup, safeAddress, safeSaltNonce, safeNotDeployed) {
|
12
|
+
constructor(provider, nearAdapter, safePack, bundler, setup, chainId, safeAddress, safeSaltNonce, safeNotDeployed) {
|
13
13
|
this.provider = provider;
|
14
14
|
this.nearAdapter = nearAdapter;
|
15
15
|
this.safePack = safePack;
|
16
16
|
this.bundler = bundler;
|
17
17
|
this.setup = setup;
|
18
|
-
this.
|
18
|
+
this.chainId = chainId;
|
19
|
+
this.address = safeAddress;
|
19
20
|
this.safeSaltNonce = safeSaltNonce;
|
20
21
|
this._safeNotDeployed = safeNotDeployed;
|
21
22
|
}
|
22
23
|
static async create(config) {
|
24
|
+
const { nearAdapter, pimlicoKey } = config;
|
23
25
|
const provider = new ethers_1.ethers.JsonRpcProvider(config.ethRpc);
|
24
|
-
const
|
25
|
-
|
26
|
-
mpcContract: new near_ca_1.MpcContract(config.nearAccount, config.mpcContractId),
|
27
|
-
}),
|
28
|
-
safe_1.ContractSuite.init(provider),
|
29
|
-
]);
|
26
|
+
const chainId = (await provider.getNetwork()).chainId;
|
27
|
+
const safePack = await safe_1.ContractSuite.init(provider);
|
30
28
|
console.log(`Near Adapter: ${nearAdapter.nearAccountId()} <> ${nearAdapter.address}`);
|
31
|
-
const bundler = new bundler_1.Erc4337Bundler(
|
29
|
+
const bundler = new bundler_1.Erc4337Bundler(`https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoKey}`, await safePack.entryPoint.getAddress());
|
32
30
|
const setup = await safePack.getSetup([nearAdapter.address]);
|
33
31
|
const safeAddress = await safePack.addressForSetup(setup, config.safeSaltNonce);
|
34
32
|
const safeNotDeployed = (await provider.getCode(safeAddress)) === "0x";
|
35
33
|
console.log(`Safe Address: ${safeAddress} - deployed? ${!safeNotDeployed}`);
|
36
|
-
return new TransactionManager(provider, nearAdapter, safePack, bundler, setup, safeAddress, config.safeSaltNonce || "0", safeNotDeployed);
|
34
|
+
return new TransactionManager(provider, nearAdapter, safePack, bundler, setup, parseInt(chainId.toString()), safeAddress, config.safeSaltNonce || "0", safeNotDeployed);
|
35
|
+
}
|
36
|
+
static async fromChainId(args) {
|
37
|
+
const { pimlicoKey, nearAdapter } = args;
|
38
|
+
return TransactionManager.create({
|
39
|
+
ethRpc: near_ca_1.Network.fromChainId(args.chainId).rpcUrl,
|
40
|
+
pimlicoKey,
|
41
|
+
nearAdapter,
|
42
|
+
});
|
37
43
|
}
|
38
44
|
get safeNotDeployed() {
|
39
45
|
return this._safeNotDeployed;
|
40
46
|
}
|
41
|
-
get
|
47
|
+
get mpcAddress() {
|
42
48
|
return this.nearAdapter.address;
|
43
49
|
}
|
44
50
|
async getSafeBalance() {
|
45
|
-
return await this.provider.getBalance(this.
|
51
|
+
return await this.provider.getBalance(this.address);
|
46
52
|
}
|
47
53
|
async buildTransaction(args) {
|
48
54
|
const { transactions, usePaymaster } = args;
|
@@ -53,7 +59,7 @@ class TransactionManager {
|
|
53
59
|
throw new Error("Empty transaction set!");
|
54
60
|
}
|
55
61
|
const tx = transactions.length > 1 ? (0, ethers_multisend_1.encodeMulti)(transactions) : transactions[0];
|
56
|
-
const rawUserOp = await this.safePack.buildUserOp(tx, this.
|
62
|
+
const rawUserOp = await this.safePack.buildUserOp(tx, this.address, gasFees, this.setup, this.safeNotDeployed, this.safeSaltNonce);
|
57
63
|
const paymasterData = await this.bundler.getPaymasterData(rawUserOp, usePaymaster, this.safeNotDeployed);
|
58
64
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
59
65
|
return unsignedUserOp;
|
@@ -67,6 +73,9 @@ class TransactionManager {
|
|
67
73
|
}
|
68
74
|
async encodeSignRequest(tx) {
|
69
75
|
// TODO - This is sloppy and ignores ChainId!
|
76
|
+
if (tx.chainId !== this.chainId) {
|
77
|
+
throw new Error(`Transaciton request for invalid ChainId ${tx.chainId} != ${this.chainId}`);
|
78
|
+
}
|
70
79
|
const unsignedUserOp = await this.buildTransaction({
|
71
80
|
transactions: [
|
72
81
|
{
|
@@ -95,12 +104,12 @@ class TransactionManager {
|
|
95
104
|
console.log("userOp Receipt", userOpReceipt);
|
96
105
|
// Update safeNotDeployed after the first transaction
|
97
106
|
this._safeNotDeployed =
|
98
|
-
(await this.provider.getCode(this.
|
107
|
+
(await this.provider.getCode(this.address)) === "0x";
|
99
108
|
return userOpReceipt;
|
100
109
|
}
|
101
110
|
addOwnerTx(address) {
|
102
111
|
return {
|
103
|
-
to: this.
|
112
|
+
to: this.address,
|
104
113
|
value: "0",
|
105
114
|
data: this.safePack.singleton.interface.encodeFunctionData("addOwnerWithThreshold", [address, 1]),
|
106
115
|
};
|
package/dist/esm/lib/safe.js
CHANGED
@@ -22,7 +22,15 @@ export class ContractSuite {
|
|
22
22
|
}
|
23
23
|
static async init(provider) {
|
24
24
|
const safeDeployment = (fn) => getDeployment(fn, { provider, version: "1.4.1" });
|
25
|
-
const m4337Deployment = (fn) =>
|
25
|
+
const m4337Deployment = async (fn) => {
|
26
|
+
try {
|
27
|
+
return await getDeployment(fn, { provider, version: "0.3.0" });
|
28
|
+
}
|
29
|
+
catch (error) {
|
30
|
+
console.warn(error.message, "using v0.2.0");
|
31
|
+
return getDeployment(fn, { provider, version: "0.2.0" });
|
32
|
+
}
|
33
|
+
};
|
26
34
|
// Need this first to get entryPoint address
|
27
35
|
const m4337 = await m4337Deployment(getSafe4337ModuleDeployment);
|
28
36
|
const [singleton, proxyFactory, moduleSetup, supportedEntryPoint] = await Promise.all([
|
@@ -32,6 +40,13 @@ export class ContractSuite {
|
|
32
40
|
m4337.SUPPORTED_ENTRYPOINT(),
|
33
41
|
]);
|
34
42
|
const entryPoint = new ethers.Contract(supportedEntryPoint, ["function getNonce(address, uint192 key) view returns (uint256 nonce)"], provider);
|
43
|
+
console.log("Initialized ERC4337 & Safe Module Contracts:", {
|
44
|
+
singleton: await singleton.getAddress(),
|
45
|
+
proxyFactory: await proxyFactory.getAddress(),
|
46
|
+
m4337: await m4337.getAddress(),
|
47
|
+
moduleSetup: await moduleSetup.getAddress(),
|
48
|
+
entryPoint: await entryPoint.getAddress(),
|
49
|
+
});
|
35
50
|
return new ContractSuite(provider, singleton, proxyFactory, m4337, moduleSetup, entryPoint);
|
36
51
|
}
|
37
52
|
async addressForSetup(setup, saltNonce) {
|
@@ -104,7 +119,7 @@ async function getDeployment(fn, { provider, version }) {
|
|
104
119
|
const { chainId } = await provider.getNetwork();
|
105
120
|
const deployment = fn({ version });
|
106
121
|
if (!deployment || !deployment.networkAddresses[`${chainId}`]) {
|
107
|
-
throw new Error(`Deployment not found for version ${version}
|
122
|
+
throw new Error(`Deployment not found for ${fn.name} version ${version} on chainId ${chainId}`);
|
108
123
|
}
|
109
124
|
return new ethers.Contract(deployment.networkAddresses[`${chainId}`], deployment.abi, provider);
|
110
125
|
}
|
package/dist/esm/tx-manager.d.ts
CHANGED
@@ -4,26 +4,30 @@ import { Erc4337Bundler } from "./lib/bundler";
|
|
4
4
|
import { UserOperation, UserOperationReceipt } from "./types";
|
5
5
|
import { MetaTransaction } from "ethers-multisend";
|
6
6
|
import { ContractSuite } from "./lib/safe";
|
7
|
-
import { Account } from "near-api-js";
|
8
7
|
export declare class TransactionManager {
|
9
8
|
readonly provider: ethers.JsonRpcProvider;
|
10
9
|
readonly nearAdapter: NearEthAdapter;
|
11
10
|
private safePack;
|
12
11
|
private bundler;
|
13
12
|
private setup;
|
14
|
-
readonly
|
13
|
+
readonly address: string;
|
14
|
+
readonly chainId: number;
|
15
15
|
private safeSaltNonce;
|
16
16
|
private _safeNotDeployed;
|
17
|
-
constructor(provider: ethers.JsonRpcProvider, nearAdapter: NearEthAdapter, safePack: ContractSuite, bundler: Erc4337Bundler, setup: string, safeAddress: string, safeSaltNonce: string, safeNotDeployed: boolean);
|
17
|
+
constructor(provider: ethers.JsonRpcProvider, nearAdapter: NearEthAdapter, safePack: ContractSuite, bundler: Erc4337Bundler, setup: string, chainId: number, safeAddress: string, safeSaltNonce: string, safeNotDeployed: boolean);
|
18
18
|
static create(config: {
|
19
19
|
ethRpc: string;
|
20
|
-
|
21
|
-
|
22
|
-
mpcContractId: string;
|
20
|
+
pimlicoKey: string;
|
21
|
+
nearAdapter: NearEthAdapter;
|
23
22
|
safeSaltNonce?: string;
|
24
23
|
}): Promise<TransactionManager>;
|
24
|
+
static fromChainId(args: {
|
25
|
+
chainId: number;
|
26
|
+
nearAdapter: NearEthAdapter;
|
27
|
+
pimlicoKey: string;
|
28
|
+
}): Promise<TransactionManager>;
|
25
29
|
get safeNotDeployed(): boolean;
|
26
|
-
get
|
30
|
+
get mpcAddress(): `0x${string}`;
|
27
31
|
getSafeBalance(): Promise<bigint>;
|
28
32
|
buildTransaction(args: {
|
29
33
|
transactions: MetaTransaction[];
|
package/dist/esm/tx-manager.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { ethers } from "ethers";
|
2
|
-
import {
|
2
|
+
import { Network } from "near-ca";
|
3
3
|
import { Erc4337Bundler } from "./lib/bundler";
|
4
4
|
import { packSignature } from "./util";
|
5
5
|
import { getNearSignature } from "./lib/near";
|
@@ -11,43 +11,50 @@ export class TransactionManager {
|
|
11
11
|
safePack;
|
12
12
|
bundler;
|
13
13
|
setup;
|
14
|
-
|
14
|
+
address;
|
15
|
+
chainId;
|
15
16
|
safeSaltNonce;
|
16
17
|
_safeNotDeployed;
|
17
|
-
constructor(provider, nearAdapter, safePack, bundler, setup, safeAddress, safeSaltNonce, safeNotDeployed) {
|
18
|
+
constructor(provider, nearAdapter, safePack, bundler, setup, chainId, safeAddress, safeSaltNonce, safeNotDeployed) {
|
18
19
|
this.provider = provider;
|
19
20
|
this.nearAdapter = nearAdapter;
|
20
21
|
this.safePack = safePack;
|
21
22
|
this.bundler = bundler;
|
22
23
|
this.setup = setup;
|
23
|
-
this.
|
24
|
+
this.chainId = chainId;
|
25
|
+
this.address = safeAddress;
|
24
26
|
this.safeSaltNonce = safeSaltNonce;
|
25
27
|
this._safeNotDeployed = safeNotDeployed;
|
26
28
|
}
|
27
29
|
static async create(config) {
|
30
|
+
const { nearAdapter, pimlicoKey } = config;
|
28
31
|
const provider = new ethers.JsonRpcProvider(config.ethRpc);
|
29
|
-
const
|
30
|
-
|
31
|
-
mpcContract: new MpcContract(config.nearAccount, config.mpcContractId),
|
32
|
-
}),
|
33
|
-
ContractSuite.init(provider),
|
34
|
-
]);
|
32
|
+
const chainId = (await provider.getNetwork()).chainId;
|
33
|
+
const safePack = await ContractSuite.init(provider);
|
35
34
|
console.log(`Near Adapter: ${nearAdapter.nearAccountId()} <> ${nearAdapter.address}`);
|
36
|
-
const bundler = new Erc4337Bundler(
|
35
|
+
const bundler = new Erc4337Bundler(`https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoKey}`, await safePack.entryPoint.getAddress());
|
37
36
|
const setup = await safePack.getSetup([nearAdapter.address]);
|
38
37
|
const safeAddress = await safePack.addressForSetup(setup, config.safeSaltNonce);
|
39
38
|
const safeNotDeployed = (await provider.getCode(safeAddress)) === "0x";
|
40
39
|
console.log(`Safe Address: ${safeAddress} - deployed? ${!safeNotDeployed}`);
|
41
|
-
return new TransactionManager(provider, nearAdapter, safePack, bundler, setup, safeAddress, config.safeSaltNonce || "0", safeNotDeployed);
|
40
|
+
return new TransactionManager(provider, nearAdapter, safePack, bundler, setup, parseInt(chainId.toString()), safeAddress, config.safeSaltNonce || "0", safeNotDeployed);
|
41
|
+
}
|
42
|
+
static async fromChainId(args) {
|
43
|
+
const { pimlicoKey, nearAdapter } = args;
|
44
|
+
return TransactionManager.create({
|
45
|
+
ethRpc: Network.fromChainId(args.chainId).rpcUrl,
|
46
|
+
pimlicoKey,
|
47
|
+
nearAdapter,
|
48
|
+
});
|
42
49
|
}
|
43
50
|
get safeNotDeployed() {
|
44
51
|
return this._safeNotDeployed;
|
45
52
|
}
|
46
|
-
get
|
53
|
+
get mpcAddress() {
|
47
54
|
return this.nearAdapter.address;
|
48
55
|
}
|
49
56
|
async getSafeBalance() {
|
50
|
-
return await this.provider.getBalance(this.
|
57
|
+
return await this.provider.getBalance(this.address);
|
51
58
|
}
|
52
59
|
async buildTransaction(args) {
|
53
60
|
const { transactions, usePaymaster } = args;
|
@@ -58,7 +65,7 @@ export class TransactionManager {
|
|
58
65
|
throw new Error("Empty transaction set!");
|
59
66
|
}
|
60
67
|
const tx = transactions.length > 1 ? encodeMulti(transactions) : transactions[0];
|
61
|
-
const rawUserOp = await this.safePack.buildUserOp(tx, this.
|
68
|
+
const rawUserOp = await this.safePack.buildUserOp(tx, this.address, gasFees, this.setup, this.safeNotDeployed, this.safeSaltNonce);
|
62
69
|
const paymasterData = await this.bundler.getPaymasterData(rawUserOp, usePaymaster, this.safeNotDeployed);
|
63
70
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
64
71
|
return unsignedUserOp;
|
@@ -72,6 +79,9 @@ export class TransactionManager {
|
|
72
79
|
}
|
73
80
|
async encodeSignRequest(tx) {
|
74
81
|
// TODO - This is sloppy and ignores ChainId!
|
82
|
+
if (tx.chainId !== this.chainId) {
|
83
|
+
throw new Error(`Transaciton request for invalid ChainId ${tx.chainId} != ${this.chainId}`);
|
84
|
+
}
|
75
85
|
const unsignedUserOp = await this.buildTransaction({
|
76
86
|
transactions: [
|
77
87
|
{
|
@@ -100,12 +110,12 @@ export class TransactionManager {
|
|
100
110
|
console.log("userOp Receipt", userOpReceipt);
|
101
111
|
// Update safeNotDeployed after the first transaction
|
102
112
|
this._safeNotDeployed =
|
103
|
-
(await this.provider.getCode(this.
|
113
|
+
(await this.provider.getCode(this.address)) === "0x";
|
104
114
|
return userOpReceipt;
|
105
115
|
}
|
106
116
|
addOwnerTx(address) {
|
107
117
|
return {
|
108
|
-
to: this.
|
118
|
+
to: this.address,
|
109
119
|
value: "0",
|
110
120
|
data: this.safePack.singleton.interface.encodeFunctionData("addOwnerWithThreshold", [address, 1]),
|
111
121
|
};
|