Skip to content

Commit

Permalink
feat: support arbitrum
Browse files Browse the repository at this point in the history
add suport for the arbitrum network
  • Loading branch information
jackmellis committed Mar 20, 2024
1 parent 1bfad43 commit bc356ad
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 167 deletions.
2 changes: 2 additions & 0 deletions packages/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,13 @@ const defaultConfig: Config = {
[Network.Mainnet]: 0,
[Network.Goerli]: 0,
[Network.Sepolia]: 0,
[Network.Arbitrum]: 0,
},
apiBlockNumber: {
[Network.Mainnet]: 0,
[Network.Goerli]: 0,
[Network.Sepolia]: 0,
[Network.Arbitrum]: 0,
},
blockBuffer: 10,
},
Expand Down
12 changes: 11 additions & 1 deletion packages/constants/src/addresses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,48 +48,55 @@ export const CREATE_VAULT_ZAP = {
[Network.Mainnet]: a('0x56dab32697B4A313f353DA0CE42B5113eD8E6f74'),
[Network.Goerli]: a('0xc6464CC63bC20b64e1633A0293C2C9b202F4f1b6'),
[Network.Sepolia]: a('0xD80b916470F8e79FD8d09874cb159CbB8D13d8da'),
[Network.Arbitrum]: a('0xF9E891AB1ECa89B7A4B3cBD45aEBFDF3Ec38946F'),
};

/** Perform buy/sell/swaps - MarketplaceUniversalRouterZap */
export const MARKETPLACE_ZAP = {
[Network.Mainnet]: a('0x293A0c49c85F1D8851C665Ac3cE1f1DC2a79bE3d'),
[Network.Goerli]: a('0x0be2D766Eef4b6a72F1fAe2e49619F013d647B8A'),
[Network.Sepolia]: a('0xd88a3B9D0Fb2d39ec8394CfFD983aFBB2D4a6410'),
[Network.Arbitrum]: a('0xf56296B3010a59Ef7F0915569DD44E1302b9Ca40'),
};

/** Stake NFTs or vTokens for xNFTs - NFTXInventoryStakingV3Upgradable */
export const INVENTORY_STAKING = {
[Network.Mainnet]: a('0x889f313e2a3FDC1c9a45bC6020A8a18749CD6152'),
[Network.Goerli]: a('0xEf771a17e6970d8B4b208a76e94F175277554230'),
[Network.Sepolia]: a('0xfBFf0635f7c5327FD138E1EBa72BD9877A6a7C1C'),
[Network.Arbitrum]: a('0xe39a7E67d3E3b6eAF58BC02C4E80C3688847d155'),
};

/** AMM Router - nftxUniversalRouter */
export const NFTX_ROUTER = {
[Network.Mainnet]: a('0x250d62a67254A46c0De472d2c9215E1d890cC90f'),
[Network.Goerli]: a('0xF7c4FC5C2e30258e1E4d1197fc63aeDE371508f3'),
[Network.Sepolia]: a('0x12156cCA1958B6591CC49EaE03a5553458a4b424'),
[Network.Arbitrum]: a('0x4529ad73b2cc8d4db0b0deba90de165e35c4b628'),
};

/** Staking / Liquidity / Pools - NftxRouter */
export const POOL_ROUTER = {
[Network.Mainnet]: a('0x70A741A12262d4b5Ff45C0179c783a380EebE42a'),
[Network.Goerli]: a('0x8E16cdd0D9A15d2d0EFeA531660e8DbD0F6eE12D'),
[Network.Sepolia]: a('0x441b7DE4340AAa5aA86dB4DA43d9Badf7B2DAA66'),
[Network.Arbitrum]: a('0x52731751Dede22827ad47109f5e9697d75a3ef4d'),
};

/** NonfungiblePositionManager */
export const NONFUNGIBLE_POSITION_MANAGER = {
[Network.Mainnet]: a('0x26387fcA3692FCac1C1e8E4E2B22A6CF0d4b71bF'),
[Network.Goerli]: a('0xDa9411C5455a1bfDb527d0988c0A2764E2a104be'),
[Network.Sepolia]: a('0xA9bCC1e29d3460177875f68fDCC0264D22c40BF0'),
[Network.Arbitrum]: a('0x8AD238377531547838370B9C4aC346b9Ed5466Ea'),
};

/** The permit2 contract, needs an approval signature because the UniversalRouter only transfers tokens from user via Permit2 */
export const PERMIT2 = {
[Network.Mainnet]: a('0x000000000022d473030f116ddee9f6b43ac78ba3'),
[Network.Goerli]: a('0x000000000022d473030f116ddee9f6b43ac78ba3'),
[Network.Sepolia]: a('0x000000000022d473030f116ddee9f6b43ac78ba3'),
[Network.Arbitrum]: a('0x000000000022d473030f116ddee9f6b43ac78ba3'),
};

/** ENS Address */
Expand All @@ -105,18 +112,21 @@ export const AMM_FACTORY = {
[Network.Mainnet]: a('0xa70e10beB02fF9a44007D9D3695d4b96003db101'),
[Network.Goerli]: a('0xf25081B098c5929A26F562aa2502795fE89BC73f'),
[Network.Sepolia]: a('0xDD2dce9C403f93c10af1846543870D065419E70b'),
[Network.Arbitrum]: a('0xF4D0512FB47319B0CE9144EF582862e2921CaBF8'),
};

/** NFTXVaultFactoryUpgradableV2 */
/** NFTXVaultFactoryUpgradableV3 */
export const VAULT_FACTORY = {
[Network.Mainnet]: a('0xC255335bc5aBd6928063F5788a5E420554858f01'),
[Network.Goerli]: a('0x1d552A0e6c2f680872C4a88b1e7def05F1858dF0'),
[Network.Sepolia]: a('0x31C56CaF49125043e80B4d3C7f8734f949d8178C'),
[Network.Arbitrum]: a('0x4dEeb9D2Bff2e9C35ce1f013DcC4582F891cb711'),
};

/** NftxFeeDistributorV3 */
export const NFTX_FEE_DISTRIBUTOR = {
[Network.Mainnet]: a('0xF4d96C5094FCD9eC24E612585e723b58F89e21fe'),
[Network.Sepolia]: a('0x66EF5B4b6ee05639194844CE4867515665F14fED'),
[Network.Goerli]: a('0xA8076Ec5Dbb95165e14624Ff43dE2290e78A6905'),
[Network.Arbitrum]: a('0x0d50970C7848ebbE52661e70057D7D063B7de886'),
};
6 changes: 4 additions & 2 deletions packages/constants/src/subgraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const NON_STANDARD_SUBGRAPH = {
export const ERC721_SUBGRAPH = {
[Network.Mainnet]:
'https://gateway-arbitrum.network.thegraph.com/api/49f332ad234c93d2f07d2c085f1ca6d6/subgraphs/id/CBf1FtUKFnipwKVm36mHyeMtkuhjmh4KHzY3uWNNq5ow',
[Network.Arbitrum]: `${SHARED_PROXY_ROOT}/quantumlyy/eip721-subgraph-arbitrum`,
[Network.Arbitrum]:
'https://api.thegraph.com/subgraphs/name/nftx-project/721-arbitrum-data-nexus',
[Network.Goerli]:
'https://api.thegraph.com/subgraphs/name/nftx-project/eip721-looksrare-goerli',
[Network.Sepolia]:
Expand All @@ -28,7 +29,8 @@ export const ERC721_SUBGRAPH = {
export const ERC1155_SUBGRAPH = {
[Network.Mainnet]:
'https://gateway-arbitrum.network.thegraph.com/api/49f332ad234c93d2f07d2c085f1ca6d6/subgraphs/id/5C6JRVzKcE9AVbT7S71EycV8eEGcfkJB9gGsyTbHMVmN',
[Network.Arbitrum]: `${SHARED_PROXY_ROOT}/quantumlyy/eip1155-subgraph-arbitrum`,
[Network.Arbitrum]:
'https://api.thegraph.com/subgraphs/name/nftx-project/1155-arbitrum-data-nexus',
[Network.Goerli]:
'https://api.thegraph.com/subgraphs/name/nftx-project/eip1155-looksrare-goerli',
[Network.Sepolia]:
Expand Down
4 changes: 4 additions & 0 deletions packages/constants/src/ticks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,26 @@ export const RFBR_MIN_PRICE = {
[Network.Mainnet]: 100000000000000n,
[Network.Goerli]: 100000000000000n,
[Network.Sepolia]: 100000000000000n,
[Network.Arbitrum]: 100000000000000n,
};
// 10,000 ETH
export const RFBR_MAX_PRICE = {
[Network.Mainnet]: 10000000000000000000000n,
[Network.Goerli]: 10000000000000000000000n,
[Network.Sepolia]: 10000000000000000000000n,
[Network.Arbitrum]: 10000000000000000000000n,
};
export const RFBR_MIN_TICK = {
[Network.Mainnet]: -92160,
[Network.Goerli]: -92160,
[Network.Sepolia]: -92160,
[Network.Arbitrum]: -92160,
};
export const RFBR_MAX_TICK = {
[Network.Mainnet]: 92100,
[Network.Goerli]: 92100,
[Network.Sepolia]: 92100,
[Network.Arbitrum]: 92100,
};

// This is the "absolute" max/min ticks that can be used
Expand Down
1 change: 1 addition & 0 deletions packages/constants/src/urls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const NFTX_ROUTER_URL = {
[Network.Mainnet]: 'https://api.nftx.xyz/v3/eth-mainnet/quote',
[Network.Goerli]: 'https://api.nftx.xyz/v3/eth-goerli/quote',
[Network.Sepolia]: 'https://api.nftx.xyz/v3/eth-sepolia/quote',
[Network.Arbitrum]: 'https://api.nftx.xyz/v3/arbitrum-one/quote',
};

export const NFTX_APR_URL = {
Expand Down
1 change: 1 addition & 0 deletions packages/constants/src/values.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const MaxUint256 =

export const PREMIUM_DURATION = {
[Network.Mainnet]: 36000, // 10 hours
[Network.Arbitrum]: 36000, // 10 hours
[Network.Goerli]: 36000, // 10 hours
[Network.Sepolia]: 3600, // 1 hour
};
56 changes: 3 additions & 53 deletions packages/core/src/assets/fetchUserHoldings/fetchErc1155s.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import config from '@nftx/config';
import { createQuery, gql, querySubgraph } from '@nftx/subgraph';
import type { Address, ERC1155Sepolia, TokenId } from '@nftx/types';
import type { Address, ERC1155, TokenId } from '@nftx/types';
import { getChainConstant } from '@nftx/utils';
import { createCursor, parseCursor } from './cursor';
import type { Holding } from './types';
Expand All @@ -22,7 +22,7 @@ const fetchErc1155sMainnet = async ({
let holdings: Array<Holding> = [];
let nextId: string | undefined;

const q = createQuery<ERC1155Sepolia.Query>();
const q = createQuery<ERC1155.Query>();

const query = q.account.id(userAddress).select((s) => [
s.holdings(
Expand Down Expand Up @@ -60,57 +60,7 @@ const fetchErc1155sMainnet = async ({
return [holdings, nextId] as const;
};

const fetchErc1155sSepolia = async ({
lastId,
network,
userAddress,
querySubgraph,
}: {
network: number;
lastId: string;
userAddress: Address;
querySubgraph: QuerySubgraph;
}) => {
let holdings: Array<Holding> = [];
let nextId: string | undefined;

const q = createQuery<ERC1155Sepolia.Query>();

const query = q.account.id(userAddress).select((s) => [
s.holdings(
q.holdings
.first(1000)
.orderBy('id')
.orderDirection('asc')
.where((w) => [w.id.gt(lastId), w.balance.gt('0')])
.select((s) => [
s.id,
s.balance,
s.token((t) => [t.identifier, t.collection((c) => [c.id])]),
])
),
]);

const data = await querySubgraph({
url: getChainConstant(config.subgraph.ERC1155_SUBGRAPH, network),
query,
});

if (data?.account?.holdings?.length) {
holdings = data.account.holdings.map((x) => {
return {
assetAddress: x.token.collection.id as Address,
tokenId: BigInt(x.token.identifier).toString() as TokenId,
quantity: BigInt(x.balance || '1'),
};
});
}
if (data?.account?.holdings?.length === 1000) {
nextId = data.account.holdings[data.account.holdings.length - 1].id;
}

return [holdings, nextId] as const;
};
const fetchErc1155sSepolia = fetchErc1155sMainnet;

const fetchErc1155sGoerli = async ({
lastId,
Expand Down
112 changes: 4 additions & 108 deletions packages/core/src/assets/fetchUserHoldings/fetchErc721s.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Address, ERC721Mainnet, ERC721Sepolia, TokenId } from '@nftx/types';
import { Address, ERC721, TokenId } from '@nftx/types';
import { createCursor, parseCursor } from './cursor';
import { Network } from '@nftx/constants';
import { createQuery, gql, querySubgraph } from '@nftx/subgraph';
Expand All @@ -22,7 +22,7 @@ const fetchErc721sMainnet = async ({
let holdings: Holding[] = [];
let nextId: string | undefined;

const query = createQuery<ERC721Mainnet.Query>()
const query = createQuery<ERC721.Query>()
.tokens.where((w) => [w.owner.is(userAddress), w.id.gt(lastId)])
.orderBy('id')
.orderDirection('asc')
Expand Down Expand Up @@ -50,47 +50,7 @@ const fetchErc721sMainnet = async ({
return [holdings, nextId] as const;
};

const fetchErc721sSepolia = async ({
network,
lastId,
userAddress,
querySubgraph,
}: {
network: number;
lastId: string;
userAddress: Address;
querySubgraph: QuerySubgraph;
}) => {
let holdings: Holding[] = [];
let nextId: string | undefined;

const query = createQuery<ERC721Sepolia.Query>()
.tokens.where((w) => [w.owner.is(userAddress), w.id.gt(lastId)])
.orderBy('id')
.orderDirection('asc')
.first(1000)
.select((s) => [s.id, s.collection((c) => [c.id]), s.identifier]);

const data = await querySubgraph({
url: getChainConstant(config.subgraph.ERC721_SUBGRAPH, network),
query,
});

if (data?.tokens?.length) {
holdings = data.tokens.map((x) => {
return {
assetAddress: x.collection.id as Address,
tokenId: BigInt(x.identifier).toString() as TokenId,
quantity: 1n,
};
});
}
if (data?.tokens?.length === 1000) {
nextId = data.tokens[data.tokens.length - 1].id;
}

return [holdings, nextId] as const;
};
const fetchErc721sSepolia = fetchErc721sMainnet;

const fetchErc721sGoerli = async ({
lastId,
Expand Down Expand Up @@ -161,71 +121,7 @@ const fetchErc721sGoerli = async ({
return [holdings, nextId] as const;
};

const fetchErc721sArbitrum = async ({
network,
lastId,
userAddress,
querySubgraph,
}: {
network: number;
lastId: string;
userAddress: Address;
querySubgraph: QuerySubgraph;
}) => {
let holdings: Array<Holding> = [];
let nextId: string | undefined;

type Response = {
account: {
id: Address;
tokens: Array<{
id: Address;
identifier: `${number}`;
contract: { id: Address };
}>;
};
};
type Params = { userAddress: Address; lastId: string };

const query = gql<Response, Params>`
{
account(id: $userAddress) {
id
tokens: ERC721tokens(
first: 1000
where: { identifier_gt: $lastId }
orderBy: identifier
orderDirection: asc
) {
id
identifier
contract {
id
}
}
}
}
`;

const data = await querySubgraph({
url: getChainConstant(config.subgraph.ERC721_SUBGRAPH, network),
query,
variables: { lastId, userAddress },
});

if (data?.account?.tokens?.length) {
holdings = data.account.tokens.map((x) => ({
assetAddress: x.contract.id,
tokenId: BigInt(x.identifier).toString() as TokenId,
quantity: 1n,
}));
}
if (data?.account?.tokens?.length === 1000) {
nextId = data.account.tokens[data.account.tokens.length - 1].identifier;
}

return [holdings, nextId] as const;
};
const fetchErc721sArbitrum = fetchErc721sMainnet;

export const makeFetchErc721s =
({ querySubgraph }: { querySubgraph: QuerySubgraph }) =>
Expand Down
14 changes: 11 additions & 3 deletions packages/core/src/positions/fetchLiquidityPositions/getManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,18 @@ const getPoolRouterAddress = (network: number, managerAddress: Address) => {
);
};

const getManager = (network: number, position: { nfpmAddress: string }) => {
const manager =
const getManagerAddress = (
network: number,
position: { nfpmAddress: string }
) => {
return (
(position.nfpmAddress as Address) ||
getChainConstant(NONFUNGIBLE_POSITION_MANAGER, network);
getChainConstant(NONFUNGIBLE_POSITION_MANAGER, network)
);
};

const getManager = (network: number, position: { nfpmAddress: string }) => {
const manager = getManagerAddress(network, position);
const poolRouter = getPoolRouterAddress(network, manager);
return { manager, poolRouter };
};
Expand Down
1 change: 1 addition & 0 deletions packages/queue/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const NETWORK_QUEUE_NAMES = {
[Network.Mainnet]: 'indexer-workers-mainnet',
[Network.Goerli]: 'indexer-workers-goerli',
[Network.Sepolia]: 'indexer-workers-sepolia',
[Network.Arbitrum]: 'indexer-workers-arbitrum',
};

export const SIGNAL_QUEUE_NAME = 'indexer-signals';
Expand Down

0 comments on commit bc356ad

Please sign in to comment.