near-safe 0.2.0 → 0.3.0
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 +5 -4
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/lib/bundler.d.ts +31 -9
- package/dist/cjs/lib/bundler.js +46 -27
- package/dist/cjs/lib/multisend.d.ts +3 -0
- package/dist/cjs/lib/multisend.js +40 -0
- package/dist/cjs/lib/safe.d.ts +20 -18
- package/dist/cjs/lib/safe.js +117 -71
- package/dist/cjs/tx-manager.d.ts +13 -7
- package/dist/cjs/tx-manager.js +44 -22
- package/dist/cjs/types.d.ts +10 -0
- package/dist/cjs/types.js +6 -0
- package/dist/cjs/util.d.ts +4 -3
- package/dist/cjs/util.js +9 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/lib/bundler.d.ts +31 -9
- package/dist/esm/lib/bundler.js +48 -29
- package/dist/esm/lib/multisend.d.ts +3 -0
- package/dist/esm/lib/multisend.js +36 -0
- package/dist/esm/lib/safe.d.ts +20 -18
- package/dist/esm/lib/safe.js +120 -73
- package/dist/esm/tx-manager.d.ts +13 -7
- package/dist/esm/tx-manager.js +44 -23
- package/dist/esm/types.d.ts +10 -0
- package/dist/esm/types.js +5 -1
- package/dist/esm/util.d.ts +4 -3
- package/dist/esm/util.js +8 -1
- package/package.json +9 -6
package/dist/esm/lib/safe.js
CHANGED
@@ -1,19 +1,20 @@
|
|
1
|
-
import { ethers } from "ethers";
|
2
1
|
import { getProxyFactoryDeployment, getSafeL2SingletonDeployment, } from "@safe-global/safe-deployments";
|
3
2
|
import { getSafe4337ModuleDeployment, getSafeModuleSetupDeployment, } from "@safe-global/safe-modules-deployments";
|
4
|
-
import {
|
3
|
+
import { encodeFunctionData, encodePacked, getCreate2Address, keccak256, parseAbi, toHex, zeroAddress, } from "viem";
|
4
|
+
import { PLACEHOLDER_SIG, getClient, packGas, packPaymasterData, } from "../util";
|
5
5
|
/**
|
6
6
|
* All contracts used in account creation & execution
|
7
7
|
*/
|
8
8
|
export class ContractSuite {
|
9
|
-
|
9
|
+
// Used only for stateless contract reads.
|
10
|
+
dummyClient;
|
10
11
|
singleton;
|
11
12
|
proxyFactory;
|
12
13
|
m4337;
|
13
14
|
moduleSetup;
|
14
15
|
entryPoint;
|
15
|
-
constructor(
|
16
|
-
this.
|
16
|
+
constructor(client, singleton, proxyFactory, m4337, moduleSetup, entryPoint) {
|
17
|
+
this.dummyClient = client;
|
17
18
|
this.singleton = singleton;
|
18
19
|
this.proxyFactory = proxyFactory;
|
19
20
|
this.m4337 = m4337;
|
@@ -22,108 +23,154 @@ export class ContractSuite {
|
|
22
23
|
}
|
23
24
|
static async init() {
|
24
25
|
// TODO - this is a cheeky hack.
|
25
|
-
const
|
26
|
-
const safeDeployment = (fn) => getDeployment(fn, {
|
26
|
+
const client = getClient(11155111);
|
27
|
+
const safeDeployment = (fn) => getDeployment(fn, { version: "1.4.1" });
|
27
28
|
const m4337Deployment = async (fn) => {
|
28
|
-
return getDeployment(fn, {
|
29
|
+
return getDeployment(fn, { version: "0.3.0" });
|
29
30
|
};
|
30
|
-
|
31
|
-
const m4337 = await m4337Deployment(getSafe4337ModuleDeployment);
|
32
|
-
const [singleton, proxyFactory, moduleSetup, supportedEntryPoint] = await Promise.all([
|
31
|
+
const [singleton, proxyFactory, moduleSetup, m4337] = await Promise.all([
|
33
32
|
safeDeployment(getSafeL2SingletonDeployment),
|
34
33
|
safeDeployment(getProxyFactoryDeployment),
|
35
34
|
m4337Deployment(getSafeModuleSetupDeployment),
|
36
|
-
|
35
|
+
m4337Deployment(getSafe4337ModuleDeployment),
|
37
36
|
]);
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
37
|
+
// console.log("Initialized ERC4337 & Safe Module Contracts:", {
|
38
|
+
// singleton: await singleton.getAddress(),
|
39
|
+
// proxyFactory: await proxyFactory.getAddress(),
|
40
|
+
// m4337: await m4337.getAddress(),
|
41
|
+
// moduleSetup: await moduleSetup.getAddress(),
|
42
|
+
// entryPoint: await entryPoint.getAddress(),
|
43
|
+
// });
|
44
|
+
return new ContractSuite(client, singleton, proxyFactory, m4337, moduleSetup,
|
45
|
+
// EntryPoint:
|
46
|
+
{
|
47
|
+
address: (await client.readContract({
|
48
|
+
address: m4337.address,
|
49
|
+
abi: m4337.abi,
|
50
|
+
functionName: "SUPPORTED_ENTRYPOINT",
|
51
|
+
})),
|
52
|
+
abi: parseAbi([
|
53
|
+
"function getNonce(address, uint192 key) view returns (uint256 nonce)",
|
54
|
+
]),
|
45
55
|
});
|
46
|
-
return new ContractSuite(provider, singleton, proxyFactory, m4337, moduleSetup, entryPoint);
|
47
56
|
}
|
48
57
|
async addressForSetup(setup, saltNonce) {
|
49
58
|
// bytes32 salt = keccak256(abi.encodePacked(keccak256(initializer), saltNonce));
|
50
59
|
// cf: https://github.com/safe-global/safe-smart-account/blob/499b17ad0191b575fcadc5cb5b8e3faeae5391ae/contracts/proxies/SafeProxyFactory.sol#L58
|
51
|
-
const salt =
|
60
|
+
const salt = keccak256(encodePacked(["bytes32", "uint256"], [keccak256(setup), BigInt(saltNonce || "0")]));
|
52
61
|
// abi.encodePacked(type(SafeProxy).creationCode, uint256(uint160(_singleton)));
|
53
62
|
// cf: https://github.com/safe-global/safe-smart-account/blob/499b17ad0191b575fcadc5cb5b8e3faeae5391ae/contracts/proxies/SafeProxyFactory.sol#L29
|
54
|
-
const initCode =
|
55
|
-
await this.
|
56
|
-
|
63
|
+
const initCode = encodePacked(["bytes", "uint256"], [
|
64
|
+
(await this.dummyClient.readContract({
|
65
|
+
address: this.proxyFactory.address,
|
66
|
+
abi: this.proxyFactory.abi,
|
67
|
+
functionName: "proxyCreationCode",
|
68
|
+
})),
|
69
|
+
BigInt(this.singleton.address),
|
57
70
|
]);
|
58
|
-
return
|
71
|
+
return getCreate2Address({
|
72
|
+
from: this.proxyFactory.address,
|
73
|
+
salt,
|
74
|
+
bytecodeHash: keccak256(initCode),
|
75
|
+
});
|
59
76
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
77
|
+
getSetup(owners) {
|
78
|
+
return encodeFunctionData({
|
79
|
+
abi: this.singleton.abi,
|
80
|
+
functionName: "setup",
|
81
|
+
args: [
|
82
|
+
owners,
|
83
|
+
1, // We use sign threshold of 1.
|
84
|
+
this.moduleSetup.address,
|
85
|
+
encodeFunctionData({
|
86
|
+
abi: this.moduleSetup.abi,
|
87
|
+
functionName: "enableModules",
|
88
|
+
args: [[this.m4337.address]],
|
89
|
+
}),
|
90
|
+
this.m4337.address,
|
91
|
+
zeroAddress,
|
92
|
+
0,
|
93
|
+
zeroAddress,
|
94
|
+
],
|
95
|
+
});
|
96
|
+
}
|
97
|
+
addOwnerData(newOwner) {
|
98
|
+
return encodeFunctionData({
|
99
|
+
abi: this.singleton.abi,
|
100
|
+
functionName: "addOwnerWithThreshold",
|
101
|
+
args: [newOwner, 1],
|
102
|
+
});
|
74
103
|
}
|
75
104
|
async getOpHash(unsignedUserOp) {
|
76
105
|
const { factory, factoryData, verificationGasLimit, callGasLimit, maxPriorityFeePerGas, maxFeePerGas, } = unsignedUserOp;
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
106
|
+
const opHash = await this.dummyClient.readContract({
|
107
|
+
address: this.m4337.address,
|
108
|
+
abi: this.m4337.abi,
|
109
|
+
functionName: "getOperationHash",
|
110
|
+
args: [
|
111
|
+
{
|
112
|
+
...unsignedUserOp,
|
113
|
+
initCode: factory
|
114
|
+
? encodePacked(["address", "bytes"], [factory, factoryData])
|
115
|
+
: "0x",
|
116
|
+
accountGasLimits: packGas(verificationGasLimit, callGasLimit),
|
117
|
+
gasFees: packGas(maxPriorityFeePerGas, maxFeePerGas),
|
118
|
+
paymasterAndData: packPaymasterData(unsignedUserOp),
|
119
|
+
signature: PLACEHOLDER_SIG,
|
120
|
+
},
|
121
|
+
],
|
86
122
|
});
|
123
|
+
return opHash;
|
87
124
|
}
|
88
125
|
factoryDataForSetup(safeNotDeployed, setup, safeSaltNonce) {
|
89
126
|
return safeNotDeployed
|
90
127
|
? {
|
91
|
-
factory: this.proxyFactory.
|
92
|
-
factoryData:
|
128
|
+
factory: this.proxyFactory.address,
|
129
|
+
factoryData: encodeFunctionData({
|
130
|
+
abi: this.proxyFactory.abi,
|
131
|
+
functionName: "createProxyWithNonce",
|
132
|
+
args: [this.singleton.address, setup, safeSaltNonce],
|
133
|
+
}),
|
93
134
|
}
|
94
135
|
: {};
|
95
136
|
}
|
96
|
-
async buildUserOp(txData, safeAddress, feeData, setup, safeNotDeployed, safeSaltNonce) {
|
97
|
-
|
137
|
+
async buildUserOp(nonce, txData, safeAddress, feeData, setup, safeNotDeployed, safeSaltNonce) {
|
138
|
+
return {
|
98
139
|
sender: safeAddress,
|
99
|
-
nonce:
|
140
|
+
nonce: toHex(nonce),
|
100
141
|
...this.factoryDataForSetup(safeNotDeployed, setup, safeSaltNonce),
|
101
142
|
// <https://github.com/safe-global/safe-modules/blob/9a18245f546bf2a8ed9bdc2b04aae44f949ec7a0/modules/4337/contracts/Safe4337Module.sol#L172>
|
102
|
-
callData:
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
143
|
+
callData: encodeFunctionData({
|
144
|
+
abi: this.m4337.abi,
|
145
|
+
functionName: "executeUserOp",
|
146
|
+
args: [
|
147
|
+
txData.to,
|
148
|
+
BigInt(txData.value),
|
149
|
+
txData.data,
|
150
|
+
txData.operation || 0,
|
151
|
+
],
|
152
|
+
}),
|
108
153
|
...feeData,
|
109
154
|
};
|
110
|
-
|
155
|
+
}
|
156
|
+
async getNonce(address, chainId) {
|
157
|
+
const nonce = (await getClient(chainId).readContract({
|
158
|
+
abi: this.entryPoint.abi,
|
159
|
+
address: this.entryPoint.address,
|
160
|
+
functionName: "getNonce",
|
161
|
+
args: [address, 0],
|
162
|
+
}));
|
163
|
+
return nonce;
|
111
164
|
}
|
112
165
|
}
|
113
|
-
async function getDeployment(fn, {
|
114
|
-
const { chainId } = await provider.getNetwork();
|
166
|
+
async function getDeployment(fn, { version }) {
|
115
167
|
const deployment = fn({ version });
|
116
168
|
if (!deployment) {
|
117
|
-
throw new Error(`Deployment not found for ${fn.name} version ${version}
|
118
|
-
}
|
119
|
-
let address = deployment.networkAddresses[`${chainId}`];
|
120
|
-
if (!address) {
|
121
|
-
// console.warn(
|
122
|
-
// `Deployment asset ${fn.name} not listed on chainId ${chainId}, using likely fallback. For more info visit https://github.com/safe-global/safe-modules-deployments`
|
123
|
-
// );
|
124
|
-
// TODO: This is a cheeky hack. Real solution proposed in
|
125
|
-
// https://github.com/Mintbase/near-safe/issues/42
|
126
|
-
address = deployment.networkAddresses["11155111"];
|
169
|
+
throw new Error(`Deployment not found for ${fn.name} version ${version}`);
|
127
170
|
}
|
128
|
-
|
171
|
+
// TODO: maybe call parseAbi on deployment.abi here.
|
172
|
+
return {
|
173
|
+
address: deployment.networkAddresses["11155111"],
|
174
|
+
abi: deployment.abi,
|
175
|
+
};
|
129
176
|
}
|
package/dist/esm/tx-manager.d.ts
CHANGED
@@ -1,25 +1,27 @@
|
|
1
|
+
import { FinalExecutionOutcome } from "near-api-js/lib/providers";
|
1
2
|
import { NearEthAdapter, NearEthTxData, BaseTx } from "near-ca";
|
3
|
+
import { Address, Hash, Hex } from "viem";
|
2
4
|
import { Erc4337Bundler } from "./lib/bundler";
|
3
|
-
import { UserOperation, UserOperationReceipt } from "./types";
|
4
|
-
import { MetaTransaction } from "ethers-multisend";
|
5
5
|
import { ContractSuite } from "./lib/safe";
|
6
|
-
import {
|
6
|
+
import { MetaTransaction, UserOperation, UserOperationReceipt } from "./types";
|
7
7
|
export declare class TransactionManager {
|
8
8
|
readonly nearAdapter: NearEthAdapter;
|
9
9
|
readonly address: Address;
|
10
|
-
readonly entryPointAddress: Address;
|
11
10
|
private safePack;
|
12
11
|
private setup;
|
13
12
|
private pimlicoKey;
|
14
13
|
private safeSaltNonce;
|
15
14
|
private deployedChains;
|
16
|
-
constructor(nearAdapter: NearEthAdapter, safePack: ContractSuite, pimlicoKey: string, setup: string, safeAddress: Address,
|
15
|
+
constructor(nearAdapter: NearEthAdapter, safePack: ContractSuite, pimlicoKey: string, setup: string, safeAddress: Address, safeSaltNonce: string);
|
17
16
|
static create(config: {
|
17
|
+
accountId: string;
|
18
|
+
mpcContractId: string;
|
18
19
|
pimlicoKey: string;
|
19
|
-
|
20
|
+
privateKey?: string;
|
20
21
|
safeSaltNonce?: string;
|
21
22
|
}): Promise<TransactionManager>;
|
22
23
|
get mpcAddress(): Address;
|
24
|
+
get mpcContractId(): string;
|
23
25
|
getBalance(chainId: number): Promise<bigint>;
|
24
26
|
bundlerForChainId(chainId: number): Erc4337Bundler;
|
25
27
|
buildTransaction(args: {
|
@@ -32,6 +34,10 @@ export declare class TransactionManager {
|
|
32
34
|
encodeSignRequest(tx: BaseTx): Promise<NearEthTxData>;
|
33
35
|
executeTransaction(chainId: number, userOp: UserOperation): Promise<UserOperationReceipt>;
|
34
36
|
safeDeployed(chainId: number): Promise<boolean>;
|
35
|
-
addOwnerTx(address:
|
37
|
+
addOwnerTx(address: Address): MetaTransaction;
|
36
38
|
safeSufficientlyFunded(chainId: number, transactions: MetaTransaction[], gasCost: bigint): Promise<boolean>;
|
39
|
+
broadcastEvm(chainId: number, outcome: FinalExecutionOutcome, unsignedUserOp: UserOperation): Promise<{
|
40
|
+
signature: Hex;
|
41
|
+
receipt: UserOperationReceipt;
|
42
|
+
}>;
|
37
43
|
}
|
package/dist/esm/tx-manager.js
CHANGED
@@ -1,59 +1,65 @@
|
|
1
|
-
import {
|
1
|
+
import { setupAdapter, signatureFromOutcome, } from "near-ca";
|
2
|
+
import { serializeSignature } from "viem";
|
2
3
|
import { Erc4337Bundler } from "./lib/bundler";
|
3
|
-
import {
|
4
|
-
import { encodeMulti } from "ethers-multisend";
|
4
|
+
import { encodeMulti } from "./lib/multisend";
|
5
5
|
import { ContractSuite } from "./lib/safe";
|
6
|
+
import { getClient, isContract, packSignature } from "./util";
|
6
7
|
export class TransactionManager {
|
7
8
|
nearAdapter;
|
8
9
|
address;
|
9
|
-
entryPointAddress;
|
10
10
|
safePack;
|
11
11
|
setup;
|
12
12
|
pimlicoKey;
|
13
13
|
safeSaltNonce;
|
14
14
|
deployedChains;
|
15
|
-
constructor(nearAdapter, safePack, pimlicoKey, setup, safeAddress,
|
15
|
+
constructor(nearAdapter, safePack, pimlicoKey, setup, safeAddress, safeSaltNonce) {
|
16
16
|
this.nearAdapter = nearAdapter;
|
17
17
|
this.safePack = safePack;
|
18
18
|
this.pimlicoKey = pimlicoKey;
|
19
|
-
this.entryPointAddress = entryPointAddress;
|
20
19
|
this.setup = setup;
|
21
20
|
this.address = safeAddress;
|
22
21
|
this.safeSaltNonce = safeSaltNonce;
|
23
22
|
this.deployedChains = new Set();
|
24
23
|
}
|
25
24
|
static async create(config) {
|
26
|
-
const {
|
27
|
-
const safePack = await
|
25
|
+
const { pimlicoKey } = config;
|
26
|
+
const [nearAdapter, safePack] = await Promise.all([
|
27
|
+
setupAdapter({ ...config }),
|
28
|
+
ContractSuite.init(),
|
29
|
+
]);
|
28
30
|
console.log(`Near Adapter: ${nearAdapter.nearAccountId()} <> ${nearAdapter.address}`);
|
29
|
-
const setup =
|
31
|
+
const setup = safePack.getSetup([nearAdapter.address]);
|
30
32
|
const safeAddress = await safePack.addressForSetup(setup, config.safeSaltNonce);
|
31
|
-
const entryPointAddress = (await safePack.entryPoint.getAddress());
|
32
33
|
console.log(`Safe Address: ${safeAddress}`);
|
33
|
-
return new TransactionManager(nearAdapter, safePack, pimlicoKey, setup, safeAddress,
|
34
|
+
return new TransactionManager(nearAdapter, safePack, pimlicoKey, setup, safeAddress, config.safeSaltNonce || "0");
|
34
35
|
}
|
35
36
|
get mpcAddress() {
|
36
37
|
return this.nearAdapter.address;
|
37
38
|
}
|
39
|
+
get mpcContractId() {
|
40
|
+
return this.nearAdapter.mpcContract.contract.contractId;
|
41
|
+
}
|
38
42
|
async getBalance(chainId) {
|
39
|
-
|
40
|
-
return await provider.getBalance({ address: this.address });
|
43
|
+
return await getClient(chainId).getBalance({ address: this.address });
|
41
44
|
}
|
42
45
|
bundlerForChainId(chainId) {
|
43
|
-
return new Erc4337Bundler(this.
|
46
|
+
return new Erc4337Bundler(this.safePack.entryPoint.address, this.pimlicoKey, chainId);
|
44
47
|
}
|
45
48
|
async buildTransaction(args) {
|
46
49
|
const { transactions, usePaymaster, chainId } = args;
|
47
|
-
const bundler = this.bundlerForChainId(chainId);
|
48
|
-
const gasFees = (await bundler.getGasPrice()).fast;
|
49
|
-
// Build Singular MetaTransaction for Multisend from transaction list.
|
50
50
|
if (transactions.length === 0) {
|
51
51
|
throw new Error("Empty transaction set!");
|
52
52
|
}
|
53
|
+
const bundler = this.bundlerForChainId(chainId);
|
54
|
+
const [gasFees, nonce, safeDeployed] = await Promise.all([
|
55
|
+
bundler.getGasPrice(),
|
56
|
+
this.safePack.getNonce(this.address, chainId),
|
57
|
+
this.safeDeployed(chainId),
|
58
|
+
]);
|
59
|
+
// Build Singular MetaTransaction for Multisend from transaction list.
|
53
60
|
const tx = transactions.length > 1 ? encodeMulti(transactions) : transactions[0];
|
54
|
-
const
|
55
|
-
const
|
56
|
-
const paymasterData = await bundler.getPaymasterData(rawUserOp, usePaymaster, safeNotDeployed);
|
61
|
+
const rawUserOp = await this.safePack.buildUserOp(nonce, tx, this.address, gasFees.fast, this.setup, !safeDeployed, this.safeSaltNonce);
|
62
|
+
const paymasterData = await bundler.getPaymasterData(rawUserOp, usePaymaster, !safeDeployed);
|
57
63
|
const unsignedUserOp = { ...rawUserOp, ...paymasterData };
|
58
64
|
return unsignedUserOp;
|
59
65
|
}
|
@@ -98,11 +104,11 @@ export class TransactionManager {
|
|
98
104
|
return userOpReceipt;
|
99
105
|
}
|
100
106
|
async safeDeployed(chainId) {
|
107
|
+
// Early exit if already known.
|
101
108
|
if (chainId in this.deployedChains) {
|
102
109
|
return true;
|
103
110
|
}
|
104
|
-
const
|
105
|
-
const deployed = (await provider.getCode({ address: this.address })) !== "0x";
|
111
|
+
const deployed = await isContract(this.address, chainId);
|
106
112
|
if (deployed) {
|
107
113
|
this.deployedChains.add(chainId);
|
108
114
|
}
|
@@ -112,7 +118,7 @@ export class TransactionManager {
|
|
112
118
|
return {
|
113
119
|
to: this.address,
|
114
120
|
value: "0",
|
115
|
-
data: this.safePack.
|
121
|
+
data: this.safePack.addOwnerData(address),
|
116
122
|
};
|
117
123
|
}
|
118
124
|
async safeSufficientlyFunded(chainId, transactions, gasCost) {
|
@@ -123,4 +129,19 @@ export class TransactionManager {
|
|
123
129
|
const safeBalance = await this.getBalance(chainId);
|
124
130
|
return txValue + gasCost < safeBalance;
|
125
131
|
}
|
132
|
+
async broadcastEvm(chainId, outcome, unsignedUserOp) {
|
133
|
+
const signature = packSignature(serializeSignature(signatureFromOutcome(outcome)));
|
134
|
+
try {
|
135
|
+
return {
|
136
|
+
signature,
|
137
|
+
receipt: await this.executeTransaction(chainId, {
|
138
|
+
...unsignedUserOp,
|
139
|
+
signature,
|
140
|
+
}),
|
141
|
+
};
|
142
|
+
}
|
143
|
+
catch (error) {
|
144
|
+
throw new Error(`Failed EVM broadcast: ${error instanceof Error ? error.message : String(error)}`);
|
145
|
+
}
|
146
|
+
}
|
126
147
|
}
|
package/dist/esm/types.d.ts
CHANGED
@@ -79,4 +79,14 @@ export interface GasPrice {
|
|
79
79
|
maxFeePerGas: Hex;
|
80
80
|
maxPriorityFeePerGas: Hex;
|
81
81
|
}
|
82
|
+
export declare enum OperationType {
|
83
|
+
Call = 0,
|
84
|
+
DelegateCall = 1
|
85
|
+
}
|
86
|
+
export interface MetaTransaction {
|
87
|
+
readonly to: string;
|
88
|
+
readonly value: string;
|
89
|
+
readonly data: string;
|
90
|
+
readonly operation?: OperationType;
|
91
|
+
}
|
82
92
|
export {};
|
package/dist/esm/types.js
CHANGED
package/dist/esm/util.d.ts
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
import {
|
2
|
-
import { MetaTransaction } from "
|
3
|
-
import { Hex } from "viem";
|
1
|
+
import { Address, Hex, PublicClient } from "viem";
|
2
|
+
import { PaymasterData, MetaTransaction } from "./types";
|
4
3
|
export declare const PLACEHOLDER_SIG: `0x${string}`;
|
5
4
|
type IntLike = Hex | bigint | string | number;
|
6
5
|
export declare const packGas: (hi: IntLike, lo: IntLike) => string;
|
7
6
|
export declare function packSignature(signature: `0x${string}`, validFrom?: number, validTo?: number): Hex;
|
8
7
|
export declare function packPaymasterData(data: PaymasterData): Hex;
|
9
8
|
export declare function containsValue(transactions: MetaTransaction[]): boolean;
|
9
|
+
export declare function isContract(address: Address, chainId: number): Promise<boolean>;
|
10
|
+
export declare function getClient(chainId: number): PublicClient;
|
10
11
|
export {};
|
package/dist/esm/util.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
import {
|
1
|
+
import { Network } from "near-ca";
|
2
|
+
import { concatHex, encodePacked, toHex, } from "viem";
|
2
3
|
export const PLACEHOLDER_SIG = encodePacked(["uint48", "uint48"], [0, 0]);
|
3
4
|
export const packGas = (hi, lo) => encodePacked(["uint128", "uint128"], [BigInt(hi), BigInt(lo)]);
|
4
5
|
export function packSignature(signature, validFrom = 0, validTo = 0) {
|
@@ -17,3 +18,9 @@ export function packPaymasterData(data) {
|
|
17
18
|
export function containsValue(transactions) {
|
18
19
|
return transactions.some((tx) => tx.value !== "0");
|
19
20
|
}
|
21
|
+
export async function isContract(address, chainId) {
|
22
|
+
return (await getClient(chainId).getCode({ address })) !== undefined;
|
23
|
+
}
|
24
|
+
export function getClient(chainId) {
|
25
|
+
return Network.fromChainId(chainId).client;
|
26
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "near-safe",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.3.0",
|
4
4
|
"license": "MIT",
|
5
5
|
"description": "An SDK for controlling Ethereum Smart Accounts via ERC4337 from a Near Account.",
|
6
6
|
"author": "bh2smith",
|
@@ -36,18 +36,15 @@
|
|
36
36
|
"example": "tsx examples/send-tx.ts",
|
37
37
|
"lint": "eslint . --ignore-pattern dist/",
|
38
38
|
"test": "jest",
|
39
|
-
"fmt": "prettier --write '{src,examples,tests}/**/*.{js,jsx,ts,tsx}'",
|
39
|
+
"fmt": "prettier --write '{src,examples,tests}/**/*.{js,jsx,ts,tsx}' && yarn lint --fix",
|
40
40
|
"all": "yarn fmt && yarn lint && yarn build"
|
41
41
|
},
|
42
42
|
"dependencies": {
|
43
43
|
"@safe-global/safe-deployments": "^1.37.0",
|
44
44
|
"@safe-global/safe-modules-deployments": "^2.2.0",
|
45
|
-
"ethers": "^6.13.1",
|
46
|
-
"ethers-multisend": "^3.1.0",
|
47
45
|
"near-api-js": "^5.0.0",
|
48
46
|
"near-ca": "^0.5.2",
|
49
|
-
"viem": "^2.16.5"
|
50
|
-
"yargs": "^17.7.2"
|
47
|
+
"viem": "^2.16.5"
|
51
48
|
},
|
52
49
|
"devDependencies": {
|
53
50
|
"@types/jest": "^29.5.12",
|
@@ -57,11 +54,17 @@
|
|
57
54
|
"@typescript-eslint/parser": "^8.1.0",
|
58
55
|
"dotenv": "^16.4.5",
|
59
56
|
"eslint": "^9.6.0",
|
57
|
+
"eslint-plugin-import": "^2.30.0",
|
58
|
+
"ethers": "^6.13.1",
|
60
59
|
"jest": "^29.7.0",
|
61
60
|
"prettier": "^3.3.2",
|
62
61
|
"ts-jest": "^29.1.5",
|
63
62
|
"tsx": "^4.16.0",
|
64
63
|
"typescript": "^5.5.2",
|
65
64
|
"yargs": "^17.7.2"
|
65
|
+
},
|
66
|
+
"resolutions": {
|
67
|
+
"glob": "^9.0.0",
|
68
|
+
"base-x": "^3.0.0"
|
66
69
|
}
|
67
70
|
}
|