@raac/rpc 2.0.0-beta.3 → 2.0.0-beta.5

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.
Files changed (34) hide show
  1. package/dist/RPCLibrary.js +25 -0
  2. package/dist/artifacts/mocks/core/tokens/ERC721Mock.sol/ERC721Mock.json +491 -0
  3. package/dist/configs/chains/8453.json +6 -1
  4. package/dist/contracts/lockers/botLocker/addRewardTokens.js +21 -0
  5. package/dist/contracts/lockers/botLocker/distributeRewardToken.js +23 -0
  6. package/dist/contracts/lockers/botLocker/getConfig.js +29 -0
  7. package/dist/contracts/lockers/botLocker/getLocks.js +11 -1
  8. package/dist/contracts/lockers/botLocker/getRoles.js +22 -0
  9. package/dist/contracts/lockers/botLocker/getUnlockWindow.js +29 -0
  10. package/dist/contracts/lockers/botLocker/grantRole.js +38 -0
  11. package/dist/contracts/lockers/botLocker/hasRole.js +18 -0
  12. package/dist/contracts/lockers/botLocker/pause.js +24 -0
  13. package/dist/contracts/lockers/botLocker/rescueTokens.js +22 -0
  14. package/dist/nfts/getNFTBalance.js +29 -0
  15. package/dist/nfts/transferNFT.js +34 -0
  16. package/dist/types/RPCLibrary.d.ts +26 -1
  17. package/dist/types/contracts/lockers/botLocker/addRewardTokens.d.ts +11 -0
  18. package/dist/types/contracts/lockers/botLocker/distributeRewardToken.d.ts +13 -0
  19. package/dist/types/contracts/lockers/botLocker/getConfig.d.ts +20 -0
  20. package/dist/types/contracts/lockers/botLocker/getLocks.d.ts +4 -0
  21. package/dist/types/contracts/lockers/botLocker/getRoles.d.ts +20 -0
  22. package/dist/types/contracts/lockers/botLocker/getUnlockWindow.d.ts +24 -0
  23. package/dist/types/contracts/lockers/botLocker/grantRole.d.ts +20 -0
  24. package/dist/types/contracts/lockers/botLocker/hasRole.d.ts +12 -0
  25. package/dist/types/contracts/lockers/botLocker/pause.d.ts +6 -0
  26. package/dist/types/contracts/lockers/botLocker/rescueTokens.d.ts +12 -0
  27. package/dist/types/nfts/getNFTBalance.d.ts +13 -0
  28. package/dist/types/nfts/transferNFT.d.ts +15 -0
  29. package/dist/types/utils/artifacts.d.ts +99 -0
  30. package/dist/types/utils/errorDecoder.d.ts +10 -0
  31. package/dist/utils/artifacts.js +3 -0
  32. package/dist/utils/errorDecoder.js +40 -12
  33. package/dist/utils/rpcError.js +25 -1
  34. package/package.json +1 -1
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getLocksByOwner = exports.getLocks = void 0;
3
+ exports.getLocksByOwner = exports.getLock = exports.getLocks = void 0;
4
+ const ethers_1 = require("ethers");
4
5
  const _helpers_1 = require("./_helpers");
5
6
  const normalize = (l) => ({
6
7
  owner: l.owner ?? l[0],
@@ -16,6 +17,15 @@ const getLocks = async (chainId, provider) => {
16
17
  return results.map(normalize);
17
18
  };
18
19
  exports.getLocks = getLocks;
20
+ /**
21
+ * Returns the lock of a single NFT, or null when it is not locked.
22
+ */
23
+ const getLock = async (chainId, tokenId, provider) => {
24
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
25
+ const lock = normalize(await contract.locks(tokenId));
26
+ return lock.owner === ethers_1.ZeroAddress ? null : lock;
27
+ };
28
+ exports.getLock = getLock;
19
29
  /**
20
30
  * Returns every active NFT lock owned by `owner`.
21
31
  */
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRoles = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Gets the access-control role identifiers used by the bot locker.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param provider - Optional ethers.js Provider instance.
10
+ * @returns The bytes32 role identifiers.
11
+ */
12
+ const getRoles = async (chainId, provider) => {
13
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
14
+ const [defaultAdminRole, pauserRole, managerRole, distributorRole] = await Promise.all([
15
+ contract.DEFAULT_ADMIN_ROLE(),
16
+ contract.PAUSER_ROLE(),
17
+ contract.MANAGER_ROLE(),
18
+ contract.DISTRIBUTOR_ROLE(),
19
+ ]);
20
+ return { defaultAdminRole, pauserRole, managerRole, distributorRole };
21
+ };
22
+ exports.getRoles = getRoles;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUnlockWindow = exports.BOT_LOCKER_LOCK_DURATION_EPOCHS = exports.BOT_LOCKER_EPOCH_DURATION = void 0;
4
+ /** EPOCH_DURATION on RAACBotLocker, seconds. */
5
+ exports.BOT_LOCKER_EPOCH_DURATION = 7 * 24 * 60 * 60;
6
+ /** LOCK_DURATION_IN_EPOCH on RAACBotLocker. */
7
+ exports.BOT_LOCKER_LOCK_DURATION_EPOCHS = 4;
8
+ /**
9
+ * Unlock window of a locked NFT, computed locally without an RPC call.
10
+ *
11
+ * The contract allows `unlockAndClaim` when `floor((now - lockedAt) / epochDuration)` is a non-zero multiple of `lockDurationEpochs`, so windows are `[lockedAt + k * cycle, lockedAt + k * cycle + epochDuration)` for `k >= 1`, where `cycle = lockDurationEpochs * epochDuration`. They are relative to each NFT's own `lockedAt`, not to a global epoch, and a missed window reopens one cycle later.
12
+ *
13
+ * @param lockedAt - Lock timestamp of the NFT, unix seconds (`locks(tokenId).lockedAt`, or `lockedAt` from the subgraph).
14
+ * @param now - Current time, unix seconds. Use the latest block timestamp to match the contract exactly.
15
+ * @param epochDuration - Epoch length, seconds. Defaults to the contract constant.
16
+ * @param lockDurationEpochs - Epochs per lock cycle. Defaults to the contract constant.
17
+ * @returns Whether the NFT can unlock now and the bounds of the current or next window.
18
+ */
19
+ const getUnlockWindow = (lockedAt, now, epochDuration = exports.BOT_LOCKER_EPOCH_DURATION, lockDurationEpochs = exports.BOT_LOCKER_LOCK_DURATION_EPOCHS) => {
20
+ const epochs = Math.floor((now - lockedAt) / epochDuration);
21
+ if (epochs > 0 && epochs % lockDurationEpochs === 0) {
22
+ const opensAt = lockedAt + epochs * epochDuration;
23
+ return { unlockable: true, opensAt, closesAt: opensAt + epochDuration };
24
+ }
25
+ const cycle = Math.floor(Math.max(epochs, 0) / lockDurationEpochs) + 1;
26
+ const opensAt = lockedAt + cycle * lockDurationEpochs * epochDuration;
27
+ return { unlockable: false, opensAt, closesAt: opensAt + epochDuration };
28
+ };
29
+ exports.getUnlockWindow = getUnlockWindow;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.revokeRole = exports.grantRole = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Grant a bot locker role. DEFAULT_ADMIN_ROLE only.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param role - The bytes32 role identifier (see `getRoles`).
10
+ * @param account - The address to grant the role to.
11
+ * @param signer - An ethers.js Signer instance (required).
12
+ */
13
+ const grantRole = async (chainId, role, account, signer) => {
14
+ if (!signer)
15
+ throw new Error("Signer is required");
16
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
17
+ const tx = await contract.grantRole(role, account);
18
+ await tx.wait();
19
+ return tx;
20
+ };
21
+ exports.grantRole = grantRole;
22
+ /**
23
+ * Revoke a bot locker role. DEFAULT_ADMIN_ROLE only.
24
+ *
25
+ * @param chainId - The chain/network to use.
26
+ * @param role - The bytes32 role identifier (see `getRoles`).
27
+ * @param account - The address to revoke the role from.
28
+ * @param signer - An ethers.js Signer instance (required).
29
+ */
30
+ const revokeRole = async (chainId, role, account, signer) => {
31
+ if (!signer)
32
+ throw new Error("Signer is required");
33
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
34
+ const tx = await contract.revokeRole(role, account);
35
+ await tx.wait();
36
+ return tx;
37
+ };
38
+ exports.revokeRole = revokeRole;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasRole = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Checks whether an account holds a bot locker role.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param role - The bytes32 role identifier (see `getRoles`).
10
+ * @param account - The address to check.
11
+ * @param provider - Optional ethers.js Provider instance.
12
+ * @returns True if the account holds the role.
13
+ */
14
+ const hasRole = async (chainId, role, account, provider) => {
15
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, provider);
16
+ return contract.hasRole(role, account);
17
+ };
18
+ exports.hasRole = hasRole;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unpause = exports.pause = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /** Pause lock, unlockAndClaim and claim. PAUSER_ROLE only. */
6
+ const pause = async (chainId, signer) => {
7
+ if (!signer)
8
+ throw new Error("Signer is required");
9
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
10
+ const tx = await contract.pause();
11
+ await tx.wait();
12
+ return tx;
13
+ };
14
+ exports.pause = pause;
15
+ /** PAUSER_ROLE only. */
16
+ const unpause = async (chainId, signer) => {
17
+ if (!signer)
18
+ throw new Error("Signer is required");
19
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
20
+ const tx = await contract.unpause();
21
+ await tx.wait();
22
+ return tx;
23
+ };
24
+ exports.unpause = unpause;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rescueTokens = void 0;
4
+ const _helpers_1 = require("./_helpers");
5
+ /**
6
+ * Send the locker's entire balance of `token` to `recipient`. DEFAULT_ADMIN_ROLE only.
7
+ * This includes rewards lockers have not claimed yet, so later claims of that token revert until it is refilled.
8
+ *
9
+ * @param chainId - The chain/network to use.
10
+ * @param token - ERC20 address to rescue.
11
+ * @param recipient - Address receiving the balance.
12
+ * @param signer - An ethers.js Signer instance (required).
13
+ */
14
+ const rescueTokens = async (chainId, token, recipient, signer) => {
15
+ if (!signer)
16
+ throw new Error("Signer is required");
17
+ const contract = await (0, _helpers_1.getBotLockerContract)(chainId, signer);
18
+ const tx = await contract.rescueTokens(token, recipient);
19
+ await tx.wait();
20
+ return tx;
21
+ };
22
+ exports.rescueTokens = rescueTokens;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ethers_1 = require("ethers");
4
+ const contracts_1 = require("../utils/contracts");
5
+ const artifacts_1 = require("../utils/artifacts");
6
+ const rpcError_1 = require("../utils/rpcError");
7
+ /**
8
+ * Get how many tokens of an NFT contract an address holds
9
+ * @param chainId - The chain ID
10
+ * @param nftContractName - The NFT contract name from configs
11
+ * @param owner - The address to check
12
+ * @param provider - The provider to use for the contract call
13
+ * @returns The number of tokens held
14
+ */
15
+ async function getNFTBalance(chainId, nftContractName, owner, provider) {
16
+ if (!provider) {
17
+ throw new Error("Provider not available");
18
+ }
19
+ const nftAddress = (0, contracts_1.getContractAddress)(chainId, nftContractName);
20
+ try {
21
+ const nftABI = (0, artifacts_1.getABI)(nftContractName);
22
+ const nftContract = new ethers_1.ethers.Contract(nftAddress, nftABI, provider);
23
+ return await nftContract.balanceOf(owner);
24
+ }
25
+ catch (error) {
26
+ throw (0, rpcError_1.toRpcError)("nfts.getNFTBalance", error, { chainId, address: nftAddress });
27
+ }
28
+ }
29
+ exports.default = getNFTBalance;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ethers_1 = require("ethers");
4
+ const contracts_1 = require("../utils/contracts");
5
+ const artifacts_1 = require("../utils/artifacts");
6
+ const rpcError_1 = require("../utils/rpcError");
7
+ /**
8
+ * Transfer an NFT from the signer to another address with safeTransferFrom
9
+ * Do not use it to put a Bot NFT into the bot locker: the locker only records NFTs deposited through `lockers.botLocker.lock`.
10
+ * @param chainId - The chain ID
11
+ * @param nftContractName - The NFT contract name from configs
12
+ * @param to - The recipient address
13
+ * @param tokenId - The token ID to transfer
14
+ * @param signer - The signer that owns the token
15
+ * @returns Transaction receipt
16
+ */
17
+ async function transferNFT(chainId, nftContractName, to, tokenId, signer) {
18
+ if (!signer) {
19
+ throw new Error("Wallet not connected");
20
+ }
21
+ const nftAddress = (0, contracts_1.getContractAddress)(chainId, nftContractName);
22
+ try {
23
+ const nftABI = (0, artifacts_1.getABI)(nftContractName);
24
+ const nftContract = new ethers_1.ethers.Contract(nftAddress, nftABI, signer);
25
+ const from = await signer.getAddress();
26
+ const tx = await nftContract["safeTransferFrom(address,address,uint256)"](from, to, tokenId);
27
+ const receipt = await tx.wait();
28
+ return receipt;
29
+ }
30
+ catch (error) {
31
+ throw (0, rpcError_1.toRpcError)("nfts.transferNFT", error, { chainId, address: nftAddress });
32
+ }
33
+ }
34
+ exports.default = transferNFT;
@@ -106,6 +106,8 @@ import getNFTApproval from "./nfts/getNFTApproval";
106
106
  import getApprovedForAll from "./nfts/getApprovalForAll";
107
107
  import setApprovalForAll from "./nfts/setApprovalForAll";
108
108
  import approveNFT from "./nfts/approveNFT";
109
+ import getNFTBalance from "./nfts/getNFTBalance";
110
+ import transferNFT from "./nfts/transferNFT";
109
111
  import vaultOpened from "./pools/lendingPool/vaultOpened";
110
112
  import { getWithdrawRequestInfo as getStabilityPoolWithdrawRequestInfo } from "./pools/stabilityPool/getWithdrawRequestInfo";
111
113
  import { getWithdrawTimelockConfig as getStabilityPoolWithdrawTimelockConfig } from "./pools/stabilityPool/getWithdrawTimelockConfig";
@@ -242,8 +244,17 @@ import { getClaimables as getClaimablesBotLocker } from "./contracts/lockers/bot
242
244
  import { getClaimedRewards as getClaimedRewardsBotLocker } from "./contracts/lockers/botLocker/getClaimedRewards";
243
245
  import { getRewardTokens as getRewardTokensBotLocker } from "./contracts/lockers/botLocker/getRewardTokens";
244
246
  import { getRewardTokenCount as getRewardTokenCountBotLocker } from "./contracts/lockers/botLocker/getRewardTokenCount";
245
- import { getLocks as getLocksBotLocker, getLocksByOwner as getLocksByOwnerBotLocker } from "./contracts/lockers/botLocker/getLocks";
247
+ import { getLocks as getLocksBotLocker, getLock as getLockBotLocker, getLocksByOwner as getLocksByOwnerBotLocker } from "./contracts/lockers/botLocker/getLocks";
246
248
  import { getLockedTokenIds as getLockedTokenIdsBotLocker } from "./contracts/lockers/botLocker/getLockedTokenIds";
249
+ import { getConfig as getConfigBotLocker } from "./contracts/lockers/botLocker/getConfig";
250
+ import { getUnlockWindow as getUnlockWindowBotLocker } from "./contracts/lockers/botLocker/getUnlockWindow";
251
+ import { getRoles as getRolesBotLocker } from "./contracts/lockers/botLocker/getRoles";
252
+ import { hasRole as hasRoleBotLocker } from "./contracts/lockers/botLocker/hasRole";
253
+ import { grantRole as grantRoleBotLocker, revokeRole as revokeRoleBotLocker } from "./contracts/lockers/botLocker/grantRole";
254
+ import { addRewardTokens as addRewardTokensBotLocker } from "./contracts/lockers/botLocker/addRewardTokens";
255
+ import { distributeRewardToken as distributeRewardTokenBotLocker } from "./contracts/lockers/botLocker/distributeRewardToken";
256
+ import { pause as pauseBotLocker, unpause as unpauseBotLocker } from "./contracts/lockers/botLocker/pause";
257
+ import { rescueTokens as rescueTokensBotLocker } from "./contracts/lockers/botLocker/rescueTokens";
247
258
  import { getBalance as getLeRAACBalance } from "./contracts/tokens/leRAAC/getBalance";
248
259
  import { getTotalSupply as getLeRAACTotalSupply } from "./contracts/tokens/leRAAC/getTotalSupply";
249
260
  import { getAllowance as getLeRAACAllowance } from "./contracts/tokens/leRAAC/getAllowance";
@@ -337,6 +348,8 @@ declare class RPCLibrary {
337
348
  getApprovedForAll: typeof getApprovedForAll;
338
349
  setApprovalForAll: typeof setApprovalForAll;
339
350
  approveNFT: typeof approveNFT;
351
+ getNFTBalance: typeof getNFTBalance;
352
+ transferNFT: typeof transferNFT;
340
353
  };
341
354
  contracts: {
342
355
  housePrices: {
@@ -549,8 +562,20 @@ declare class RPCLibrary {
549
562
  getRewardTokens: typeof getRewardTokensBotLocker;
550
563
  getRewardTokenCount: typeof getRewardTokenCountBotLocker;
551
564
  getLocks: typeof getLocksBotLocker;
565
+ getLock: typeof getLockBotLocker;
552
566
  getLocksByOwner: typeof getLocksByOwnerBotLocker;
553
567
  getLockedTokenIds: typeof getLockedTokenIdsBotLocker;
568
+ getConfig: typeof getConfigBotLocker;
569
+ getUnlockWindow: typeof getUnlockWindowBotLocker;
570
+ getRoles: typeof getRolesBotLocker;
571
+ hasRole: typeof hasRoleBotLocker;
572
+ grantRole: typeof grantRoleBotLocker;
573
+ revokeRole: typeof revokeRoleBotLocker;
574
+ addRewardTokens: typeof addRewardTokensBotLocker;
575
+ distributeRewardToken: typeof distributeRewardTokenBotLocker;
576
+ pause: typeof pauseBotLocker;
577
+ unpause: typeof unpauseBotLocker;
578
+ rescueTokens: typeof rescueTokensBotLocker;
554
579
  };
555
580
  };
556
581
  zap: {
@@ -0,0 +1,11 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Register reward tokens that can be distributed to lockers. MANAGER_ROLE only.
5
+ * Reverts if any token is the zero address or already registered.
6
+ *
7
+ * @param chainId - The chain/network to use.
8
+ * @param tokens - ERC20 addresses to register.
9
+ * @param signer - An ethers.js Signer instance (required).
10
+ */
11
+ export declare const addRewardTokens: (chainId: ChainId, tokens: string[], signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
@@ -0,0 +1,13 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Distribute `amount` of a registered reward token across all currently locked NFTs. DISTRIBUTOR_ROLE only.
5
+ * The signer's tokens are pulled via transferFrom, so approve the locker for `amount` first.
6
+ * Reverts when nothing is locked.
7
+ *
8
+ * @param chainId - The chain/network to use.
9
+ * @param token - Address of a registered reward token.
10
+ * @param amount - Amount to distribute, in `token` base units.
11
+ * @param signer - An ethers.js Signer instance (required).
12
+ */
13
+ export declare const distributeRewardToken: (chainId: ChainId, token: string, amount: bigint, signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
@@ -0,0 +1,20 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ export interface BotLockerConfig {
4
+ /** Address of the RAAC Bot NFT collection the locker accepts. */
5
+ nft: string;
6
+ /** Length of one epoch, seconds (EPOCH_DURATION). */
7
+ epochDuration: number;
8
+ /** Epochs per lock cycle; an NFT can unlock when its locked epochs are a non-zero multiple of this (LOCK_DURATION_IN_EPOCH). */
9
+ lockDurationEpochs: number;
10
+ rewardTokens: string[];
11
+ paused: boolean;
12
+ }
13
+ /**
14
+ * Read the locker's configuration in a single call batch.
15
+ *
16
+ * @param chainId - The chain/network to use.
17
+ * @param provider - Optional ethers.js Provider instance.
18
+ * @returns The NFT collection, lock timing constants, reward tokens and pause state.
19
+ */
20
+ export declare const getConfig: (chainId: ChainId, provider?: Provider) => Promise<BotLockerConfig>;
@@ -9,6 +9,10 @@ export interface BotLockerNFTLock {
9
9
  * Returns every active NFT lock across all owners.
10
10
  */
11
11
  export declare const getLocks: (chainId: ChainId, provider?: Provider) => Promise<BotLockerNFTLock[]>;
12
+ /**
13
+ * Returns the lock of a single NFT, or null when it is not locked.
14
+ */
15
+ export declare const getLock: (chainId: ChainId, tokenId: string | number | bigint, provider?: Provider) => Promise<BotLockerNFTLock | null>;
12
16
  /**
13
17
  * Returns every active NFT lock owned by `owner`.
14
18
  */
@@ -0,0 +1,20 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ export interface BotLockerRoles {
4
+ /** Grants and revokes roles, and calls `rescueTokens`. */
5
+ defaultAdminRole: string;
6
+ /** Calls `pause` and `unpause`. */
7
+ pauserRole: string;
8
+ /** Calls `addRewardTokens`. */
9
+ managerRole: string;
10
+ /** Calls `distributeRewardToken`; held by RAACLiquidLocker. */
11
+ distributorRole: string;
12
+ }
13
+ /**
14
+ * Gets the access-control role identifiers used by the bot locker.
15
+ *
16
+ * @param chainId - The chain/network to use.
17
+ * @param provider - Optional ethers.js Provider instance.
18
+ * @returns The bytes32 role identifiers.
19
+ */
20
+ export declare const getRoles: (chainId: ChainId, provider?: Provider) => Promise<BotLockerRoles>;
@@ -0,0 +1,24 @@
1
+ /** EPOCH_DURATION on RAACBotLocker, seconds. */
2
+ export declare const BOT_LOCKER_EPOCH_DURATION: number;
3
+ /** LOCK_DURATION_IN_EPOCH on RAACBotLocker. */
4
+ export declare const BOT_LOCKER_LOCK_DURATION_EPOCHS = 4;
5
+ export interface BotLockerUnlockWindow {
6
+ /** True when `now` is inside an unlock window. */
7
+ unlockable: boolean;
8
+ /** Start of the current window when unlockable, otherwise of the next one, unix seconds. */
9
+ opensAt: number;
10
+ /** End (exclusive) of that window, unix seconds. */
11
+ closesAt: number;
12
+ }
13
+ /**
14
+ * Unlock window of a locked NFT, computed locally without an RPC call.
15
+ *
16
+ * The contract allows `unlockAndClaim` when `floor((now - lockedAt) / epochDuration)` is a non-zero multiple of `lockDurationEpochs`, so windows are `[lockedAt + k * cycle, lockedAt + k * cycle + epochDuration)` for `k >= 1`, where `cycle = lockDurationEpochs * epochDuration`. They are relative to each NFT's own `lockedAt`, not to a global epoch, and a missed window reopens one cycle later.
17
+ *
18
+ * @param lockedAt - Lock timestamp of the NFT, unix seconds (`locks(tokenId).lockedAt`, or `lockedAt` from the subgraph).
19
+ * @param now - Current time, unix seconds. Use the latest block timestamp to match the contract exactly.
20
+ * @param epochDuration - Epoch length, seconds. Defaults to the contract constant.
21
+ * @param lockDurationEpochs - Epochs per lock cycle. Defaults to the contract constant.
22
+ * @returns Whether the NFT can unlock now and the bounds of the current or next window.
23
+ */
24
+ export declare const getUnlockWindow: (lockedAt: number, now: number, epochDuration?: number, lockDurationEpochs?: number) => BotLockerUnlockWindow;
@@ -0,0 +1,20 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Grant a bot locker role. DEFAULT_ADMIN_ROLE only.
5
+ *
6
+ * @param chainId - The chain/network to use.
7
+ * @param role - The bytes32 role identifier (see `getRoles`).
8
+ * @param account - The address to grant the role to.
9
+ * @param signer - An ethers.js Signer instance (required).
10
+ */
11
+ export declare const grantRole: (chainId: ChainId, role: string, account: string, signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
12
+ /**
13
+ * Revoke a bot locker role. DEFAULT_ADMIN_ROLE only.
14
+ *
15
+ * @param chainId - The chain/network to use.
16
+ * @param role - The bytes32 role identifier (see `getRoles`).
17
+ * @param account - The address to revoke the role from.
18
+ * @param signer - An ethers.js Signer instance (required).
19
+ */
20
+ export declare const revokeRole: (chainId: ChainId, role: string, account: string, signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
@@ -0,0 +1,12 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Checks whether an account holds a bot locker role.
5
+ *
6
+ * @param chainId - The chain/network to use.
7
+ * @param role - The bytes32 role identifier (see `getRoles`).
8
+ * @param account - The address to check.
9
+ * @param provider - Optional ethers.js Provider instance.
10
+ * @returns True if the account holds the role.
11
+ */
12
+ export declare const hasRole: (chainId: ChainId, role: string, account: string, provider?: Provider) => Promise<boolean>;
@@ -0,0 +1,6 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /** Pause lock, unlockAndClaim and claim. PAUSER_ROLE only. */
4
+ export declare const pause: (chainId: ChainId, signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
5
+ /** PAUSER_ROLE only. */
6
+ export declare const unpause: (chainId: ChainId, signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
@@ -0,0 +1,12 @@
1
+ import { Signer } from "ethers";
2
+ import { ChainId } from "../../../configs/chains";
3
+ /**
4
+ * Send the locker's entire balance of `token` to `recipient`. DEFAULT_ADMIN_ROLE only.
5
+ * This includes rewards lockers have not claimed yet, so later claims of that token revert until it is refilled.
6
+ *
7
+ * @param chainId - The chain/network to use.
8
+ * @param token - ERC20 address to rescue.
9
+ * @param recipient - Address receiving the balance.
10
+ * @param signer - An ethers.js Signer instance (required).
11
+ */
12
+ export declare const rescueTokens: (chainId: ChainId, token: string, recipient: string, signer: Signer) => Promise<import("ethers").ContractTransactionResponse>;
@@ -0,0 +1,13 @@
1
+ import { Provider } from "ethers";
2
+ import { ChainId } from "../configs/chains/index";
3
+ import { NftContractNames } from "./approveNFT";
4
+ /**
5
+ * Get how many tokens of an NFT contract an address holds
6
+ * @param chainId - The chain ID
7
+ * @param nftContractName - The NFT contract name from configs
8
+ * @param owner - The address to check
9
+ * @param provider - The provider to use for the contract call
10
+ * @returns The number of tokens held
11
+ */
12
+ declare function getNFTBalance(chainId: ChainId, nftContractName: NftContractNames, owner: string, provider: Provider): Promise<bigint>;
13
+ export default getNFTBalance;
@@ -0,0 +1,15 @@
1
+ import { ethers, Signer } from "ethers";
2
+ import { ChainId } from "../configs/chains/index";
3
+ import { NftContractNames } from "./approveNFT";
4
+ /**
5
+ * Transfer an NFT from the signer to another address with safeTransferFrom
6
+ * Do not use it to put a Bot NFT into the bot locker: the locker only records NFTs deposited through `lockers.botLocker.lock`.
7
+ * @param chainId - The chain ID
8
+ * @param nftContractName - The NFT contract name from configs
9
+ * @param to - The recipient address
10
+ * @param tokenId - The token ID to transfer
11
+ * @param signer - The signer that owns the token
12
+ * @returns Transaction receipt
13
+ */
14
+ declare function transferNFT(chainId: ChainId, nftContractName: NftContractNames, to: string, tokenId: string | number | bigint, signer: Signer): Promise<ethers.ContractTransactionReceipt>;
15
+ export default transferNFT;
@@ -117,6 +117,56 @@ declare const ABIS: {
117
117
  type: string;
118
118
  anonymous?: undefined;
119
119
  })[];
120
+ raacbotnft: ({
121
+ inputs: {
122
+ internalType: string;
123
+ name: string;
124
+ type: string;
125
+ }[];
126
+ stateMutability: string;
127
+ type: string;
128
+ name?: undefined;
129
+ anonymous?: undefined;
130
+ outputs?: undefined;
131
+ } | {
132
+ inputs: {
133
+ internalType: string;
134
+ name: string;
135
+ type: string;
136
+ }[];
137
+ name: string;
138
+ type: string;
139
+ stateMutability?: undefined;
140
+ anonymous?: undefined;
141
+ outputs?: undefined;
142
+ } | {
143
+ anonymous: boolean;
144
+ inputs: {
145
+ indexed: boolean;
146
+ internalType: string;
147
+ name: string;
148
+ type: string;
149
+ }[];
150
+ name: string;
151
+ type: string;
152
+ stateMutability?: undefined;
153
+ outputs?: undefined;
154
+ } | {
155
+ inputs: {
156
+ internalType: string;
157
+ name: string;
158
+ type: string;
159
+ }[];
160
+ name: string;
161
+ outputs: {
162
+ internalType: string;
163
+ name: string;
164
+ type: string;
165
+ }[];
166
+ stateMutability: string;
167
+ type: string;
168
+ anonymous?: undefined;
169
+ })[];
120
170
  raactoken: ({
121
171
  inputs: {
122
172
  internalType: string;
@@ -4937,6 +4987,55 @@ declare const getABI: (name: keyof typeof ABIS) => any[] | ({
4937
4987
  stateMutability: string;
4938
4988
  type: string;
4939
4989
  anonymous?: undefined;
4990
+ })[] | ({
4991
+ inputs: {
4992
+ internalType: string;
4993
+ name: string;
4994
+ type: string;
4995
+ }[];
4996
+ stateMutability: string;
4997
+ type: string;
4998
+ name?: undefined;
4999
+ anonymous?: undefined;
5000
+ outputs?: undefined;
5001
+ } | {
5002
+ inputs: {
5003
+ internalType: string;
5004
+ name: string;
5005
+ type: string;
5006
+ }[];
5007
+ name: string;
5008
+ type: string;
5009
+ stateMutability?: undefined;
5010
+ anonymous?: undefined;
5011
+ outputs?: undefined;
5012
+ } | {
5013
+ anonymous: boolean;
5014
+ inputs: {
5015
+ indexed: boolean;
5016
+ internalType: string;
5017
+ name: string;
5018
+ type: string;
5019
+ }[];
5020
+ name: string;
5021
+ type: string;
5022
+ stateMutability?: undefined;
5023
+ outputs?: undefined;
5024
+ } | {
5025
+ inputs: {
5026
+ internalType: string;
5027
+ name: string;
5028
+ type: string;
5029
+ }[];
5030
+ name: string;
5031
+ outputs: {
5032
+ internalType: string;
5033
+ name: string;
5034
+ type: string;
5035
+ }[];
5036
+ stateMutability: string;
5037
+ type: string;
5038
+ anonymous?: undefined;
4940
5039
  })[] | ({
4941
5040
  inputs: any[];
4942
5041
  stateMutability: string;
@@ -26,3 +26,13 @@ export declare function decodeRevertWithAbi(abi: Interface | InterfaceAbi, data?
26
26
  * @returns The error name and its decoded arguments, or null if no known contract declares that selector.
27
27
  */
28
28
  export declare function decodeRevertWithAllAbis(data?: string): DecodedRevert | null;
29
+ /**
30
+ * Names the custom error behind a bare 4-byte selector, for when a wallet or
31
+ * client surfaced the selector but not the full revert data (so the arguments
32
+ * cannot be decoded). Looks in `abi` first, then in every known ABI.
33
+ *
34
+ * @param selector The 4-byte error selector, e.g. "0x79db4619".
35
+ * @param abi The ABI of the contract that was called, when known.
36
+ * @returns The error name, or null if no known contract declares that selector.
37
+ */
38
+ export declare function errorNameForSelector(selector: string, abi?: Interface | InterfaceAbi): string | null;
@@ -52,6 +52,7 @@ const pmBlender_json_1 = __importDefault(require("../artifacts/core/pmBlender/pm
52
52
  const RAACLiquidLocker_json_1 = __importDefault(require("../artifacts/core/lockers/RAACLiquidLocker.sol/RAACLiquidLocker.json"));
53
53
  const RAACMaturityVault_json_1 = __importDefault(require("../artifacts/core/lockers/RAACMaturityVault.sol/RAACMaturityVault.json"));
54
54
  const RAACBotLocker_json_1 = __importDefault(require("../artifacts/core/lockers/RAACBotLocker.sol/RAACBotLocker.json"));
55
+ const ERC721Mock_json_1 = __importDefault(require("../artifacts/mocks/core/tokens/ERC721Mock.sol/ERC721Mock.json"));
55
56
  // leRAAC token
56
57
  const LiquidEscrowedRAAC_json_1 = __importDefault(require("../artifacts/core/tokens/LeRAAC.sol/LiquidEscrowedRAAC.json"));
57
58
  // Zap
@@ -95,6 +96,8 @@ const ABIS = {
95
96
  xpm: XPM_ABI,
96
97
  // RAAC
97
98
  raacnft: RAACNFT_ABI,
99
+ // Standard OpenZeppelin ERC721 ABI; the Bot NFT is a plain ERC721 with no RAAC-specific functions
100
+ raacbotnft: ERC721Mock_json_1.default.abi,
98
101
  raactoken: RAACToken_ABI,
99
102
  veraac: VERAAC_ABI,
100
103
  // Pools tokens