near-safe 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/lib/safe.js +17 -2
- package/dist/cjs/tx-manager.d.ts +10 -4
- package/dist/cjs/tx-manager.js +26 -12
- package/dist/esm/lib/safe.js +17 -2
- package/dist/esm/tx-manager.d.ts +10 -4
- package/dist/esm/tx-manager.js +28 -13
- 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
@@ -10,18 +10,24 @@ export declare class TransactionManager {
|
|
10
10
|
private safePack;
|
11
11
|
private bundler;
|
12
12
|
private setup;
|
13
|
-
readonly
|
13
|
+
readonly address: string;
|
14
|
+
readonly chainId: number;
|
14
15
|
private safeSaltNonce;
|
15
16
|
private _safeNotDeployed;
|
16
|
-
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);
|
17
18
|
static create(config: {
|
18
19
|
ethRpc: string;
|
19
|
-
|
20
|
+
pimlicoKey: string;
|
20
21
|
nearAdapter: NearEthAdapter;
|
21
22
|
safeSaltNonce?: string;
|
22
23
|
}): Promise<TransactionManager>;
|
24
|
+
static fromChainId(args: {
|
25
|
+
chainId: number;
|
26
|
+
nearAdapter: NearEthAdapter;
|
27
|
+
pimlicoKey: string;
|
28
|
+
}): Promise<TransactionManager>;
|
23
29
|
get safeNotDeployed(): boolean;
|
24
|
-
get
|
30
|
+
get mpcAddress(): `0x${string}`;
|
25
31
|
getSafeBalance(): Promise<bigint>;
|
26
32
|
buildTransaction(args: {
|
27
33
|
transactions: MetaTransaction[];
|
package/dist/cjs/tx-manager.js
CHANGED
@@ -2,42 +2,53 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.TransactionManager = void 0;
|
4
4
|
const ethers_1 = require("ethers");
|
5
|
+
const near_ca_1 = require("near-ca");
|
5
6
|
const bundler_1 = require("./lib/bundler");
|
6
7
|
const util_1 = require("./util");
|
7
8
|
const near_1 = require("./lib/near");
|
8
9
|
const ethers_multisend_1 = require("ethers-multisend");
|
9
10
|
const safe_1 = require("./lib/safe");
|
10
11
|
class TransactionManager {
|
11
|
-
constructor(provider, nearAdapter, safePack, bundler, setup, safeAddress, safeSaltNonce, safeNotDeployed) {
|
12
|
+
constructor(provider, nearAdapter, safePack, bundler, setup, chainId, safeAddress, safeSaltNonce, safeNotDeployed) {
|
12
13
|
this.provider = provider;
|
13
14
|
this.nearAdapter = nearAdapter;
|
14
15
|
this.safePack = safePack;
|
15
16
|
this.bundler = bundler;
|
16
17
|
this.setup = setup;
|
17
|
-
this.
|
18
|
+
this.chainId = chainId;
|
19
|
+
this.address = safeAddress;
|
18
20
|
this.safeSaltNonce = safeSaltNonce;
|
19
21
|
this._safeNotDeployed = safeNotDeployed;
|
20
22
|
}
|
21
23
|
static async create(config) {
|
22
|
-
const
|
24
|
+
const { nearAdapter, pimlicoKey } = config;
|
23
25
|
const provider = new ethers_1.ethers.JsonRpcProvider(config.ethRpc);
|
26
|
+
const chainId = (await provider.getNetwork()).chainId;
|
24
27
|
const safePack = await safe_1.ContractSuite.init(provider);
|
25
|
-
console.log(`Near Adapter: ${
|
26
|
-
const bundler = new bundler_1.Erc4337Bundler(
|
27
|
-
const setup = await safePack.getSetup([
|
28
|
+
console.log(`Near Adapter: ${nearAdapter.nearAccountId()} <> ${nearAdapter.address}`);
|
29
|
+
const bundler = new bundler_1.Erc4337Bundler(`https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoKey}`, await safePack.entryPoint.getAddress());
|
30
|
+
const setup = await safePack.getSetup([nearAdapter.address]);
|
28
31
|
const safeAddress = await safePack.addressForSetup(setup, config.safeSaltNonce);
|
29
32
|
const safeNotDeployed = (await provider.getCode(safeAddress)) === "0x";
|
30
33
|
console.log(`Safe Address: ${safeAddress} - deployed? ${!safeNotDeployed}`);
|
31
|
-
return new TransactionManager(provider,
|
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
|
+
});
|
32
43
|
}
|
33
44
|
get safeNotDeployed() {
|
34
45
|
return this._safeNotDeployed;
|
35
46
|
}
|
36
|
-
get
|
47
|
+
get mpcAddress() {
|
37
48
|
return this.nearAdapter.address;
|
38
49
|
}
|
39
50
|
async getSafeBalance() {
|
40
|
-
return await this.provider.getBalance(this.
|
51
|
+
return await this.provider.getBalance(this.address);
|
41
52
|
}
|
42
53
|
async buildTransaction(args) {
|
43
54
|
const { transactions, usePaymaster } = args;
|
@@ -48,7 +59,7 @@ class TransactionManager {
|
|
48
59
|
throw new Error("Empty transaction set!");
|
49
60
|
}
|
50
61
|
const tx = transactions.length > 1 ? (0, ethers_multisend_1.encodeMulti)(transactions) : transactions[0];
|
51
|
-
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);
|
52
63
|
const paymasterData = await this.bundler.getPaymasterData(rawUserOp, usePaymaster, this.safeNotDeployed);
|
53
64
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
54
65
|
return unsignedUserOp;
|
@@ -62,6 +73,9 @@ class TransactionManager {
|
|
62
73
|
}
|
63
74
|
async encodeSignRequest(tx) {
|
64
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
|
+
}
|
65
79
|
const unsignedUserOp = await this.buildTransaction({
|
66
80
|
transactions: [
|
67
81
|
{
|
@@ -90,12 +104,12 @@ class TransactionManager {
|
|
90
104
|
console.log("userOp Receipt", userOpReceipt);
|
91
105
|
// Update safeNotDeployed after the first transaction
|
92
106
|
this._safeNotDeployed =
|
93
|
-
(await this.provider.getCode(this.
|
107
|
+
(await this.provider.getCode(this.address)) === "0x";
|
94
108
|
return userOpReceipt;
|
95
109
|
}
|
96
110
|
addOwnerTx(address) {
|
97
111
|
return {
|
98
|
-
to: this.
|
112
|
+
to: this.address,
|
99
113
|
value: "0",
|
100
114
|
data: this.safePack.singleton.interface.encodeFunctionData("addOwnerWithThreshold", [address, 1]),
|
101
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
@@ -10,18 +10,24 @@ export declare class TransactionManager {
|
|
10
10
|
private safePack;
|
11
11
|
private bundler;
|
12
12
|
private setup;
|
13
|
-
readonly
|
13
|
+
readonly address: string;
|
14
|
+
readonly chainId: number;
|
14
15
|
private safeSaltNonce;
|
15
16
|
private _safeNotDeployed;
|
16
|
-
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);
|
17
18
|
static create(config: {
|
18
19
|
ethRpc: string;
|
19
|
-
|
20
|
+
pimlicoKey: string;
|
20
21
|
nearAdapter: NearEthAdapter;
|
21
22
|
safeSaltNonce?: string;
|
22
23
|
}): Promise<TransactionManager>;
|
24
|
+
static fromChainId(args: {
|
25
|
+
chainId: number;
|
26
|
+
nearAdapter: NearEthAdapter;
|
27
|
+
pimlicoKey: string;
|
28
|
+
}): Promise<TransactionManager>;
|
23
29
|
get safeNotDeployed(): boolean;
|
24
|
-
get
|
30
|
+
get mpcAddress(): `0x${string}`;
|
25
31
|
getSafeBalance(): Promise<bigint>;
|
26
32
|
buildTransaction(args: {
|
27
33
|
transactions: MetaTransaction[];
|
package/dist/esm/tx-manager.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { ethers } from "ethers";
|
2
|
+
import { Network } from "near-ca";
|
2
3
|
import { Erc4337Bundler } from "./lib/bundler";
|
3
4
|
import { packSignature } from "./util";
|
4
5
|
import { getNearSignature } from "./lib/near";
|
@@ -10,39 +11,50 @@ export class TransactionManager {
|
|
10
11
|
safePack;
|
11
12
|
bundler;
|
12
13
|
setup;
|
13
|
-
|
14
|
+
address;
|
15
|
+
chainId;
|
14
16
|
safeSaltNonce;
|
15
17
|
_safeNotDeployed;
|
16
|
-
constructor(provider, nearAdapter, safePack, bundler, setup, safeAddress, safeSaltNonce, safeNotDeployed) {
|
18
|
+
constructor(provider, nearAdapter, safePack, bundler, setup, chainId, safeAddress, safeSaltNonce, safeNotDeployed) {
|
17
19
|
this.provider = provider;
|
18
20
|
this.nearAdapter = nearAdapter;
|
19
21
|
this.safePack = safePack;
|
20
22
|
this.bundler = bundler;
|
21
23
|
this.setup = setup;
|
22
|
-
this.
|
24
|
+
this.chainId = chainId;
|
25
|
+
this.address = safeAddress;
|
23
26
|
this.safeSaltNonce = safeSaltNonce;
|
24
27
|
this._safeNotDeployed = safeNotDeployed;
|
25
28
|
}
|
26
29
|
static async create(config) {
|
27
|
-
const
|
30
|
+
const { nearAdapter, pimlicoKey } = config;
|
28
31
|
const provider = new ethers.JsonRpcProvider(config.ethRpc);
|
32
|
+
const chainId = (await provider.getNetwork()).chainId;
|
29
33
|
const safePack = await ContractSuite.init(provider);
|
30
|
-
console.log(`Near Adapter: ${
|
31
|
-
const bundler = new Erc4337Bundler(
|
32
|
-
const setup = await safePack.getSetup([
|
34
|
+
console.log(`Near Adapter: ${nearAdapter.nearAccountId()} <> ${nearAdapter.address}`);
|
35
|
+
const bundler = new Erc4337Bundler(`https://api.pimlico.io/v2/${chainId}/rpc?apikey=${pimlicoKey}`, await safePack.entryPoint.getAddress());
|
36
|
+
const setup = await safePack.getSetup([nearAdapter.address]);
|
33
37
|
const safeAddress = await safePack.addressForSetup(setup, config.safeSaltNonce);
|
34
38
|
const safeNotDeployed = (await provider.getCode(safeAddress)) === "0x";
|
35
39
|
console.log(`Safe Address: ${safeAddress} - deployed? ${!safeNotDeployed}`);
|
36
|
-
return new TransactionManager(provider,
|
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
|
+
});
|
37
49
|
}
|
38
50
|
get safeNotDeployed() {
|
39
51
|
return this._safeNotDeployed;
|
40
52
|
}
|
41
|
-
get
|
53
|
+
get mpcAddress() {
|
42
54
|
return this.nearAdapter.address;
|
43
55
|
}
|
44
56
|
async getSafeBalance() {
|
45
|
-
return await this.provider.getBalance(this.
|
57
|
+
return await this.provider.getBalance(this.address);
|
46
58
|
}
|
47
59
|
async buildTransaction(args) {
|
48
60
|
const { transactions, usePaymaster } = args;
|
@@ -53,7 +65,7 @@ export class TransactionManager {
|
|
53
65
|
throw new Error("Empty transaction set!");
|
54
66
|
}
|
55
67
|
const tx = transactions.length > 1 ? encodeMulti(transactions) : transactions[0];
|
56
|
-
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);
|
57
69
|
const paymasterData = await this.bundler.getPaymasterData(rawUserOp, usePaymaster, this.safeNotDeployed);
|
58
70
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
59
71
|
return unsignedUserOp;
|
@@ -67,6 +79,9 @@ export class TransactionManager {
|
|
67
79
|
}
|
68
80
|
async encodeSignRequest(tx) {
|
69
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
|
+
}
|
70
85
|
const unsignedUserOp = await this.buildTransaction({
|
71
86
|
transactions: [
|
72
87
|
{
|
@@ -95,12 +110,12 @@ export class TransactionManager {
|
|
95
110
|
console.log("userOp Receipt", userOpReceipt);
|
96
111
|
// Update safeNotDeployed after the first transaction
|
97
112
|
this._safeNotDeployed =
|
98
|
-
(await this.provider.getCode(this.
|
113
|
+
(await this.provider.getCode(this.address)) === "0x";
|
99
114
|
return userOpReceipt;
|
100
115
|
}
|
101
116
|
addOwnerTx(address) {
|
102
117
|
return {
|
103
|
-
to: this.
|
118
|
+
to: this.address,
|
104
119
|
value: "0",
|
105
120
|
data: this.safePack.singleton.interface.encodeFunctionData("addOwnerWithThreshold", [address, 1]),
|
106
121
|
};
|