near-safe 0.3.2 → 0.4.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/dist/cjs/_gen/deployments.d.ts +2 -0
- package/dist/cjs/_gen/deployments.js +1889 -0
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/lib/bundler.d.ts +1 -0
- package/dist/cjs/lib/bundler.js +15 -4
- package/dist/cjs/lib/safe.d.ts +9 -15
- package/dist/cjs/lib/safe.js +12 -56
- package/dist/cjs/{tx-manager.d.ts → near-safe.d.ts} +18 -17
- package/dist/cjs/{tx-manager.js → near-safe.js} +43 -50
- package/dist/cjs/types.d.ts +12 -1
- package/dist/esm/_gen/deployments.d.ts +2 -0
- package/dist/esm/_gen/deployments.js +1886 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/lib/bundler.d.ts +1 -0
- package/dist/esm/lib/bundler.js +14 -4
- package/dist/esm/lib/safe.d.ts +9 -15
- package/dist/esm/lib/safe.js +11 -55
- package/dist/esm/{tx-manager.d.ts → near-safe.d.ts} +18 -17
- package/dist/esm/{tx-manager.js → near-safe.js} +42 -50
- package/dist/esm/types.d.ts +12 -1
- package/package.json +4 -3
package/dist/cjs/index.d.ts
CHANGED
package/dist/cjs/index.js
CHANGED
@@ -15,7 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
15
|
};
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
17
17
|
exports.populateTx = exports.Network = void 0;
|
18
|
-
__exportStar(require("./
|
18
|
+
__exportStar(require("./near-safe"), exports);
|
19
19
|
__exportStar(require("./types"), exports);
|
20
20
|
__exportStar(require("./util"), exports);
|
21
21
|
var near_ca_1 = require("near-ca");
|
package/dist/cjs/lib/bundler.js
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.Erc4337Bundler = void 0;
|
4
|
+
exports.stripApiKey = stripApiKey;
|
4
5
|
const viem_1 = require("viem");
|
5
6
|
const util_1 = require("../util");
|
6
7
|
function bundlerUrl(chainId, apikey) {
|
@@ -65,18 +66,19 @@ async function handleRequest(clientMethod) {
|
|
65
66
|
return await clientMethod();
|
66
67
|
}
|
67
68
|
catch (error) {
|
69
|
+
const message = stripApiKey(error);
|
68
70
|
if (error instanceof viem_1.HttpRequestError) {
|
69
71
|
if (error.status === 401) {
|
70
|
-
throw new Error("Unauthorized request. Please check your API key.");
|
72
|
+
throw new Error("Unauthorized request. Please check your Pimlico API key.");
|
71
73
|
}
|
72
74
|
else {
|
73
|
-
|
75
|
+
throw new Error(`Pimlico: ${message}`);
|
74
76
|
}
|
75
77
|
}
|
76
78
|
else if (error instanceof viem_1.RpcError) {
|
77
|
-
throw new Error(`Failed to send user op with: ${
|
79
|
+
throw new Error(`Failed to send user op with: ${message}`);
|
78
80
|
}
|
79
|
-
throw new Error(`
|
81
|
+
throw new Error(`Bundler Request: ${message}`);
|
80
82
|
}
|
81
83
|
}
|
82
84
|
// TODO(bh2smith) Should probably get reasonable estimates here:
|
@@ -87,3 +89,12 @@ const defaultPaymasterData = (safeNotDeployed) => {
|
|
87
89
|
preVerificationGas: (0, viem_1.toHex)(100000),
|
88
90
|
};
|
89
91
|
};
|
92
|
+
function stripApiKey(error) {
|
93
|
+
const message = error instanceof Error ? error.message : String(error);
|
94
|
+
return message.replace(/(apikey=)[^\s&]+/, "$1***");
|
95
|
+
// Could also do this with slicing.
|
96
|
+
// const keyStart = message.indexOf("apikey=") + 7;
|
97
|
+
// // If no apikey in the message, return it as is.
|
98
|
+
// if (keyStart === -1) return message;
|
99
|
+
// return `${message.slice(0, keyStart)}***${message.slice(keyStart + 36)}`;
|
100
|
+
}
|
package/dist/cjs/lib/safe.d.ts
CHANGED
@@ -1,21 +1,16 @@
|
|
1
|
-
import { Address, Hash, Hex,
|
2
|
-
import { GasPrice, MetaTransaction, UnsignedUserOperation, UserOperation } from "../types";
|
3
|
-
interface DeploymentData {
|
4
|
-
abi: unknown[] | ParseAbi<readonly string[]>;
|
5
|
-
address: `0x${string}`;
|
6
|
-
}
|
1
|
+
import { Address, Hash, Hex, PublicClient } from "viem";
|
2
|
+
import { Deployment, GasPrice, MetaTransaction, UnsignedUserOperation, UserOperation } from "../types";
|
7
3
|
/**
|
8
4
|
* All contracts used in account creation & execution
|
9
5
|
*/
|
10
|
-
export declare class
|
6
|
+
export declare class SafeContractSuite {
|
11
7
|
dummyClient: PublicClient;
|
12
|
-
singleton:
|
13
|
-
proxyFactory:
|
14
|
-
m4337:
|
15
|
-
moduleSetup:
|
16
|
-
entryPoint:
|
17
|
-
constructor(
|
18
|
-
static init(): Promise<ContractSuite>;
|
8
|
+
singleton: Deployment;
|
9
|
+
proxyFactory: Deployment;
|
10
|
+
m4337: Deployment;
|
11
|
+
moduleSetup: Deployment;
|
12
|
+
entryPoint: Deployment;
|
13
|
+
constructor();
|
19
14
|
addressForSetup(setup: Hex, saltNonce?: string): Promise<Address>;
|
20
15
|
getSetup(owners: string[]): Hex;
|
21
16
|
addOwnerData(newOwner: Address): Hex;
|
@@ -24,4 +19,3 @@ export declare class ContractSuite {
|
|
24
19
|
buildUserOp(nonce: bigint, txData: MetaTransaction, safeAddress: Address, feeData: GasPrice, setup: string, safeNotDeployed: boolean, safeSaltNonce: string): Promise<UnsignedUserOperation>;
|
25
20
|
getNonce(address: Address, chainId: number): Promise<bigint>;
|
26
21
|
}
|
27
|
-
export {};
|
package/dist/cjs/lib/safe.js
CHANGED
@@ -1,54 +1,21 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
4
|
-
const safe_deployments_1 = require("@safe-global/safe-deployments");
|
5
|
-
const safe_modules_deployments_1 = require("@safe-global/safe-modules-deployments");
|
3
|
+
exports.SafeContractSuite = void 0;
|
6
4
|
const viem_1 = require("viem");
|
5
|
+
const deployments_1 = require("../_gen/deployments");
|
7
6
|
const util_1 = require("../util");
|
8
7
|
/**
|
9
8
|
* All contracts used in account creation & execution
|
10
9
|
*/
|
11
|
-
class
|
12
|
-
constructor(
|
13
|
-
this.dummyClient =
|
14
|
-
|
15
|
-
this.
|
16
|
-
this.
|
17
|
-
this.
|
18
|
-
this.
|
19
|
-
|
20
|
-
static async init() {
|
21
|
-
// TODO - this is a cheeky hack.
|
22
|
-
const client = (0, util_1.getClient)(11155111);
|
23
|
-
const safeDeployment = (fn) => getDeployment(fn, { version: "1.4.1" });
|
24
|
-
const m4337Deployment = async (fn) => {
|
25
|
-
return getDeployment(fn, { version: "0.3.0" });
|
26
|
-
};
|
27
|
-
const [singleton, proxyFactory, moduleSetup, m4337] = await Promise.all([
|
28
|
-
safeDeployment(safe_deployments_1.getSafeL2SingletonDeployment),
|
29
|
-
safeDeployment(safe_deployments_1.getProxyFactoryDeployment),
|
30
|
-
m4337Deployment(safe_modules_deployments_1.getSafeModuleSetupDeployment),
|
31
|
-
m4337Deployment(safe_modules_deployments_1.getSafe4337ModuleDeployment),
|
32
|
-
]);
|
33
|
-
// console.log("Initialized ERC4337 & Safe Module Contracts:", {
|
34
|
-
// singleton: await singleton.getAddress(),
|
35
|
-
// proxyFactory: await proxyFactory.getAddress(),
|
36
|
-
// m4337: await m4337.getAddress(),
|
37
|
-
// moduleSetup: await moduleSetup.getAddress(),
|
38
|
-
// entryPoint: await entryPoint.getAddress(),
|
39
|
-
// });
|
40
|
-
return new ContractSuite(client, singleton, proxyFactory, m4337, moduleSetup,
|
41
|
-
// EntryPoint:
|
42
|
-
{
|
43
|
-
address: (await client.readContract({
|
44
|
-
address: m4337.address,
|
45
|
-
abi: m4337.abi,
|
46
|
-
functionName: "SUPPORTED_ENTRYPOINT",
|
47
|
-
})),
|
48
|
-
abi: (0, viem_1.parseAbi)([
|
49
|
-
"function getNonce(address, uint192 key) view returns (uint256 nonce)",
|
50
|
-
]),
|
51
|
-
});
|
10
|
+
class SafeContractSuite {
|
11
|
+
constructor() {
|
12
|
+
this.dummyClient = (0, util_1.getClient)(11155111);
|
13
|
+
const deployments = deployments_1.SAFE_DEPLOYMENTS;
|
14
|
+
this.singleton = deployments.singleton;
|
15
|
+
this.proxyFactory = deployments.proxyFactory;
|
16
|
+
this.m4337 = deployments.m4337;
|
17
|
+
this.moduleSetup = deployments.moduleSetup;
|
18
|
+
this.entryPoint = deployments.entryPoint;
|
52
19
|
}
|
53
20
|
async addressForSetup(setup, saltNonce) {
|
54
21
|
// bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));
|
@@ -159,15 +126,4 @@ class ContractSuite {
|
|
159
126
|
return nonce;
|
160
127
|
}
|
161
128
|
}
|
162
|
-
exports.
|
163
|
-
async function getDeployment(fn, { version }) {
|
164
|
-
const deployment = fn({ version });
|
165
|
-
if (!deployment) {
|
166
|
-
throw new Error(`Deployment not found for ${fn.name} version ${version}`);
|
167
|
-
}
|
168
|
-
// TODO: maybe call parseAbi on deployment.abi here.
|
169
|
-
return {
|
170
|
-
address: deployment.networkAddresses["11155111"],
|
171
|
-
abi: deployment.abi,
|
172
|
-
};
|
173
|
-
}
|
129
|
+
exports.SafeContractSuite = SafeContractSuite;
|
@@ -1,29 +1,29 @@
|
|
1
|
+
import { NearConfig } from "near-api-js/lib/near";
|
1
2
|
import { FinalExecutionOutcome } from "near-api-js/lib/providers";
|
2
3
|
import { NearEthAdapter, SignRequestData } from "near-ca";
|
3
4
|
import { Address, Hash, Hex } from "viem";
|
4
|
-
import {
|
5
|
-
import { ContractSuite } from "./lib/safe";
|
5
|
+
import { SafeContractSuite } from "./lib/safe";
|
6
6
|
import { EncodedTxData, MetaTransaction, UserOperation, UserOperationReceipt } from "./types";
|
7
|
-
export
|
7
|
+
export interface NearSafeConfig {
|
8
|
+
accountId: string;
|
9
|
+
mpcContractId: string;
|
10
|
+
pimlicoKey: string;
|
11
|
+
nearConfig?: NearConfig;
|
12
|
+
privateKey?: string;
|
13
|
+
safeSaltNonce?: string;
|
14
|
+
}
|
15
|
+
export declare class NearSafe {
|
8
16
|
readonly nearAdapter: NearEthAdapter;
|
9
17
|
readonly address: Address;
|
10
18
|
private safePack;
|
11
19
|
private setup;
|
12
20
|
private pimlicoKey;
|
13
21
|
private safeSaltNonce;
|
14
|
-
|
15
|
-
constructor(nearAdapter: NearEthAdapter, safePack:
|
16
|
-
static create(config: {
|
17
|
-
accountId: string;
|
18
|
-
mpcContractId: string;
|
19
|
-
pimlicoKey: string;
|
20
|
-
privateKey?: string;
|
21
|
-
safeSaltNonce?: string;
|
22
|
-
}): Promise<TransactionManager>;
|
22
|
+
static create(config: NearSafeConfig): Promise<NearSafe>;
|
23
|
+
constructor(nearAdapter: NearEthAdapter, safePack: SafeContractSuite, pimlicoKey: string, setup: string, safeAddress: Address, safeSaltNonce: string);
|
23
24
|
get mpcAddress(): Address;
|
24
25
|
get mpcContractId(): string;
|
25
26
|
getBalance(chainId: number): Promise<bigint>;
|
26
|
-
bundlerForChainId(chainId: number): Erc4337Bundler;
|
27
27
|
buildTransaction(args: {
|
28
28
|
chainId: number;
|
29
29
|
transactions: MetaTransaction[];
|
@@ -32,14 +32,15 @@ export declare class TransactionManager {
|
|
32
32
|
signTransaction(safeOpHash: Hex): Promise<Hex>;
|
33
33
|
opHash(userOp: UserOperation): Promise<Hash>;
|
34
34
|
encodeSignRequest(signRequest: SignRequestData, usePaymaster: boolean): Promise<EncodedTxData>;
|
35
|
-
executeTransaction(chainId: number, userOp: UserOperation): Promise<UserOperationReceipt>;
|
36
|
-
safeDeployed(chainId: number): Promise<boolean>;
|
37
|
-
addOwnerTx(address: Address): MetaTransaction;
|
38
|
-
safeSufficientlyFunded(chainId: number, transactions: MetaTransaction[], gasCost: bigint): Promise<boolean>;
|
39
35
|
broadcastEvm(chainId: number, outcome: FinalExecutionOutcome, unsignedUserOp: UserOperation): Promise<{
|
40
36
|
signature: Hex;
|
41
37
|
receipt: UserOperationReceipt;
|
42
38
|
}>;
|
39
|
+
executeTransaction(chainId: number, userOp: UserOperation): Promise<UserOperationReceipt>;
|
40
|
+
safeDeployed(chainId: number): Promise<boolean>;
|
41
|
+
sufficientlyFunded(chainId: number, transactions: MetaTransaction[], gasCost: bigint): Promise<boolean>;
|
42
|
+
addOwnerTx(address: Address): MetaTransaction;
|
43
|
+
private bundlerForChainId;
|
43
44
|
/**
|
44
45
|
* Handles routing of signature requests based on the provided method, chain ID, and parameters.
|
45
46
|
*
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.NearSafe = void 0;
|
4
4
|
const near_ca_1 = require("near-ca");
|
5
5
|
const viem_1 = require("viem");
|
6
6
|
const bundler_1 = require("./lib/bundler");
|
@@ -8,27 +8,28 @@ const multisend_1 = require("./lib/multisend");
|
|
8
8
|
const safe_1 = require("./lib/safe");
|
9
9
|
const safe_message_1 = require("./lib/safe-message");
|
10
10
|
const util_1 = require("./util");
|
11
|
-
class
|
11
|
+
class NearSafe {
|
12
|
+
static async create(config) {
|
13
|
+
const { pimlicoKey, safeSaltNonce } = config;
|
14
|
+
const nearAdapter = await (0, near_ca_1.setupAdapter)({ ...config });
|
15
|
+
const safePack = new safe_1.SafeContractSuite();
|
16
|
+
const setup = safePack.getSetup([nearAdapter.address]);
|
17
|
+
const safeAddress = await safePack.addressForSetup(setup, safeSaltNonce);
|
18
|
+
console.log(`
|
19
|
+
Near Adapter:
|
20
|
+
Near Account ID: ${nearAdapter.nearAccountId()}
|
21
|
+
MPC EOA: ${nearAdapter.address}
|
22
|
+
Safe: ${safeAddress}
|
23
|
+
`);
|
24
|
+
return new NearSafe(nearAdapter, safePack, pimlicoKey, setup, safeAddress, safeSaltNonce || "0");
|
25
|
+
}
|
12
26
|
constructor(nearAdapter, safePack, pimlicoKey, setup, safeAddress, safeSaltNonce) {
|
13
27
|
this.nearAdapter = nearAdapter;
|
28
|
+
this.address = safeAddress;
|
29
|
+
this.setup = setup;
|
14
30
|
this.safePack = safePack;
|
15
31
|
this.pimlicoKey = pimlicoKey;
|
16
|
-
this.setup = setup;
|
17
|
-
this.address = safeAddress;
|
18
32
|
this.safeSaltNonce = safeSaltNonce;
|
19
|
-
this.deployedChains = new Set();
|
20
|
-
}
|
21
|
-
static async create(config) {
|
22
|
-
const { pimlicoKey } = config;
|
23
|
-
const [nearAdapter, safePack] = await Promise.all([
|
24
|
-
(0, near_ca_1.setupAdapter)({ ...config }),
|
25
|
-
safe_1.ContractSuite.init(),
|
26
|
-
]);
|
27
|
-
console.log(`Near Adapter: ${nearAdapter.nearAccountId()} <> ${nearAdapter.address}`);
|
28
|
-
const setup = safePack.getSetup([nearAdapter.address]);
|
29
|
-
const safeAddress = await safePack.addressForSetup(setup, config.safeSaltNonce);
|
30
|
-
console.log(`Safe Address: ${safeAddress}`);
|
31
|
-
return new TransactionManager(nearAdapter, safePack, pimlicoKey, setup, safeAddress, config.safeSaltNonce || "0");
|
32
33
|
}
|
33
34
|
get mpcAddress() {
|
34
35
|
return this.nearAdapter.address;
|
@@ -39,9 +40,6 @@ class TransactionManager {
|
|
39
40
|
async getBalance(chainId) {
|
40
41
|
return await (0, util_1.getClient)(chainId).getBalance({ address: this.address });
|
41
42
|
}
|
42
|
-
bundlerForChainId(chainId) {
|
43
|
-
return new bundler_1.Erc4337Bundler(this.safePack.entryPoint.address, this.pimlicoKey, chainId);
|
44
|
-
}
|
45
43
|
async buildTransaction(args) {
|
46
44
|
const { transactions, usePaymaster, chainId } = args;
|
47
45
|
if (transactions.length === 0) {
|
@@ -82,6 +80,21 @@ class TransactionManager {
|
|
82
80
|
},
|
83
81
|
};
|
84
82
|
}
|
83
|
+
async broadcastEvm(chainId, outcome, unsignedUserOp) {
|
84
|
+
const signature = (0, util_1.packSignature)((0, viem_1.serializeSignature)((0, near_ca_1.signatureFromOutcome)(outcome)));
|
85
|
+
try {
|
86
|
+
return {
|
87
|
+
signature,
|
88
|
+
receipt: await this.executeTransaction(chainId, {
|
89
|
+
...unsignedUserOp,
|
90
|
+
signature,
|
91
|
+
}),
|
92
|
+
};
|
93
|
+
}
|
94
|
+
catch (error) {
|
95
|
+
throw new Error(`Failed EVM broadcast: ${error instanceof Error ? error.message : String(error)}`);
|
96
|
+
}
|
97
|
+
}
|
85
98
|
async executeTransaction(chainId, userOp) {
|
86
99
|
const bundler = this.bundlerForChainId(chainId);
|
87
100
|
const userOpHash = await bundler.sendUserOperation(userOp);
|
@@ -93,15 +106,15 @@ class TransactionManager {
|
|
93
106
|
return userOpReceipt;
|
94
107
|
}
|
95
108
|
async safeDeployed(chainId) {
|
96
|
-
|
97
|
-
|
109
|
+
return (0, util_1.isContract)(this.address, chainId);
|
110
|
+
}
|
111
|
+
async sufficientlyFunded(chainId, transactions, gasCost) {
|
112
|
+
const txValue = transactions.reduce((acc, tx) => acc + BigInt(tx.value), 0n);
|
113
|
+
if (txValue + gasCost === 0n) {
|
98
114
|
return true;
|
99
115
|
}
|
100
|
-
const
|
101
|
-
|
102
|
-
this.deployedChains.add(chainId);
|
103
|
-
}
|
104
|
-
return deployed;
|
116
|
+
const safeBalance = await this.getBalance(chainId);
|
117
|
+
return txValue + gasCost < safeBalance;
|
105
118
|
}
|
106
119
|
addOwnerTx(address) {
|
107
120
|
return {
|
@@ -110,28 +123,8 @@ class TransactionManager {
|
|
110
123
|
data: this.safePack.addOwnerData(address),
|
111
124
|
};
|
112
125
|
}
|
113
|
-
|
114
|
-
|
115
|
-
if (txValue + gasCost === 0n) {
|
116
|
-
return true;
|
117
|
-
}
|
118
|
-
const safeBalance = await this.getBalance(chainId);
|
119
|
-
return txValue + gasCost < safeBalance;
|
120
|
-
}
|
121
|
-
async broadcastEvm(chainId, outcome, unsignedUserOp) {
|
122
|
-
const signature = (0, util_1.packSignature)((0, viem_1.serializeSignature)((0, near_ca_1.signatureFromOutcome)(outcome)));
|
123
|
-
try {
|
124
|
-
return {
|
125
|
-
signature,
|
126
|
-
receipt: await this.executeTransaction(chainId, {
|
127
|
-
...unsignedUserOp,
|
128
|
-
signature,
|
129
|
-
}),
|
130
|
-
};
|
131
|
-
}
|
132
|
-
catch (error) {
|
133
|
-
throw new Error(`Failed EVM broadcast: ${error instanceof Error ? error.message : String(error)}`);
|
134
|
-
}
|
126
|
+
bundlerForChainId(chainId) {
|
127
|
+
return new bundler_1.Erc4337Bundler(this.safePack.entryPoint.address, this.pimlicoKey, chainId);
|
135
128
|
}
|
136
129
|
/**
|
137
130
|
* Handles routing of signature requests based on the provided method, chain ID, and parameters.
|
@@ -190,4 +183,4 @@ class TransactionManager {
|
|
190
183
|
}
|
191
184
|
}
|
192
185
|
}
|
193
|
-
exports.
|
186
|
+
exports.NearSafe = NearSafe;
|
package/dist/cjs/types.d.ts
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
import { FunctionCallTransaction, SignArgs } from "near-ca";
|
2
|
-
import { Address, Hash, Hex, TransactionSerializable } from "viem";
|
2
|
+
import { Address, Hash, Hex, ParseAbi, TransactionSerializable } from "viem";
|
3
|
+
export type SafeDeployments = {
|
4
|
+
singleton: Deployment;
|
5
|
+
proxyFactory: Deployment;
|
6
|
+
moduleSetup: Deployment;
|
7
|
+
m4337: Deployment;
|
8
|
+
entryPoint: Deployment;
|
9
|
+
};
|
10
|
+
export interface Deployment {
|
11
|
+
abi: unknown[] | ParseAbi<readonly string[]>;
|
12
|
+
address: Address;
|
13
|
+
}
|
3
14
|
export interface UnsignedUserOperation {
|
4
15
|
sender: Address;
|
5
16
|
nonce: string;
|