@funkit/core 0.8.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 +110 -0
- package/dist/fetch-polyfill.d.ts +1 -0
- package/dist/fetch-polyfill.js +35 -0
- package/dist/fetch-polyfill.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/src/abis/ApproveAndExec.json +1 -0
- package/dist/src/abis/ApproveAndSwap.json +1 -0
- package/dist/src/abis/ERC20.json +1 -0
- package/dist/src/abis/ERC721.json +1 -0
- package/dist/src/abis/EntryPoint.json +1 -0
- package/dist/src/abis/EstimationPaymaster.json +1 -0
- package/dist/src/abis/FeePercentOracle.json +1 -0
- package/dist/src/abis/FunWallet.json +1 -0
- package/dist/src/abis/FunWalletFactory.json +1 -0
- package/dist/src/abis/GaslessPaymaster.json +1 -0
- package/dist/src/abis/LidoWithdrawQueue.json +1 -0
- package/dist/src/abis/RoleBasedAccessControl.json +1 -0
- package/dist/src/abis/TestNFT.json +1 -0
- package/dist/src/abis/TokenPaymaster.json +1 -0
- package/dist/src/abis/TokenPriceOracle.json +1 -0
- package/dist/src/abis/UniswapV2Factory.json +1 -0
- package/dist/src/abis/UniswapV2Router02.json +1 -0
- package/dist/src/abis/UniswapV3LimitOrder.json +1 -0
- package/dist/src/abis/UserAuthentication.json +1 -0
- package/dist/src/abis/univ3factory.json +1 -0
- package/dist/src/abis/univ3quoter.json +1 -0
- package/dist/src/abis/univ3router.json +1 -0
- package/dist/src/actions/AccessControl.d.ts +9 -0
- package/dist/src/actions/AccessControl.js +88 -0
- package/dist/src/actions/AccessControl.js.map +1 -0
- package/dist/src/actions/BatchActions.d.ts +3 -0
- package/dist/src/actions/BatchActions.js +12 -0
- package/dist/src/actions/BatchActions.js.map +1 -0
- package/dist/src/actions/FirstClassActions.d.ts +161 -0
- package/dist/src/actions/FirstClassActions.js +347 -0
- package/dist/src/actions/FirstClassActions.js.map +1 -0
- package/dist/src/actions/Group.d.ts +6 -0
- package/dist/src/actions/Group.js +44 -0
- package/dist/src/actions/Group.js.map +1 -0
- package/dist/src/actions/LimitOrder.d.ts +4 -0
- package/dist/src/actions/LimitOrder.js +45 -0
- package/dist/src/actions/LimitOrder.js.map +1 -0
- package/dist/src/actions/Stake.d.ts +8 -0
- package/dist/src/actions/Stake.js +124 -0
- package/dist/src/actions/Stake.js.map +1 -0
- package/dist/src/actions/Swap.d.ts +9 -0
- package/dist/src/actions/Swap.js +169 -0
- package/dist/src/actions/Swap.js.map +1 -0
- package/dist/src/actions/Token.d.ts +12 -0
- package/dist/src/actions/Token.js +102 -0
- package/dist/src/actions/Token.js.map +1 -0
- package/dist/src/actions/index.d.ts +7 -0
- package/dist/src/actions/index.js +24 -0
- package/dist/src/actions/index.js.map +1 -0
- package/dist/src/actions/types.d.ts +117 -0
- package/dist/src/actions/types.js +11 -0
- package/dist/src/actions/types.js.map +1 -0
- package/dist/src/apis/AccessControlApis.d.ts +5 -0
- package/dist/src/apis/AccessControlApis.js +22 -0
- package/dist/src/apis/AccessControlApis.js.map +1 -0
- package/dist/src/apis/AssetApis.d.ts +79 -0
- package/dist/src/apis/AssetApis.js +100 -0
- package/dist/src/apis/AssetApis.js.map +1 -0
- package/dist/src/apis/ContractApis.d.ts +1 -0
- package/dist/src/apis/ContractApis.js +11 -0
- package/dist/src/apis/ContractApis.js.map +1 -0
- package/dist/src/apis/GroupApis.d.ts +8 -0
- package/dist/src/apis/GroupApis.js +45 -0
- package/dist/src/apis/GroupApis.js.map +1 -0
- package/dist/src/apis/InfoApis.d.ts +6 -0
- package/dist/src/apis/InfoApis.js +59 -0
- package/dist/src/apis/InfoApis.js.map +1 -0
- package/dist/src/apis/ListenerApis.d.ts +3 -0
- package/dist/src/apis/ListenerApis.js +36 -0
- package/dist/src/apis/ListenerApis.js.map +1 -0
- package/dist/src/apis/NFTApis.d.ts +22 -0
- package/dist/src/apis/NFTApis.js +34 -0
- package/dist/src/apis/NFTApis.js.map +1 -0
- package/dist/src/apis/OnOffRampApis.d.ts +2 -0
- package/dist/src/apis/OnOffRampApis.js +23 -0
- package/dist/src/apis/OnOffRampApis.js.map +1 -0
- package/dist/src/apis/OnOffRampUtils.d.ts +2 -0
- package/dist/src/apis/OnOffRampUtils.js +23 -0
- package/dist/src/apis/OnOffRampUtils.js.map +1 -0
- package/dist/src/apis/OperationApis.d.ts +14 -0
- package/dist/src/apis/OperationApis.js +77 -0
- package/dist/src/apis/OperationApis.js.map +1 -0
- package/dist/src/apis/PaymasterApis.d.ts +15 -0
- package/dist/src/apis/PaymasterApis.js +89 -0
- package/dist/src/apis/PaymasterApis.js.map +1 -0
- package/dist/src/apis/UserApis.d.ts +12 -0
- package/dist/src/apis/UserApis.js +77 -0
- package/dist/src/apis/UserApis.js.map +1 -0
- package/dist/src/apis/index.d.ts +10 -0
- package/dist/src/apis/index.js +27 -0
- package/dist/src/apis/index.js.map +1 -0
- package/dist/src/apis/types.d.ts +49 -0
- package/dist/src/apis/types.js +3 -0
- package/dist/src/apis/types.js.map +1 -0
- package/dist/src/auth/Auth.d.ts +81 -0
- package/dist/src/auth/Auth.js +317 -0
- package/dist/src/auth/Auth.js.map +1 -0
- package/dist/src/auth/SessionKeyAuth.d.ts +19 -0
- package/dist/src/auth/SessionKeyAuth.js +118 -0
- package/dist/src/auth/SessionKeyAuth.js.map +1 -0
- package/dist/src/auth/index.d.ts +2 -0
- package/dist/src/auth/index.js +19 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/auth/types.d.ts +20 -0
- package/dist/src/auth/types.js +3 -0
- package/dist/src/auth/types.js.map +1 -0
- package/dist/src/common/constants.d.ts +1072 -0
- package/dist/src/common/constants.js +153 -0
- package/dist/src/common/constants.js.map +1 -0
- package/dist/src/common/index.d.ts +2 -0
- package/dist/src/common/index.js +19 -0
- package/dist/src/common/index.js.map +1 -0
- package/dist/src/common/types.d.ts +32 -0
- package/dist/src/common/types.js +3 -0
- package/dist/src/common/types.js.map +1 -0
- package/dist/src/config/Config.d.ts +3 -0
- package/dist/src/config/Config.js +46 -0
- package/dist/src/config/Config.js.map +1 -0
- package/dist/src/config/index.d.ts +2 -0
- package/dist/src/config/index.js +19 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/types.d.ts +21 -0
- package/dist/src/config/types.js +3 -0
- package/dist/src/config/types.js.map +1 -0
- package/dist/src/data/Chain.d.ts +29 -0
- package/dist/src/data/Chain.js +174 -0
- package/dist/src/data/Chain.js.map +1 -0
- package/dist/src/data/NFT.d.ts +24 -0
- package/dist/src/data/NFT.js +104 -0
- package/dist/src/data/NFT.js.map +1 -0
- package/dist/src/data/Operation.d.ts +33 -0
- package/dist/src/data/Operation.js +68 -0
- package/dist/src/data/Operation.js.map +1 -0
- package/dist/src/data/SolidityData.d.ts +8 -0
- package/dist/src/data/SolidityData.js +72 -0
- package/dist/src/data/SolidityData.js.map +1 -0
- package/dist/src/data/Token.d.ts +26 -0
- package/dist/src/data/Token.js +122 -0
- package/dist/src/data/Token.js.map +1 -0
- package/dist/src/data/index.d.ts +6 -0
- package/dist/src/data/index.js +23 -0
- package/dist/src/data/index.js.map +1 -0
- package/dist/src/data/types.d.ts +112 -0
- package/dist/src/data/types.js +25 -0
- package/dist/src/data/types.js.map +1 -0
- package/dist/src/errors/BaseError.d.ts +9 -0
- package/dist/src/errors/BaseError.js +23 -0
- package/dist/src/errors/BaseError.js.map +1 -0
- package/dist/src/errors/ClientError.d.ts +22 -0
- package/dist/src/errors/ClientError.js +75 -0
- package/dist/src/errors/ClientError.js.map +1 -0
- package/dist/src/errors/ServerError.d.ts +7 -0
- package/dist/src/errors/ServerError.js +18 -0
- package/dist/src/errors/ServerError.js.map +1 -0
- package/dist/src/errors/index.d.ts +4 -0
- package/dist/src/errors/index.js +21 -0
- package/dist/src/errors/index.js.map +1 -0
- package/dist/src/errors/types.d.ts +54 -0
- package/dist/src/errors/types.js +45 -0
- package/dist/src/errors/types.js.map +1 -0
- package/dist/src/sponsors/GaslessSponsor.d.ts +19 -0
- package/dist/src/sponsors/GaslessSponsor.js +91 -0
- package/dist/src/sponsors/GaslessSponsor.js.map +1 -0
- package/dist/src/sponsors/Sponsor.d.ts +31 -0
- package/dist/src/sponsors/Sponsor.js +94 -0
- package/dist/src/sponsors/Sponsor.js.map +1 -0
- package/dist/src/sponsors/TokenSponsor.d.ts +40 -0
- package/dist/src/sponsors/TokenSponsor.js +271 -0
- package/dist/src/sponsors/TokenSponsor.js.map +1 -0
- package/dist/src/sponsors/index.d.ts +3 -0
- package/dist/src/sponsors/index.js +20 -0
- package/dist/src/sponsors/index.js.map +1 -0
- package/dist/src/sponsors/types.d.ts +9 -0
- package/dist/src/sponsors/types.js +10 -0
- package/dist/src/sponsors/types.js.map +1 -0
- package/dist/src/utils/ApiUtils.d.ts +19 -0
- package/dist/src/utils/ApiUtils.js +97 -0
- package/dist/src/utils/ApiUtils.js.map +1 -0
- package/dist/src/utils/AuthUtils.d.ts +4 -0
- package/dist/src/utils/AuthUtils.js +54 -0
- package/dist/src/utils/AuthUtils.js.map +1 -0
- package/dist/src/utils/ChainUtils.d.ts +12 -0
- package/dist/src/utils/ChainUtils.js +89 -0
- package/dist/src/utils/ChainUtils.js.map +1 -0
- package/dist/src/utils/MerkleUtils.d.ts +18 -0
- package/dist/src/utils/MerkleUtils.js +96 -0
- package/dist/src/utils/MerkleUtils.js.map +1 -0
- package/dist/src/utils/PaymasterUtils.d.ts +3 -0
- package/dist/src/utils/PaymasterUtils.js +17 -0
- package/dist/src/utils/PaymasterUtils.js.map +1 -0
- package/dist/src/utils/SwapUtils.d.ts +35 -0
- package/dist/src/utils/SwapUtils.js +193 -0
- package/dist/src/utils/SwapUtils.js.map +1 -0
- package/dist/src/utils/TypeUtils.d.ts +1 -0
- package/dist/src/utils/TypeUtils.js +13 -0
- package/dist/src/utils/TypeUtils.js.map +1 -0
- package/dist/src/utils/UserOpUtils.d.ts +12 -0
- package/dist/src/utils/UserOpUtils.js +166 -0
- package/dist/src/utils/UserOpUtils.js.map +1 -0
- package/dist/src/utils/ViemUtils.d.ts +9 -0
- package/dist/src/utils/ViemUtils.js +30 -0
- package/dist/src/utils/ViemUtils.js.map +1 -0
- package/dist/src/utils/WalletUtils.d.ts +11 -0
- package/dist/src/utils/WalletUtils.js +61 -0
- package/dist/src/utils/WalletUtils.js.map +1 -0
- package/dist/src/utils/index.d.ts +7 -0
- package/dist/src/utils/index.js +24 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/viem/ContractInterface.d.ts +19 -0
- package/dist/src/viem/ContractInterface.js +88 -0
- package/dist/src/viem/ContractInterface.js.map +1 -0
- package/dist/src/viem/Converter.d.ts +1770 -0
- package/dist/src/viem/Converter.js +50 -0
- package/dist/src/viem/Converter.js.map +1 -0
- package/dist/src/viem/index.d.ts +2 -0
- package/dist/src/viem/index.js +19 -0
- package/dist/src/viem/index.js.map +1 -0
- package/dist/src/wallet/FunWallet.d.ts +185 -0
- package/dist/src/wallet/FunWallet.js +720 -0
- package/dist/src/wallet/FunWallet.js.map +1 -0
- package/dist/src/wallet/index.d.ts +2 -0
- package/dist/src/wallet/index.js +19 -0
- package/dist/src/wallet/index.js.map +1 -0
- package/dist/src/wallet/types.d.ts +13 -0
- package/dist/src/wallet/types.js +3 -0
- package/dist/src/wallet/types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,720 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FunWallet = void 0;
|
|
4
|
+
const viem_1 = require("viem");
|
|
5
|
+
const FirstClassActions_1 = require("../actions/FirstClassActions");
|
|
6
|
+
const apis_1 = require("../apis");
|
|
7
|
+
const AccessControlApis_1 = require("../apis/AccessControlApis");
|
|
8
|
+
const GroupApis_1 = require("../apis/GroupApis");
|
|
9
|
+
const OperationApis_1 = require("../apis/OperationApis");
|
|
10
|
+
const PaymasterApis_1 = require("../apis/PaymasterApis");
|
|
11
|
+
const UserApis_1 = require("../apis/UserApis");
|
|
12
|
+
const common_1 = require("../common");
|
|
13
|
+
const constants_1 = require("../common/constants");
|
|
14
|
+
const config_1 = require("../config");
|
|
15
|
+
const data_1 = require("../data");
|
|
16
|
+
const errors_1 = require("../errors");
|
|
17
|
+
const sponsors_1 = require("../sponsors");
|
|
18
|
+
const utils_1 = require("../utils");
|
|
19
|
+
const PaymasterUtils_1 = require("../utils/PaymasterUtils");
|
|
20
|
+
const TypeUtils_1 = require("../utils/TypeUtils");
|
|
21
|
+
class FunWallet extends FirstClassActions_1.FirstClassActions {
|
|
22
|
+
/**
|
|
23
|
+
* Creates FunWallet object
|
|
24
|
+
* @constructor
|
|
25
|
+
* @param {object} params - The parameters for the constructing fun wallet - (users, uniqueId) or walletAddr
|
|
26
|
+
*/
|
|
27
|
+
constructor(params) {
|
|
28
|
+
super();
|
|
29
|
+
if (typeof params === "string") {
|
|
30
|
+
if ((0, viem_1.isAddress)(params)) {
|
|
31
|
+
this.address = params;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InvalidParameter, "string input must be an address type", params, "Provide either (uniqueId, users) or walletAddr when constructing a FunWallet", "https://docs.fun.xyz/how-to-guides/execute-transactions/create-funwallet#create-funwallet-manual-funwallet-creation");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const { users, uniqueId } = params;
|
|
39
|
+
if (!uniqueId || !(0, TypeUtils_1.isBytes32)(uniqueId) || !users || users.length <= 0) {
|
|
40
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InvalidParameter, "uniqueId must be bytes32 and users must be non-empty", params, "The uniqueId field should be a 32 byte Hexstring and the users field should be an array of User objects", "https://docs.fun.xyz/how-to-guides/execute-transactions/create-funwallet#create-funwallet-manual-funwallet-creation");
|
|
41
|
+
}
|
|
42
|
+
this.userInfo = new Map(users?.map((user) => {
|
|
43
|
+
if (!user.userId || !(0, viem_1.isHex)(user.userId)) {
|
|
44
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InvalidParameter, "userId is required and must be a hex string", users, "Provide hex string userId when creating a FunWallet", "https://docs.fun.xyz/how-to-guides/execute-transactions/create-funwallet#create-funwallet-manual-funwallet-creation");
|
|
45
|
+
}
|
|
46
|
+
if (user.groupInfo &&
|
|
47
|
+
(!Number.isInteger(user.groupInfo.threshold) ||
|
|
48
|
+
!Array.isArray(user.groupInfo.memberIds) ||
|
|
49
|
+
!user.groupInfo.memberIds.every((memberId) => (0, viem_1.isHex)(memberId)))) {
|
|
50
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InvalidParameter, "groupInfo must be an object with threshold as integer and memberIds as array of hex strings", users, "Provide valid groupInfo when creating a FunWallet", "https://docs.fun.xyz/how-to-guides/execute-transactions/create-funwallet#create-funwallet-manual-funwallet-creation");
|
|
51
|
+
}
|
|
52
|
+
return [(0, viem_1.pad)(user.userId, { size: 32 }), user];
|
|
53
|
+
}));
|
|
54
|
+
this.walletUniqueId = uniqueId;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Retrieves the wallet address associated with this FunWallet. The address should be the same for all EVM chains so no input is needed
|
|
59
|
+
* If the address is not already cached, it fetches it using the wallet's unique ID and chain information.
|
|
60
|
+
* @returns {Promise<Address>} The wallet address.
|
|
61
|
+
*/
|
|
62
|
+
async getAddress() {
|
|
63
|
+
if (!this.address) {
|
|
64
|
+
this.address = await (0, utils_1.getWalletAddress)(await data_1.Chain.getChain({ chainIdentifier: 137 }), this.walletUniqueId);
|
|
65
|
+
}
|
|
66
|
+
return this.address;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves the wallet address associated with the provided unique ID using the given API key.
|
|
70
|
+
* @param {string} uniqueId - The unique ID of the wallet.
|
|
71
|
+
* @param {string} apiKey - The API key to access the required resources.
|
|
72
|
+
* @returns {Promise<Address>} The wallet address.
|
|
73
|
+
*/
|
|
74
|
+
static async getAddress(uniqueId, apiKey) {
|
|
75
|
+
;
|
|
76
|
+
globalThis.globalEnvOption.apiKey = apiKey;
|
|
77
|
+
return await (0, utils_1.getWalletAddress)(await data_1.Chain.getChain({ chainIdentifier: 137 }), (0, viem_1.keccak256)((0, viem_1.toBytes)(uniqueId)));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Retrieves the wallet address associated with the provided unique ID in an offline environment.
|
|
81
|
+
* @param {string} uniqueId - The unique ID of the wallet.
|
|
82
|
+
* @param {string} rpcUrl - The URL of the RPC endpoint for offline querying.
|
|
83
|
+
* @param {Address} factoryAddress - The address of the factory contract.
|
|
84
|
+
* @returns {Promise<Address>} The wallet address.
|
|
85
|
+
*/
|
|
86
|
+
static async getAddressOffline(uniqueId, rpcUrl, factoryAddress) {
|
|
87
|
+
const client = await (0, viem_1.createPublicClient)({
|
|
88
|
+
transport: (0, viem_1.http)(rpcUrl)
|
|
89
|
+
});
|
|
90
|
+
return await constants_1.FACTORY_CONTRACT_INTERFACE.readFromChain(factoryAddress, "getAddress", [(0, viem_1.keccak256)((0, viem_1.toBytes)(uniqueId))], client);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get all tokens for a specific chain
|
|
94
|
+
* @param {string} chainId string version of the chainId or ALL. If empty, then default to the one in globalEnvOption
|
|
95
|
+
* @param {string} onlyVerifiedTokens If true, only return alchemy tokens that are verified(filters spam) - defaults to false
|
|
96
|
+
* @returns JSON
|
|
97
|
+
*/
|
|
98
|
+
async getTokens(chainIdInput, onlyVerifiedTokens = false) {
|
|
99
|
+
let chainId;
|
|
100
|
+
if (!chainIdInput) {
|
|
101
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: globalThis.globalEnvOption.chain });
|
|
102
|
+
chainId = await chain.getChainId();
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
chainId = chainIdInput;
|
|
106
|
+
}
|
|
107
|
+
if (chainId === "ALL") {
|
|
108
|
+
return await (0, apis_1.getAllTokens)(await this.getAddress(), onlyVerifiedTokens);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
return await (0, apis_1.getTokens)(chainId, await this.getAddress(), onlyVerifiedTokens);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Given an address and a chain, returns all NFTs owned by that address
|
|
116
|
+
* @param {string} chainId string version of the chainId or ALL. If empty, then default to the one in globalEnvOption
|
|
117
|
+
* @returns array
|
|
118
|
+
*/
|
|
119
|
+
async getNFTs(chainIdInput) {
|
|
120
|
+
let chainId;
|
|
121
|
+
if (!chainIdInput) {
|
|
122
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: globalThis.globalEnvOption.chain });
|
|
123
|
+
chainId = await chain.getChainId();
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
chainId = chainIdInput;
|
|
127
|
+
}
|
|
128
|
+
if (chainId === "ALL") {
|
|
129
|
+
return await (0, apis_1.getAllNFTs)(await this.getAddress());
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
return await (0, apis_1.getNFTs)(chainId, await this.getAddress());
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Get all tokens on all supported chains. Merge tokens by symbol
|
|
137
|
+
* @param {string} chainIdInput string version of the chainId or ALL. If empty, then default to the one in globalEnvOption
|
|
138
|
+
* @param {*} onlyVerifiedTokens true if you want to filter out spam tokens(Uses alchemy lists)
|
|
139
|
+
* @param {boolean} checkStatus true if you want to check if the address has any pending lido withdrawals
|
|
140
|
+
* @returns JSON of all tokens owned by address
|
|
141
|
+
*/
|
|
142
|
+
async getAssets(chainIdInput, onlyVerifiedTokens = false, checkStatus = false) {
|
|
143
|
+
let chainId;
|
|
144
|
+
if (!chainIdInput) {
|
|
145
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: globalThis.globalEnvOption.chain });
|
|
146
|
+
chainId = await chain.getChainId();
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
chainId = chainIdInput;
|
|
150
|
+
}
|
|
151
|
+
let tokens = {}, nfts = {}, lidoWithdrawals = {};
|
|
152
|
+
if (chainId === "ALL") {
|
|
153
|
+
tokens = await (0, apis_1.getAllTokens)(await this.getAddress(), onlyVerifiedTokens);
|
|
154
|
+
nfts = await (0, apis_1.getAllNFTs)(await this.getAddress());
|
|
155
|
+
if (checkStatus) {
|
|
156
|
+
const ethMainnetLidoWithdrawals = await (0, apis_1.getLidoWithdrawals)("1", await this.getAddress());
|
|
157
|
+
const goerliLidoWithdrawals = await (0, apis_1.getLidoWithdrawals)("5", await this.getAddress());
|
|
158
|
+
lidoWithdrawals = { ...ethMainnetLidoWithdrawals, ...goerliLidoWithdrawals };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
tokens = await (0, apis_1.getTokens)(chainId, await this.getAddress(), onlyVerifiedTokens);
|
|
163
|
+
nfts = await (0, apis_1.getNFTs)(chainId, await this.getAddress());
|
|
164
|
+
if (checkStatus) {
|
|
165
|
+
lidoWithdrawals = await (0, apis_1.getLidoWithdrawals)(chainId, await this.getAddress());
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { ...lidoWithdrawals, ...tokens, ...nfts };
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Retrieves the nonce value for the specified sender address and nonce key.
|
|
172
|
+
* If the nonce is unavailable, a random nonce key is generated and returned as the nonce.
|
|
173
|
+
* @param {string} sender - The sender's address.
|
|
174
|
+
* @param {string} key - The nonce key (default: randomly generated).
|
|
175
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
176
|
+
* @returns {Promise<bigint>} The nonce value.
|
|
177
|
+
*/
|
|
178
|
+
async getNonce(sender, key = (0, utils_1.generateRandomNonceKey)(), txOptions = globalThis.globalEnvOption) {
|
|
179
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
180
|
+
const entryPointAddress = await chain.getAddress("entryPointAddress");
|
|
181
|
+
let nonce = undefined;
|
|
182
|
+
let retryCount = 3;
|
|
183
|
+
while ((nonce === undefined || nonce === null) && retryCount > 0) {
|
|
184
|
+
nonce = await common_1.ENTRYPOINT_CONTRACT_INTERFACE.readFromChain(entryPointAddress, "getNonce", [sender, key], chain);
|
|
185
|
+
retryCount--;
|
|
186
|
+
}
|
|
187
|
+
if (nonce !== undefined && nonce !== null) {
|
|
188
|
+
return BigInt(nonce);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
return BigInt(key << 64n);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Retrieves a list of operations associated with the wallet.
|
|
196
|
+
* @param {OperationStatus} status - The status of operations to retrieve (default: OperationStatus.ALL).
|
|
197
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
198
|
+
* @returns {Promise<Operation[]>} A list of operations.
|
|
199
|
+
*/
|
|
200
|
+
async getOperations(status = data_1.OperationStatus.ALL, txOptions = globalThis.globalEnvOption) {
|
|
201
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
202
|
+
return await (0, OperationApis_1.getOpsOfWallet)(await this.getAddress(), await chain.getChainId(), status);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Retrieves a specific operation by its ID.
|
|
206
|
+
* @param {Hex} opId - The ID of the operation to retrieve.
|
|
207
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
208
|
+
* @returns {Promise<Operation>} The requested operation.
|
|
209
|
+
*/
|
|
210
|
+
async getOperation(opId, txOptions = globalThis.globalEnvOption) {
|
|
211
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
212
|
+
return (await (0, OperationApis_1.getOps)([opId], await chain.getChainId()))[0];
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Retrieves a list of users associated with the wallet and their potential corresponding group information.
|
|
216
|
+
* @param {Auth} auth - The authentication instance for retrieving user information.
|
|
217
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
218
|
+
* @returns {Promise<User[]>} A list of users with their group information.
|
|
219
|
+
*/
|
|
220
|
+
async getUsers(auth, txOptions = globalThis.globalEnvOption) {
|
|
221
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
222
|
+
const storedUserIds = await auth.getUserIds(await this.getAddress(), await chain.getChainId());
|
|
223
|
+
const userIds = new Set([...storedUserIds]);
|
|
224
|
+
if (this.userInfo) {
|
|
225
|
+
for (const userId of this.userInfo.keys()) {
|
|
226
|
+
userIds.add(userId);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const users = [];
|
|
230
|
+
const groupIds = [];
|
|
231
|
+
for (const userId of userIds) {
|
|
232
|
+
if ((0, viem_1.pad)(userId, { size: 32 }) === (await auth.getUserId())) {
|
|
233
|
+
users.push({ userId: (0, viem_1.pad)(userId, { size: 32 }) });
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
groupIds.push((0, viem_1.pad)(userId, { size: 32 }));
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (groupIds && groupIds.length > 0) {
|
|
240
|
+
const groups = await (0, GroupApis_1.getGroups)(groupIds, await chain.getChainId());
|
|
241
|
+
groups.forEach((group) => {
|
|
242
|
+
users.push({
|
|
243
|
+
userId: group.groupId,
|
|
244
|
+
groupInfo: {
|
|
245
|
+
threshold: group.threshold,
|
|
246
|
+
memberIds: group.memberIds
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
return users;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Checks the deployment status of the wallet's address to determine if it's a contract.
|
|
255
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
256
|
+
* @returns {Promise<boolean>} `true` if the address is a contract, `false` otherwise.
|
|
257
|
+
*/
|
|
258
|
+
async getDeploymentStatus(txOptions = globalThis.globalEnvOption) {
|
|
259
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
260
|
+
return await chain.addressIsContract(await this.getAddress());
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Creates the wallet.
|
|
264
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
265
|
+
* @param {string} userId - The ID of the user initiating the operation.
|
|
266
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
267
|
+
* @returns {Promise<Operation>} The operation to create the wallet.
|
|
268
|
+
*/
|
|
269
|
+
async create(auth, userId, txOptions = globalThis.globalEnvOption) {
|
|
270
|
+
const transactionParams = { to: await this.getAddress(), data: "0x", value: 0n };
|
|
271
|
+
return await this.createOperation(auth, userId, transactionParams, txOptions);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Generates an on-ramp URL for the account address.
|
|
275
|
+
* @param {Address} address - The account address (optional, defaults to the wallet's address).
|
|
276
|
+
* @returns {Promise<string>} The on-ramp URL.
|
|
277
|
+
*/
|
|
278
|
+
async onRamp(address) {
|
|
279
|
+
return await (0, apis_1.getOnRampUrl)(address ? address : await this.getAddress());
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Generates an off-ramp URL for the account address.
|
|
283
|
+
* @param {Address} address - The account address (optional, defaults to the wallet's address).
|
|
284
|
+
* @returns {Promise<string>} The off-ramp URL.
|
|
285
|
+
*/
|
|
286
|
+
async offRamp(address) {
|
|
287
|
+
return await (0, apis_1.getOffRampUrl)(address ? address : await this.getAddress());
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Creates a new operation to be associated with the wallet and prepares it for execution.
|
|
291
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
292
|
+
* @param {string} userId - The ID of the user initiating the operation.
|
|
293
|
+
* @param {TransactionParams} transactionParams - The parameters for the transaction.
|
|
294
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
295
|
+
* @returns {Promise<Operation>} The created and prepared operation.
|
|
296
|
+
*/
|
|
297
|
+
async createOperation(auth, userId, transactionParams, txOptions = globalThis.globalEnvOption) {
|
|
298
|
+
if (!userId || userId === "") {
|
|
299
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.MissingParameter, "userId is required", { userId: userId }, "Provide userId when createOperation", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
300
|
+
}
|
|
301
|
+
userId = (0, viem_1.pad)(userId, { size: 32 });
|
|
302
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
303
|
+
const sender = await this.getAddress();
|
|
304
|
+
const initCode = (await chain.addressIsContract(sender)) ? "0x" : await this.getThisInitCode(chain);
|
|
305
|
+
let paymasterAndData = "0x";
|
|
306
|
+
let maxFeePerGas, maxPriorityFeePerGas;
|
|
307
|
+
const chainId = await chain.getChainId();
|
|
308
|
+
const OPStackChains = ["10"];
|
|
309
|
+
if (OPStackChains.includes(chainId)) {
|
|
310
|
+
maxFeePerGas = 10n ** 8n;
|
|
311
|
+
maxPriorityFeePerGas = 10n ** 8n;
|
|
312
|
+
}
|
|
313
|
+
else if (chainId === "8453") {
|
|
314
|
+
maxFeePerGas = 10n ** 9n;
|
|
315
|
+
maxPriorityFeePerGas = 10n ** 9n;
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
maxFeePerGas = 1n;
|
|
319
|
+
maxPriorityFeePerGas = 1n;
|
|
320
|
+
}
|
|
321
|
+
const partialOp = {
|
|
322
|
+
callData: await this.buildCalldata(auth, userId, transactionParams, txOptions),
|
|
323
|
+
paymasterAndData,
|
|
324
|
+
sender,
|
|
325
|
+
maxFeePerGas,
|
|
326
|
+
maxPriorityFeePerGas,
|
|
327
|
+
initCode,
|
|
328
|
+
nonce: txOptions.nonce !== null && txOptions.nonce !== undefined ? txOptions.nonce : await this.getNonce(sender),
|
|
329
|
+
preVerificationGas: 100000n,
|
|
330
|
+
callGasLimit: BigInt(10e6),
|
|
331
|
+
verificationGasLimit: BigInt(10e6)
|
|
332
|
+
};
|
|
333
|
+
const isGroupOp = (await auth.getUserId()) !== userId;
|
|
334
|
+
const operation = new data_1.Operation(partialOp, {
|
|
335
|
+
chainId: await chain.getChainId(),
|
|
336
|
+
opType: isGroupOp ? data_1.OperationType.GROUP_OPERATION : data_1.OperationType.SINGLE_OPERATION,
|
|
337
|
+
authType: isGroupOp ? data_1.AuthType.MULTI_SIG : data_1.AuthType.ECDSA,
|
|
338
|
+
walletAddr: await this.getAddress(),
|
|
339
|
+
proposer: await auth.getAddress()
|
|
340
|
+
});
|
|
341
|
+
if (isGroupOp) {
|
|
342
|
+
operation.groupId = (0, viem_1.pad)(userId, { size: 32 });
|
|
343
|
+
}
|
|
344
|
+
if (txOptions.gasSponsor && Object.keys(txOptions.gasSponsor).length > 0) {
|
|
345
|
+
if (txOptions.gasSponsor.token) {
|
|
346
|
+
const sponsor = new sponsors_1.TokenSponsor(txOptions);
|
|
347
|
+
if (txOptions.gasSponsor.usePermit) {
|
|
348
|
+
paymasterAndData = (await sponsor.getPaymasterAndDataPermit(operation, await this.getAddress(), userId, auth)).toLowerCase();
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
paymasterAndData = (await sponsor.getPaymasterAndData(txOptions)).toLowerCase();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
else {
|
|
355
|
+
const sponsor = new sponsors_1.GaslessSponsor(txOptions);
|
|
356
|
+
paymasterAndData = (await sponsor.getPaymasterAndData(txOptions)).toLowerCase();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
operation.userOp.paymasterAndData = paymasterAndData;
|
|
360
|
+
const estimatedOperation = await this.estimateOperation(auth, userId, operation, txOptions);
|
|
361
|
+
// sign the userOp directly here as we do not have the opId yet
|
|
362
|
+
estimatedOperation.userOp.signature = await auth.signOp(estimatedOperation, chain, (0, utils_1.isGroupOperation)(operation));
|
|
363
|
+
if (txOptions.skipDBAction !== true) {
|
|
364
|
+
const opId = await (0, OperationApis_1.createOp)(estimatedOperation);
|
|
365
|
+
estimatedOperation.opId = opId;
|
|
366
|
+
if (!(await (0, AccessControlApis_1.checkWalletAccessInitialization)(sender))) {
|
|
367
|
+
await (0, AccessControlApis_1.initializeWalletAccess)(sender, await auth.getAddress());
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return estimatedOperation;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Signs an operation using the provided authentication instance and returns the signed operation.
|
|
374
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
375
|
+
* @param {Operation} operation - The operation to be signed.
|
|
376
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
377
|
+
* @returns {Promise<Operation>} The signed operation.
|
|
378
|
+
*/
|
|
379
|
+
async signOperation(auth, operation, txOptions = globalThis.globalEnvOption) {
|
|
380
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
381
|
+
operation = data_1.Operation.convertTypeToObject(operation);
|
|
382
|
+
operation.userOp.signature = await auth.signOp(operation, chain, (0, utils_1.isGroupOperation)(operation));
|
|
383
|
+
if ((0, utils_1.isGroupOperation)(operation) && txOptions.skipDBAction !== true) {
|
|
384
|
+
await (0, OperationApis_1.signOp)(operation.opId, await chain.getChainId(), operation.userOp.signature, await auth.getAddress(), this.userInfo?.get(operation.groupId)?.groupInfo?.threshold);
|
|
385
|
+
}
|
|
386
|
+
return operation;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Executes an operation and returns the execution receipt.
|
|
390
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
391
|
+
* @param {Operation} operation - The operation to be executed.
|
|
392
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
393
|
+
* @returns {Promise<ExecutionReceipt>} The execution receipt of the operation.
|
|
394
|
+
*/
|
|
395
|
+
async executeOperation(auth, operation, txOptions = globalThis.globalEnvOption) {
|
|
396
|
+
txOptions = (0, config_1.parseOptions)(txOptions);
|
|
397
|
+
operation = data_1.Operation.convertTypeToObject(operation);
|
|
398
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
399
|
+
const chainId = await chain.getChainId();
|
|
400
|
+
if (txOptions.skipDBAction !== true) {
|
|
401
|
+
// cache group info
|
|
402
|
+
if ((0, utils_1.isGroupOperation)(operation)) {
|
|
403
|
+
const groups = await (0, GroupApis_1.getGroups)([operation.groupId], chainId);
|
|
404
|
+
if (groups && groups.length > 0) {
|
|
405
|
+
// could be empty as a new wallet wants to create a group
|
|
406
|
+
this.userInfo?.set(operation.groupId, {
|
|
407
|
+
userId: operation.groupId,
|
|
408
|
+
groupInfo: {
|
|
409
|
+
threshold: groups[0].threshold,
|
|
410
|
+
memberIds: groups[0].memberIds
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const threshold = this.userInfo?.get(operation.groupId)?.groupInfo?.threshold ?? 1;
|
|
417
|
+
if (threshold <= 1) {
|
|
418
|
+
if (!operation.userOp.signature || operation.userOp.signature === "0x") {
|
|
419
|
+
operation.userOp.signature = await auth.signOp(operation, chain, (0, utils_1.isGroupOperation)(operation));
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
else {
|
|
423
|
+
if (txOptions.skipDBAction !== true) {
|
|
424
|
+
// check remote collected signature
|
|
425
|
+
const storedOps = await (0, OperationApis_1.getOps)([operation.opId], chainId);
|
|
426
|
+
let collectedSigCount;
|
|
427
|
+
if ((0, utils_1.isSignatureMissing)(await auth.getUserId(), storedOps[0]?.signatures)) {
|
|
428
|
+
collectedSigCount = storedOps[0]?.signatures?.length ? storedOps[0]?.signatures?.length + 1 : 1;
|
|
429
|
+
if (collectedSigCount >= threshold) {
|
|
430
|
+
operation.userOp.signature = await auth.signOp(operation, chain, (0, utils_1.isGroupOperation)(operation));
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
collectedSigCount = storedOps[0]?.signatures?.length ?? 1;
|
|
435
|
+
}
|
|
436
|
+
if (collectedSigCount < threshold) {
|
|
437
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InsufficientSignatures, "Signatures are not sufficient to execute the operation", { threshold, collectedSigCount, chainId }, "Only execute operation with enough signatures", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InsufficientSignatures, "Signatures are not sufficient to execute the operation", { threshold, chainId, skipDBAction: txOptions.skipDBAction }, "Only execute operation with enough signatures", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
let receipt;
|
|
445
|
+
if ((0, utils_1.isGroupOperation)(operation)) {
|
|
446
|
+
receipt = await (0, OperationApis_1.executeOp)({
|
|
447
|
+
opId: operation.opId,
|
|
448
|
+
chainId,
|
|
449
|
+
executedBy: await auth.getAddress(),
|
|
450
|
+
entryPointAddress: await chain.getAddress("entryPointAddress"),
|
|
451
|
+
signature: operation.userOp.signature,
|
|
452
|
+
groupInfo: this.userInfo?.get(operation.groupId)?.groupInfo
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
receipt = await (0, OperationApis_1.executeOp)({
|
|
457
|
+
opId: operation.opId,
|
|
458
|
+
chainId,
|
|
459
|
+
executedBy: await auth.getAddress(),
|
|
460
|
+
entryPointAddress: await chain.getAddress("entryPointAddress"),
|
|
461
|
+
signature: operation.userOp.signature,
|
|
462
|
+
userOp: operation.userOp
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
receipt = await (0, OperationApis_1.getFullReceipt)(operation.opId, chainId, receipt.userOpHash);
|
|
466
|
+
if ((0, utils_1.isWalletInitOp)(operation.userOp) && txOptions.skipDBAction !== true) {
|
|
467
|
+
await (0, UserApis_1.addUserToWallet)(auth.authId, chainId, await this.getAddress(), Array.from(this.userInfo.keys()), this.walletUniqueId);
|
|
468
|
+
if ((0, utils_1.isGroupOperation)(operation)) {
|
|
469
|
+
const group = this.userInfo.get(operation.groupId);
|
|
470
|
+
if (group && group.groupInfo) {
|
|
471
|
+
await (0, GroupApis_1.createGroup)(operation.groupId, chainId, group.groupInfo.threshold, await this.getAddress(), group.groupInfo.memberIds);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
if (txOptions?.gasSponsor?.sponsorAddress) {
|
|
475
|
+
const paymasterType = (0, PaymasterUtils_1.getPaymasterType)(txOptions);
|
|
476
|
+
(0, PaymasterApis_1.addTransaction)(await chain.getChainId(), Date.now(), receipt.txId, {
|
|
477
|
+
action: "sponsor",
|
|
478
|
+
amount: -1,
|
|
479
|
+
from: txOptions.gasSponsor.sponsorAddress,
|
|
480
|
+
to: await this.getAddress(),
|
|
481
|
+
token: "eth",
|
|
482
|
+
txid: receipt.txId
|
|
483
|
+
}, paymasterType, txOptions.gasSponsor.sponsorAddress);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
return receipt;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Schedules an operation for execution and returns the scheduled operation's ID.
|
|
490
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
491
|
+
* @param {Operation} operation - The operation to be scheduled.
|
|
492
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
493
|
+
* @returns {Promise<Hex>} The ID of the scheduled operation.
|
|
494
|
+
*/
|
|
495
|
+
async scheduleOperation(auth, operation, txOptions = globalThis.globalEnvOption) {
|
|
496
|
+
txOptions = (0, config_1.parseOptions)(txOptions);
|
|
497
|
+
operation = data_1.Operation.convertTypeToObject(operation);
|
|
498
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
499
|
+
const chainId = await chain.getChainId();
|
|
500
|
+
if (txOptions.skipDBAction !== true) {
|
|
501
|
+
// cache group info
|
|
502
|
+
if ((0, utils_1.isGroupOperation)(operation)) {
|
|
503
|
+
const groups = await (0, GroupApis_1.getGroups)([operation.groupId], chainId);
|
|
504
|
+
if (groups && groups.length > 0) {
|
|
505
|
+
// could be empty as a new wallet wants to create a group
|
|
506
|
+
this.userInfo?.set(operation.groupId, {
|
|
507
|
+
userId: operation.groupId,
|
|
508
|
+
groupInfo: {
|
|
509
|
+
threshold: groups[0].threshold,
|
|
510
|
+
memberIds: groups[0].memberIds
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const threshold = this.userInfo?.get(operation.groupId)?.groupInfo?.threshold ?? 1;
|
|
517
|
+
if (threshold <= 1) {
|
|
518
|
+
if (!operation.userOp.signature || operation.userOp.signature === "0x") {
|
|
519
|
+
operation.userOp.signature = await auth.signOp(operation, chain, (0, utils_1.isGroupOperation)(operation));
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
else {
|
|
523
|
+
if (txOptions.skipDBAction !== true) {
|
|
524
|
+
// check remote collected signature
|
|
525
|
+
const storedOps = await (0, OperationApis_1.getOps)([operation.opId], chainId);
|
|
526
|
+
let collectedSigCount;
|
|
527
|
+
if ((0, utils_1.isSignatureMissing)(await auth.getUserId(), storedOps[0]?.signatures)) {
|
|
528
|
+
collectedSigCount = storedOps[0]?.signatures?.length ? storedOps[0]?.signatures?.length + 1 : 1;
|
|
529
|
+
if (collectedSigCount >= threshold) {
|
|
530
|
+
operation.userOp.signature = await auth.signOp(operation, chain, (0, utils_1.isGroupOperation)(operation));
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
else {
|
|
534
|
+
collectedSigCount = storedOps[0]?.signatures?.length ?? 1;
|
|
535
|
+
}
|
|
536
|
+
if (collectedSigCount < threshold) {
|
|
537
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InsufficientSignatures, "Signatures are not sufficient to execute the operation", { threshold, collectedSigCount, chainId }, "Only execute operation with enough signatures", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InsufficientSignatures, "Signatures are not sufficient to execute the operation", { threshold, chainId, skipDBAction: txOptions.skipDBAction }, "Only execute operation with enough signatures", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if ((0, utils_1.isGroupOperation)(operation)) {
|
|
545
|
+
await (0, OperationApis_1.scheduleOp)({
|
|
546
|
+
opId: operation.opId,
|
|
547
|
+
chainId,
|
|
548
|
+
scheduledBy: await auth.getAddress(),
|
|
549
|
+
entryPointAddress: await chain.getAddress("entryPointAddress"),
|
|
550
|
+
signature: operation.userOp.signature,
|
|
551
|
+
groupInfo: this.userInfo?.get(operation.groupId)?.groupInfo
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
else {
|
|
555
|
+
await (0, OperationApis_1.scheduleOp)({
|
|
556
|
+
opId: operation.opId,
|
|
557
|
+
chainId,
|
|
558
|
+
scheduledBy: await auth.getAddress(),
|
|
559
|
+
entryPointAddress: await chain.getAddress("entryPointAddress"),
|
|
560
|
+
signature: operation.userOp.signature,
|
|
561
|
+
userOp: operation.userOp
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
if (!operation.opId) {
|
|
565
|
+
throw new errors_1.InternalFailureError(errors_1.ErrorCode.ServerFailure, "Operation id is required", operation, "Make sure you are scheduling a valid operation", "https://docs.fun.xyz/");
|
|
566
|
+
}
|
|
567
|
+
return operation.opId;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Removes an operation from the system using its ID.
|
|
571
|
+
* @param {Auth} _ - The authentication instance (not used in this method).
|
|
572
|
+
* @param {Hex} operationId - The ID of the operation to be removed.
|
|
573
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
574
|
+
* @returns {Promise<void>} A promise that resolves after the operation is removed.
|
|
575
|
+
*/
|
|
576
|
+
async removeOperation(_, operationId, txOptions = globalThis.globalEnvOption) {
|
|
577
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
578
|
+
await (0, OperationApis_1.deleteOp)(operationId, await chain.getChainId());
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Creates and prepares a rejection operation for an existing operation.
|
|
582
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
583
|
+
* @param {string} groupId - The ID of the group to which the operation belongs.
|
|
584
|
+
* @param {Operation} operation - The operation to be rejected.
|
|
585
|
+
* @param {string} rejectionMessage - Optional rejection message.
|
|
586
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
587
|
+
* @returns {Promise<Operation>} The prepared rejection operation.
|
|
588
|
+
*/
|
|
589
|
+
async createRejectOperation(auth, groupId, operation, rejectionMessage, txOptions = globalThis.globalEnvOption) {
|
|
590
|
+
const rejectOperation = await this.transfer(auth, groupId, { to: await this.getAddress(), amount: 0, token: "eth" }, { ...txOptions, skipDBAction: true, nonce: BigInt(operation.userOp.nonce) });
|
|
591
|
+
if (rejectionMessage)
|
|
592
|
+
rejectOperation.message = rejectionMessage;
|
|
593
|
+
rejectOperation.relatedOpIds = [operation.opId];
|
|
594
|
+
rejectOperation.opType = data_1.OperationType.REJECTION;
|
|
595
|
+
rejectOperation.opId = (await (0, OperationApis_1.createOp)(rejectOperation));
|
|
596
|
+
return rejectOperation;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Estimates the gas cost for executing an operation and returns the updated operation with gas estimation details.
|
|
600
|
+
* @param {Auth} auth - The authentication instance for the user.
|
|
601
|
+
* @param {string} userId - The ID of the user initiating the operation.
|
|
602
|
+
* @param {Operation} operation - The operation for which to estimate gas.
|
|
603
|
+
* @param {EnvOption} txOptions - Transaction environment options (default: global environment options).
|
|
604
|
+
* @returns {Promise<Operation>} The updated operation with gas estimation details.
|
|
605
|
+
*/
|
|
606
|
+
async estimateOperation(auth, userId, operation, txOptions = globalThis.globalEnvOption) {
|
|
607
|
+
const chain = await data_1.Chain.getChain({ chainIdentifier: txOptions.chain });
|
|
608
|
+
const estimateGasSignature = await auth.getEstimateGasSignature(userId, operation);
|
|
609
|
+
operation.userOp.signature = estimateGasSignature.toLowerCase();
|
|
610
|
+
const res = await chain.estimateOpGas(operation.userOp);
|
|
611
|
+
operation.userOp = {
|
|
612
|
+
...operation.userOp,
|
|
613
|
+
...res
|
|
614
|
+
};
|
|
615
|
+
const maxFeePerGas = await chain.getFeeData();
|
|
616
|
+
operation.userOp.maxFeePerGas = maxFeePerGas;
|
|
617
|
+
operation.userOp.maxPriorityFeePerGas = maxFeePerGas;
|
|
618
|
+
return operation;
|
|
619
|
+
}
|
|
620
|
+
async getThisInitCode(chain) {
|
|
621
|
+
const owners = Array.from(this.userInfo.keys());
|
|
622
|
+
const entryPointAddress = await chain.getAddress("entryPointAddress");
|
|
623
|
+
const factoryAddress = await chain.getAddress("factoryAddress");
|
|
624
|
+
const rbac = await chain.getAddress("rbacAddress");
|
|
625
|
+
const userAuth = await chain.getAddress("userAuthAddress");
|
|
626
|
+
const loginData = {
|
|
627
|
+
salt: this.walletUniqueId
|
|
628
|
+
};
|
|
629
|
+
const rbacInitData = (0, data_1.toBytes32Arr)(owners);
|
|
630
|
+
let userAuthInitData = "0x";
|
|
631
|
+
const groupUsers = Array.from(this.userInfo.values()).filter((user) => user.groupInfo !== null && user.groupInfo !== undefined);
|
|
632
|
+
if (groupUsers.length > 0) {
|
|
633
|
+
userAuthInitData = (0, data_1.encodeUserAuthInitData)(groupUsers);
|
|
634
|
+
}
|
|
635
|
+
const initCodeParams = {
|
|
636
|
+
entryPointAddress,
|
|
637
|
+
factoryAddress,
|
|
638
|
+
implementationAddress: constants_1.AddressZero,
|
|
639
|
+
loginData: loginData,
|
|
640
|
+
verificationAddresses: [rbac, userAuth],
|
|
641
|
+
verificationData: [rbacInitData, userAuthInitData]
|
|
642
|
+
};
|
|
643
|
+
return this.getInitCode(initCodeParams);
|
|
644
|
+
}
|
|
645
|
+
getInitCode(input) {
|
|
646
|
+
const encodedVerificationInitdata = (0, viem_1.encodeAbiParameters)([
|
|
647
|
+
{
|
|
648
|
+
type: "address[]",
|
|
649
|
+
name: "verificationAddresses"
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
type: "bytes[]",
|
|
653
|
+
name: "verificationData"
|
|
654
|
+
}
|
|
655
|
+
], [input.verificationAddresses, input.verificationData]);
|
|
656
|
+
const initializerCallData = common_1.WALLET_CONTRACT_INTERFACE.encodeData("initialize", [
|
|
657
|
+
input.entryPointAddress,
|
|
658
|
+
encodedVerificationInitdata
|
|
659
|
+
]);
|
|
660
|
+
const data = constants_1.FACTORY_CONTRACT_INTERFACE.encodeData("createAccount", [initializerCallData, (0, data_1.encodeLoginData)(input.loginData)]);
|
|
661
|
+
return (0, viem_1.concat)([input.factoryAddress, data]);
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Encodes arbitrary transactions calls to include fees
|
|
665
|
+
* @param params Transaction Params, generated from various calldata generating functions
|
|
666
|
+
* @param options EnvOptions to read fee data from
|
|
667
|
+
* @returns calldata to be passed into createUserOperation
|
|
668
|
+
*/
|
|
669
|
+
async buildCalldata(auth, userId, params, options) {
|
|
670
|
+
if (!params.value) {
|
|
671
|
+
params.value = 0n;
|
|
672
|
+
}
|
|
673
|
+
if (options.fee) {
|
|
674
|
+
if (!options.fee.token && options.gasSponsor && options.gasSponsor.token) {
|
|
675
|
+
options.fee.token = options.gasSponsor.token;
|
|
676
|
+
}
|
|
677
|
+
if (!options.fee.token) {
|
|
678
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.MissingParameter, "EnvOption.fee.token or EnvOption.gasSponsor.token is required", { options }, "Provide EnvOption.fee.token or EnvOption.gasSponsor.token when calling wallet.createOperation", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
679
|
+
}
|
|
680
|
+
if (!options.fee.recipient) {
|
|
681
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.MissingParameter, "EnvOption.fee.recipient is required", { options }, "Provide EnvOption.fee.recipient when calling wallet.createOperation", "https://docs.fun.xyz/how-to-guides/execute-transactions#execute-transactions");
|
|
682
|
+
}
|
|
683
|
+
const token = new data_1.Token(options.fee.token);
|
|
684
|
+
if (options.fee.gasPercent && !token.isNative) {
|
|
685
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.InvalidParameterCombination, "GasPercent is only valid for native tokens", { options }, "Use native token as the fee token if you want to charge fee based on percentage", "https://docs.fun.xyz/how-to-guides/configure-environment/set-developer-fee");
|
|
686
|
+
}
|
|
687
|
+
if (token.isNative) {
|
|
688
|
+
options.fee.token = constants_1.AddressZero;
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
options.fee.token = await token.getAddress();
|
|
692
|
+
}
|
|
693
|
+
if (options.fee.amount) {
|
|
694
|
+
options.fee.amount = Number(await token.getDecimalAmount(options.fee.amount));
|
|
695
|
+
}
|
|
696
|
+
else if (options.fee.gasPercent) {
|
|
697
|
+
const feedata = [options.fee.token, options.fee.recipient, 1];
|
|
698
|
+
const estimateGasCalldata = common_1.WALLET_CONTRACT_INTERFACE.encodeData("execFromEntryPointWithFee", [
|
|
699
|
+
params.to,
|
|
700
|
+
params.value,
|
|
701
|
+
params.data,
|
|
702
|
+
feedata
|
|
703
|
+
]);
|
|
704
|
+
const operation = await this.createOperation(auth, userId, { to: params.to, value: params.value, data: estimateGasCalldata }, { ...options, fee: undefined });
|
|
705
|
+
const gasUsed = await operation.getMaxTxCost();
|
|
706
|
+
options.fee.amount = Math.ceil((Number(gasUsed) * options.fee.gasPercent) / 100);
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
throw new errors_1.InvalidParameterError(errors_1.ErrorCode.MissingParameter, "EnvOption.fee.amount or EnvOption.fee.gasPercent is required", { options }, "Provide either EnvOption.fee.amount or EnvOption.fee.gasPercent when calling wallet.createOperation", "https://docs.fun.xyz/how-to-guides/configure-environment/set-developer-fee");
|
|
710
|
+
}
|
|
711
|
+
const feedata = [options.fee.token, options.fee.recipient, options.fee.amount];
|
|
712
|
+
return common_1.WALLET_CONTRACT_INTERFACE.encodeData("execFromEntryPointWithFee", [params.to, params.value, params.data, feedata]);
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
return common_1.WALLET_CONTRACT_INTERFACE.encodeData("execFromEntryPoint", [params.to, params.value, params.data]);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
exports.FunWallet = FunWallet;
|
|
720
|
+
//# sourceMappingURL=FunWallet.js.map
|