@metamask-previews/assets-controllers 103.1.1-preview-6e596eb → 103.1.1-preview-61580fcee
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/CHANGELOG.md +0 -7
- package/dist/NftController.cjs +74 -44
- package/dist/NftController.cjs.map +1 -1
- package/dist/NftController.d.cts +17 -9
- package/dist/NftController.d.cts.map +1 -1
- package/dist/NftController.d.mts +17 -9
- package/dist/NftController.d.mts.map +1 -1
- package/dist/NftController.mjs +74 -44
- package/dist/NftController.mjs.map +1 -1
- package/dist/multicall.cjs +1 -220
- package/dist/multicall.cjs.map +1 -1
- package/dist/multicall.d.cts +0 -22
- package/dist/multicall.d.cts.map +1 -1
- package/dist/multicall.d.mts +0 -22
- package/dist/multicall.d.mts.map +1 -1
- package/dist/multicall.mjs +0 -218
- package/dist/multicall.mjs.map +1 -1
- package/dist/token-prices-service/codefi-v2.d.cts +1 -1
- package/dist/token-prices-service/codefi-v2.d.mts +1 -1
- package/package.json +1 -1
package/dist/multicall.d.cts
CHANGED
|
@@ -73,26 +73,4 @@ export declare const getTokenBalancesForMultipleAddresses: (accountTokenGroups:
|
|
|
73
73
|
tokenBalances: Record<string, Record<string, BN>>;
|
|
74
74
|
stakedBalances?: Record<string, BN>;
|
|
75
75
|
}>;
|
|
76
|
-
export type NftOwnershipQuery = {
|
|
77
|
-
nftAddress: string;
|
|
78
|
-
tokenId: string;
|
|
79
|
-
userAddress: string;
|
|
80
|
-
standard: string | null;
|
|
81
|
-
};
|
|
82
|
-
export type NftOwnershipResult = {
|
|
83
|
-
nftAddress: string;
|
|
84
|
-
tokenId: string;
|
|
85
|
-
isOwned: boolean | undefined;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Check ownership for multiple NFTs, using Multicall3 when available to batch
|
|
89
|
-
* all calls into a single RPC request, falling back to individual calls otherwise.
|
|
90
|
-
*
|
|
91
|
-
* @param nfts - Array of NFT queries containing address, tokenId, owner address, and standard.
|
|
92
|
-
* @param chainId - The hexadecimal chain id.
|
|
93
|
-
* @param provider - An ethers rpc provider.
|
|
94
|
-
* @returns Promise resolving to array of ownership results. `isOwned` is `undefined`
|
|
95
|
-
* when ownership could not be determined (e.g. unsupported standard or RPC error).
|
|
96
|
-
*/
|
|
97
|
-
export declare const getNftOwnershipForMultipleNfts: (nfts: NftOwnershipQuery[], chainId: Hex, provider: Web3Provider) => Promise<NftOwnershipResult[]>;
|
|
98
76
|
//# sourceMappingURL=multicall.d.cts.map
|
package/dist/multicall.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicall.d.cts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;AAqXvB,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"multicall.d.cts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;AAqXvB,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA0HF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,UACvB,IAAI,EAAE,WACJ,GAAG,YACF,YAAY,+DAGrB,QAAQ,eAAe,EAAE,CA6B3B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,UACd,cAAc,EAAE,WACd,GAAG,YACF,YAAY,KACrB,QAAQ,gBAAgB,EAAE,CAa5B,CAAC;AAoQF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,kBACzB,MAAM,EAAE,WACd,GAAG,YACF,YAAY,KACrB,QAAQ,OAAO,MAAM,EAAE,EAAE,CAAC,CAmF5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oCAAoC,uBAC3B;IAAE,cAAc,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,EAAE,CAAA;CAAE,EAAE,WAC3D,GAAG,YACF,YAAY,iBACP,OAAO,iBACP,OAAO,KACrB,QAAQ;IACT,aAAa,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAClD,cAAc,CAAC,EAAE,OAAO,MAAM,EAAE,EAAE,CAAC,CAAC;CACrC,CAkMA,CAAC"}
|
package/dist/multicall.d.mts
CHANGED
|
@@ -73,26 +73,4 @@ export declare const getTokenBalancesForMultipleAddresses: (accountTokenGroups:
|
|
|
73
73
|
tokenBalances: Record<string, Record<string, BN>>;
|
|
74
74
|
stakedBalances?: Record<string, BN>;
|
|
75
75
|
}>;
|
|
76
|
-
export type NftOwnershipQuery = {
|
|
77
|
-
nftAddress: string;
|
|
78
|
-
tokenId: string;
|
|
79
|
-
userAddress: string;
|
|
80
|
-
standard: string | null;
|
|
81
|
-
};
|
|
82
|
-
export type NftOwnershipResult = {
|
|
83
|
-
nftAddress: string;
|
|
84
|
-
tokenId: string;
|
|
85
|
-
isOwned: boolean | undefined;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Check ownership for multiple NFTs, using Multicall3 when available to batch
|
|
89
|
-
* all calls into a single RPC request, falling back to individual calls otherwise.
|
|
90
|
-
*
|
|
91
|
-
* @param nfts - Array of NFT queries containing address, tokenId, owner address, and standard.
|
|
92
|
-
* @param chainId - The hexadecimal chain id.
|
|
93
|
-
* @param provider - An ethers rpc provider.
|
|
94
|
-
* @returns Promise resolving to array of ownership results. `isOwned` is `undefined`
|
|
95
|
-
* when ownership could not be determined (e.g. unsupported standard or RPC error).
|
|
96
|
-
*/
|
|
97
|
-
export declare const getNftOwnershipForMultipleNfts: (nfts: NftOwnershipQuery[], chainId: Hex, provider: Web3Provider) => Promise<NftOwnershipResult[]>;
|
|
98
76
|
//# sourceMappingURL=multicall.d.mts.map
|
package/dist/multicall.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multicall.d.mts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;AAqXvB,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;
|
|
1
|
+
{"version":3,"file":"multicall.d.mts","sourceRoot":"","sources":["../src/multicall.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iCAAiC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,iCAAiC;AAC7D,OAAO,KAAK,EAAE,GAAG,EAAE,wBAAwB;AAC3C,OAAO,EAAE,cAAc;AAqXvB,MAAM,MAAM,IAAI,GAAG;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnE,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AA0HF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,UACvB,IAAI,EAAE,WACJ,GAAG,YACF,YAAY,+DAGrB,QAAQ,eAAe,EAAE,CA6B3B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,UACd,cAAc,EAAE,WACd,GAAG,YACF,YAAY,KACrB,QAAQ,gBAAgB,EAAE,CAa5B,CAAC;AAoQF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,kBACzB,MAAM,EAAE,WACd,GAAG,YACF,YAAY,KACrB,QAAQ,OAAO,MAAM,EAAE,EAAE,CAAC,CAmF5B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oCAAoC,uBAC3B;IAAE,cAAc,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,EAAE,CAAA;CAAE,EAAE,WAC3D,GAAG,YACF,YAAY,iBACP,OAAO,iBACP,OAAO,KACrB,QAAQ;IACT,aAAa,EAAE,OAAO,MAAM,EAAE,OAAO,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAClD,cAAc,CAAC,EAAE,OAAO,MAAM,EAAE,EAAE,CAAC,CAAC;CACrC,CAkMA,CAAC"}
|
package/dist/multicall.mjs
CHANGED
|
@@ -377,34 +377,9 @@ const multicall3Abi = [
|
|
|
377
377
|
// Constants for encoded strings and addresses
|
|
378
378
|
const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
379
379
|
const BALANCE_OF_FUNCTION = 'balanceOf(address)';
|
|
380
|
-
const OWNER_OF_FUNCTION = 'ownerOf(uint256)';
|
|
381
|
-
const ERC1155_BALANCE_OF_FUNCTION = 'balanceOf(address,uint256)';
|
|
382
380
|
const GET_ETH_BALANCE_FUNCTION = 'getEthBalance';
|
|
383
381
|
const GET_SHARES_FUNCTION = 'getShares';
|
|
384
382
|
const CONVERT_TO_ASSETS_FUNCTION = 'convertToAssets';
|
|
385
|
-
// ERC-721 ownerOf ABI
|
|
386
|
-
const ERC721_OWNER_OF_ABI = [
|
|
387
|
-
{
|
|
388
|
-
name: 'ownerOf',
|
|
389
|
-
type: 'function',
|
|
390
|
-
inputs: [{ name: 'tokenId', type: 'uint256' }],
|
|
391
|
-
outputs: [{ name: 'owner', type: 'address' }],
|
|
392
|
-
stateMutability: 'view',
|
|
393
|
-
},
|
|
394
|
-
];
|
|
395
|
-
// ERC-1155 balanceOf ABI
|
|
396
|
-
const ERC1155_BALANCE_OF_ABI = [
|
|
397
|
-
{
|
|
398
|
-
name: 'balanceOf',
|
|
399
|
-
type: 'function',
|
|
400
|
-
inputs: [
|
|
401
|
-
{ name: 'account', type: 'address' },
|
|
402
|
-
{ name: 'id', type: 'uint256' },
|
|
403
|
-
],
|
|
404
|
-
outputs: [{ name: 'balance', type: 'uint256' }],
|
|
405
|
-
stateMutability: 'view',
|
|
406
|
-
},
|
|
407
|
-
];
|
|
408
383
|
// ERC20 balanceOf ABI
|
|
409
384
|
const ERC20_BALANCE_OF_ABI = [
|
|
410
385
|
{
|
|
@@ -891,197 +866,4 @@ export const getTokenBalancesForMultipleAddresses = async (accountTokenGroups, c
|
|
|
891
866
|
return result;
|
|
892
867
|
}
|
|
893
868
|
};
|
|
894
|
-
const normalizeNftStandard = (standard) => {
|
|
895
|
-
if (!standard) {
|
|
896
|
-
return null;
|
|
897
|
-
}
|
|
898
|
-
const upper = standard.toUpperCase();
|
|
899
|
-
if (upper === 'ERC721') {
|
|
900
|
-
return 'ERC721';
|
|
901
|
-
}
|
|
902
|
-
if (upper === 'ERC1155') {
|
|
903
|
-
return 'ERC1155';
|
|
904
|
-
}
|
|
905
|
-
return null;
|
|
906
|
-
};
|
|
907
|
-
const getNftOwnershipViaMulticall = async (nfts, chainId, provider) => {
|
|
908
|
-
const erc721Contract = new Contract(ZERO_ADDRESS, ERC721_OWNER_OF_ABI, provider);
|
|
909
|
-
const erc1155Contract = new Contract(ZERO_ADDRESS, ERC1155_BALANCE_OF_ABI, provider);
|
|
910
|
-
const calls = [];
|
|
911
|
-
const meta = [];
|
|
912
|
-
// When the standard is known, emit only the relevant call to halve the number
|
|
913
|
-
// of multicall subcalls. When unknown (null), emit both — ERC-721 first so
|
|
914
|
-
// the `!== undefined` guard below replicates the original early-return
|
|
915
|
-
// behavior: once ERC-721 gives a definitive answer, ERC-1155 is skipped.
|
|
916
|
-
nfts.forEach(({ nftAddress, tokenId, userAddress, standard }, i) => {
|
|
917
|
-
const normalized = normalizeNftStandard(standard);
|
|
918
|
-
const tryErc721 = normalized !== 'ERC1155';
|
|
919
|
-
const tryErc1155 = normalized !== 'ERC721';
|
|
920
|
-
if (tryErc721) {
|
|
921
|
-
calls.push({
|
|
922
|
-
target: nftAddress,
|
|
923
|
-
allowFailure: true,
|
|
924
|
-
callData: erc721Contract.interface.encodeFunctionData(OWNER_OF_FUNCTION, [tokenId]),
|
|
925
|
-
});
|
|
926
|
-
meta.push({ nftIndex: i, callVariant: 'erc721' });
|
|
927
|
-
}
|
|
928
|
-
if (tryErc1155) {
|
|
929
|
-
calls.push({
|
|
930
|
-
target: nftAddress,
|
|
931
|
-
allowFailure: true,
|
|
932
|
-
callData: erc1155Contract.interface.encodeFunctionData(ERC1155_BALANCE_OF_FUNCTION, [userAddress, tokenId]),
|
|
933
|
-
});
|
|
934
|
-
meta.push({ nftIndex: i, callVariant: 'erc1155' });
|
|
935
|
-
}
|
|
936
|
-
});
|
|
937
|
-
const maxCallsPerBatch = 300;
|
|
938
|
-
const allReturnData = [];
|
|
939
|
-
// Batches are processed serially and results are pushed in order, so
|
|
940
|
-
// allReturnData[i] always corresponds to meta[i]. Do NOT change this to
|
|
941
|
-
// parallel batching without also reworking the index correspondence.
|
|
942
|
-
await reduceInBatchesSerially({
|
|
943
|
-
values: calls,
|
|
944
|
-
batchSize: maxCallsPerBatch,
|
|
945
|
-
initialResult: undefined,
|
|
946
|
-
eachBatch: async (_, batch) => {
|
|
947
|
-
const batchResults = await aggregate3(batch, chainId, provider);
|
|
948
|
-
allReturnData.push(...batchResults);
|
|
949
|
-
},
|
|
950
|
-
});
|
|
951
|
-
const results = nfts.map(({ nftAddress, tokenId }) => ({
|
|
952
|
-
nftAddress,
|
|
953
|
-
tokenId,
|
|
954
|
-
isOwned: undefined,
|
|
955
|
-
}));
|
|
956
|
-
allReturnData.forEach(({ success, returnData: data }, i) => {
|
|
957
|
-
if (!success) {
|
|
958
|
-
return;
|
|
959
|
-
}
|
|
960
|
-
const { nftIndex, callVariant } = meta[i];
|
|
961
|
-
if (results[nftIndex].isOwned !== undefined) {
|
|
962
|
-
return;
|
|
963
|
-
}
|
|
964
|
-
try {
|
|
965
|
-
if (callVariant === 'erc721') {
|
|
966
|
-
const [owner] = erc721Contract.interface.decodeFunctionResult(OWNER_OF_FUNCTION, data);
|
|
967
|
-
results[nftIndex].isOwned =
|
|
968
|
-
owner.toLowerCase() === nfts[nftIndex].userAddress.toLowerCase();
|
|
969
|
-
}
|
|
970
|
-
else {
|
|
971
|
-
const [balance] = erc1155Contract.interface.decodeFunctionResult(ERC1155_BALANCE_OF_FUNCTION, data);
|
|
972
|
-
results[nftIndex].isOwned = new BN(balance.toString()).gt(new BN(0));
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
catch {
|
|
976
|
-
// Malformed return data from a non-standard contract; leave isOwned as undefined.
|
|
977
|
-
}
|
|
978
|
-
});
|
|
979
|
-
return results;
|
|
980
|
-
};
|
|
981
|
-
const MAX_PARALLEL_NFT_CALLS = 50;
|
|
982
|
-
const getNftOwnershipIndividually = async (nfts, provider) => {
|
|
983
|
-
const erc721Iface = new Contract(ZERO_ADDRESS, ERC721_OWNER_OF_ABI, provider)
|
|
984
|
-
.interface;
|
|
985
|
-
const erc1155Iface = new Contract(ZERO_ADDRESS, ERC1155_BALANCE_OF_ABI, provider).interface;
|
|
986
|
-
return reduceInBatchesSerially({
|
|
987
|
-
values: nfts,
|
|
988
|
-
batchSize: MAX_PARALLEL_NFT_CALLS,
|
|
989
|
-
initialResult: [],
|
|
990
|
-
eachBatch: async (workingResult, batch) => {
|
|
991
|
-
const batchResults = await Promise.all(batch.map(async ({ nftAddress, tokenId, userAddress, standard }) => {
|
|
992
|
-
let isOwned;
|
|
993
|
-
const normalized = normalizeNftStandard(standard);
|
|
994
|
-
const tryErc721 = normalized !== 'ERC1155';
|
|
995
|
-
const tryErc1155 = normalized !== 'ERC721';
|
|
996
|
-
if (tryErc721) {
|
|
997
|
-
try {
|
|
998
|
-
const callData = erc721Iface.encodeFunctionData(OWNER_OF_FUNCTION, [tokenId]);
|
|
999
|
-
const raw = await provider.call({
|
|
1000
|
-
to: nftAddress,
|
|
1001
|
-
data: callData,
|
|
1002
|
-
});
|
|
1003
|
-
const [owner] = erc721Iface.decodeFunctionResult(OWNER_OF_FUNCTION, raw);
|
|
1004
|
-
isOwned = owner.toLowerCase() === userAddress.toLowerCase();
|
|
1005
|
-
}
|
|
1006
|
-
catch {
|
|
1007
|
-
// ERC-721 unavailable; try ERC-1155 below if applicable.
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
if (isOwned === undefined && tryErc1155) {
|
|
1011
|
-
try {
|
|
1012
|
-
const callData = erc1155Iface.encodeFunctionData(ERC1155_BALANCE_OF_FUNCTION, [userAddress, tokenId]);
|
|
1013
|
-
const raw = await provider.call({
|
|
1014
|
-
to: nftAddress,
|
|
1015
|
-
data: callData,
|
|
1016
|
-
});
|
|
1017
|
-
const [balance] = erc1155Iface.decodeFunctionResult(ERC1155_BALANCE_OF_FUNCTION, raw);
|
|
1018
|
-
isOwned = new BN(balance.toString()).gt(new BN(0));
|
|
1019
|
-
}
|
|
1020
|
-
catch {
|
|
1021
|
-
// ownership remains undefined
|
|
1022
|
-
}
|
|
1023
|
-
}
|
|
1024
|
-
return { nftAddress, tokenId, isOwned };
|
|
1025
|
-
}));
|
|
1026
|
-
return [...workingResult, ...batchResults];
|
|
1027
|
-
},
|
|
1028
|
-
});
|
|
1029
|
-
};
|
|
1030
|
-
/**
|
|
1031
|
-
* Check ownership for multiple NFTs, using Multicall3 when available to batch
|
|
1032
|
-
* all calls into a single RPC request, falling back to individual calls otherwise.
|
|
1033
|
-
*
|
|
1034
|
-
* @param nfts - Array of NFT queries containing address, tokenId, owner address, and standard.
|
|
1035
|
-
* @param chainId - The hexadecimal chain id.
|
|
1036
|
-
* @param provider - An ethers rpc provider.
|
|
1037
|
-
* @returns Promise resolving to array of ownership results. `isOwned` is `undefined`
|
|
1038
|
-
* when ownership could not be determined (e.g. unsupported standard or RPC error).
|
|
1039
|
-
*/
|
|
1040
|
-
export const getNftOwnershipForMultipleNfts = async (nfts, chainId, provider) => {
|
|
1041
|
-
if (nfts.length === 0) {
|
|
1042
|
-
return [];
|
|
1043
|
-
}
|
|
1044
|
-
const results = nfts.map(({ nftAddress, tokenId }) => ({
|
|
1045
|
-
nftAddress,
|
|
1046
|
-
tokenId,
|
|
1047
|
-
isOwned: undefined,
|
|
1048
|
-
}));
|
|
1049
|
-
// Filter out NFTs whose standard is explicitly unrecognized (e.g.
|
|
1050
|
-
// CryptoPunks with standard="UNKNOWN"). Such contracts use pre-Solidity-
|
|
1051
|
-
// 0.4.10 bytecode that compiles unrecognized selectors to the INVALID
|
|
1052
|
-
// opcode, which consumes ALL forwarded gas. Including them in a Multicall3
|
|
1053
|
-
// aggregate3 batch causes the entire batch to revert, and calling them
|
|
1054
|
-
// individually also always fails. They stay as isOwned=undefined.
|
|
1055
|
-
//
|
|
1056
|
-
// NFTs with `standard: null` (not yet categorized) are still included
|
|
1057
|
-
// because they are likely valid ERC-721/ERC-1155 contracts.
|
|
1058
|
-
const callable = nfts.reduce((acc, nft, index) => {
|
|
1059
|
-
const hasExplicitNonStandard = nft.standard !== null && normalizeNftStandard(nft.standard) === null;
|
|
1060
|
-
if (!hasExplicitNonStandard) {
|
|
1061
|
-
acc.push({ nft, index });
|
|
1062
|
-
}
|
|
1063
|
-
return acc;
|
|
1064
|
-
}, []);
|
|
1065
|
-
if (callable.length === 0) {
|
|
1066
|
-
return results;
|
|
1067
|
-
}
|
|
1068
|
-
const multicallAddress = MULTICALL_CONTRACT_BY_CHAINID[chainId];
|
|
1069
|
-
if (multicallAddress) {
|
|
1070
|
-
try {
|
|
1071
|
-
const batchResults = await getNftOwnershipViaMulticall(callable.map(({ nft }) => nft), chainId, provider);
|
|
1072
|
-
batchResults.forEach((result, batchIndex) => {
|
|
1073
|
-
results[callable[batchIndex].index] = result;
|
|
1074
|
-
});
|
|
1075
|
-
return results;
|
|
1076
|
-
}
|
|
1077
|
-
catch (error) {
|
|
1078
|
-
console.warn('Multicall3 NFT ownership check failed, falling back to individual calls', error);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
const individualResults = await getNftOwnershipIndividually(callable.map(({ nft }) => nft), provider);
|
|
1082
|
-
individualResults.forEach((result, batchIndex) => {
|
|
1083
|
-
results[callable[batchIndex].index] = result;
|
|
1084
|
-
});
|
|
1085
|
-
return results;
|
|
1086
|
-
};
|
|
1087
869
|
//# sourceMappingURL=multicall.mjs.map
|