Skip to content

Commit 43e1229

Browse files
authored
feat(sp-registry): getProvidersWithProductByIds() to get multiple providers (#333)
1 parent 6801108 commit 43e1229

File tree

3 files changed

+426
-0
lines changed

3 files changed

+426
-0
lines changed

service_contracts/abi/ServiceProviderRegistry.abi.json

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,101 @@
736736
],
737737
"stateMutability": "view"
738738
},
739+
{
740+
"type": "function",
741+
"name": "getProvidersWithProductByIds",
742+
"inputs": [
743+
{
744+
"name": "providerIds",
745+
"type": "uint256[]",
746+
"internalType": "uint256[]"
747+
},
748+
{
749+
"name": "productType",
750+
"type": "uint8",
751+
"internalType": "enum ServiceProviderRegistryStorage.ProductType"
752+
}
753+
],
754+
"outputs": [
755+
{
756+
"name": "providersWithProducts",
757+
"type": "tuple[]",
758+
"internalType": "struct ServiceProviderRegistryStorage.ProviderWithProduct[]",
759+
"components": [
760+
{
761+
"name": "providerId",
762+
"type": "uint256",
763+
"internalType": "uint256"
764+
},
765+
{
766+
"name": "providerInfo",
767+
"type": "tuple",
768+
"internalType": "struct ServiceProviderRegistryStorage.ServiceProviderInfo",
769+
"components": [
770+
{
771+
"name": "serviceProvider",
772+
"type": "address",
773+
"internalType": "address"
774+
},
775+
{
776+
"name": "payee",
777+
"type": "address",
778+
"internalType": "address"
779+
},
780+
{
781+
"name": "name",
782+
"type": "string",
783+
"internalType": "string"
784+
},
785+
{
786+
"name": "description",
787+
"type": "string",
788+
"internalType": "string"
789+
},
790+
{
791+
"name": "isActive",
792+
"type": "bool",
793+
"internalType": "bool"
794+
}
795+
]
796+
},
797+
{
798+
"name": "product",
799+
"type": "tuple",
800+
"internalType": "struct ServiceProviderRegistryStorage.ServiceProduct",
801+
"components": [
802+
{
803+
"name": "productType",
804+
"type": "uint8",
805+
"internalType": "enum ServiceProviderRegistryStorage.ProductType"
806+
},
807+
{
808+
"name": "capabilityKeys",
809+
"type": "string[]",
810+
"internalType": "string[]"
811+
},
812+
{
813+
"name": "isActive",
814+
"type": "bool",
815+
"internalType": "bool"
816+
}
817+
]
818+
},
819+
{
820+
"name": "productCapabilityValues",
821+
"type": "bytes[]",
822+
"internalType": "bytes[]"
823+
}
824+
]
825+
},
826+
{
827+
"name": "validIds",
828+
"type": "bool[]",
829+
"internalType": "bool[]"
830+
}
831+
],
832+
"stateMutability": "view"
833+
},
739834
{
740835
"type": "function",
741836
"name": "initialize",

service_contracts/src/ServiceProviderRegistry.sol

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,66 @@ contract ServiceProviderRegistry is
638638
}
639639
}
640640

641+
/// @notice Get multiple providers with product information by their IDs
642+
/// @param providerIds Array of provider IDs to retrieve
643+
/// @param productType The type of product to include in the response
644+
/// @return providersWithProducts Array of provider and product information corresponding to the input IDs
645+
/// @return validIds Array of booleans indicating whether each ID is valid (exists, is active, and has the product)
646+
/// @dev Returns empty ProviderWithProduct structs for invalid IDs, with corresponding validIds[i] = false
647+
function getProvidersWithProductByIds(uint256[] calldata providerIds, ProductType productType)
648+
external
649+
view
650+
returns (ProviderWithProduct[] memory providersWithProducts, bool[] memory validIds)
651+
{
652+
uint256 length = providerIds.length;
653+
providersWithProducts = new ProviderWithProduct[](length);
654+
validIds = new bool[](length);
655+
656+
uint256 _numProviders = numProviders;
657+
658+
for (uint256 i = 0; i < length; i++) {
659+
uint256 providerId = providerIds[i];
660+
661+
if (providerId > 0 && providerId <= _numProviders) {
662+
ServiceProviderInfo storage provider = providers[providerId];
663+
ServiceProduct storage product = providerProducts[providerId][productType];
664+
665+
if (provider.serviceProvider != address(0) && provider.isActive && product.isActive) {
666+
providersWithProducts[i] = ProviderWithProduct({
667+
providerId: providerId,
668+
providerInfo: provider,
669+
product: product,
670+
productCapabilityValues: getProductCapabilities(providerId, productType, product.capabilityKeys)
671+
});
672+
validIds[i] = true;
673+
} else {
674+
providersWithProducts[i] = _getEmptyProviderWithProduct();
675+
validIds[i] = false;
676+
}
677+
} else {
678+
providersWithProducts[i] = _getEmptyProviderWithProduct();
679+
validIds[i] = false;
680+
}
681+
}
682+
}
683+
684+
/// @notice Internal helper to create an empty ProviderWithProduct
685+
/// @return Empty ProviderWithProduct struct
686+
function _getEmptyProviderWithProduct() internal pure returns (ProviderWithProduct memory) {
687+
return ProviderWithProduct({
688+
providerId: 0,
689+
providerInfo: ServiceProviderInfo({
690+
serviceProvider: address(0),
691+
payee: address(0),
692+
name: "",
693+
description: "",
694+
isActive: false
695+
}),
696+
product: ServiceProduct({productType: ProductType.PDP, capabilityKeys: new string[](0), isActive: false}),
697+
productCapabilityValues: new bytes[](0)
698+
});
699+
}
700+
641701
/// @notice Internal helper to create an empty ServiceProviderInfoView
642702
/// @return Empty ServiceProviderInfoView struct
643703
function _getEmptyProviderInfoView() internal pure returns (ServiceProviderInfoView memory) {

0 commit comments

Comments
 (0)