@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.
@@ -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
@@ -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;AAqJF;;;;;;;;;;;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;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAuMF;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,SACnC,iBAAiB,EAAE,WAChB,GAAG,YACF,YAAY,KACrB,QAAQ,kBAAkB,EAAE,CAkE9B,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"}
@@ -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
@@ -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;AAqJF;;;;;;;;;;;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;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAuMF;;;;;;;;;GASG;AACH,eAAO,MAAM,8BAA8B,SACnC,iBAAiB,EAAE,WAChB,GAAG,YACF,YAAY,KACrB,QAAQ,kBAAkB,EAAE,CAkE9B,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"}
@@ -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