@startinblox/components-ds4go 4.1.1 → 4.1.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startinblox/components-ds4go",
3
- "version": "4.1.1",
3
+ "version": "4.1.3",
4
4
  "description": "Startin'blox DS4GO",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -58,6 +58,131 @@ export class SolidDspConnector extends OrbitDSPComponent {
58
58
  this.loadContracts(),
59
59
  this.loadNegotiations(),
60
60
  ]);
61
+
62
+ // Ensure to load assets from other providers when agreement does exists
63
+ await this.forceLoadAllAssets();
64
+ }
65
+
66
+ @state()
67
+ agreements: (ContractAgreement & { contract?: ContractNegotiation })[] = [];
68
+
69
+ // IMPROVEME: allows Consumer connector to load assets from other providers
70
+ private async forceLoadAllAssets() {
71
+ if (!this.storeService) {
72
+ console.error("Store not initialized. Check connector configuration.");
73
+ return;
74
+ }
75
+
76
+ try {
77
+ await Promise.all(
78
+ this.negotiations.map(async (n: ContractNegotiation) => {
79
+ if (n.contractAgreementId) {
80
+ const agreement = await this.loadAgreement(n["@id"]);
81
+ if (agreement && !this.agreements.find(a => a["@id"] === agreement["@id"])) {
82
+ this.agreements.push(agreement);
83
+ }
84
+ }
85
+ }),
86
+ );
87
+
88
+ const consumerAgreements = this.agreements.filter(
89
+ (a: ContractAgreement) => {
90
+ if (!a.consumerId) return false;
91
+ const consumerParticipantId = a.consumerId.split("/").pop();
92
+ if (!this.participantId) {
93
+ throw new Error("Participant ID not set");
94
+ }
95
+ return consumerParticipantId?.startsWith(this.participantId);
96
+ },
97
+ );
98
+
99
+ const assets: Promise<Response>[] = [];
100
+ for (const agreement of consumerAgreements) {
101
+ if (!this.assets.find((asset) => asset["@id"] === agreement.assetId)) {
102
+ for (const provider of this.providers) {
103
+ assets.push(
104
+ fetch(
105
+ `${provider.address.replace("/protocol", "")}/management/v3/assets/${agreement.assetId}`,
106
+ ),
107
+ );
108
+ }
109
+ }
110
+ }
111
+
112
+ const assetResponses = await Promise.all(assets);
113
+ this.assets = [
114
+ ...this.assets,
115
+ ...(await Promise.all(
116
+ assetResponses
117
+ .filter((r: Response) => r.status === 200)
118
+ .map((r) => r.json()),
119
+ )),
120
+ ];
121
+ } catch (e) {
122
+ console.error(`Failed to get all assets from all providers:`, e);
123
+ }
124
+ }
125
+
126
+ private async getAgreementForResource(resourceUrl: string) {
127
+ if (!this.storeService) {
128
+ console.error("Store not initialized. Check connector configuration.");
129
+ return;
130
+ }
131
+
132
+ try {
133
+ const relatedAsset = this.assets.find(
134
+ (asset) => asset.dataAddress?.baseUrl === resourceUrl,
135
+ );
136
+
137
+ if (!relatedAsset) {
138
+ throw new Error(`No asset found for resource ${resourceUrl}`);
139
+ }
140
+
141
+ const relatedAgreement = this.agreements.find(
142
+ (n) => n.assetId === relatedAsset["@id"],
143
+ );
144
+
145
+ if (!relatedAgreement) {
146
+ throw new Error(`No agreement found for asset ${relatedAsset["@id"]}`);
147
+ }
148
+
149
+ return relatedAgreement;
150
+ } catch (e) {
151
+ console.error(`Failed to get agreement ID for ${resourceUrl}:`, e);
152
+ }
153
+ }
154
+
155
+ public async fetchProtectedResource(resourceUrl: string) {
156
+ if (!this.storeService) {
157
+ console.error("Store not initialized. Check connector configuration.");
158
+ return;
159
+ }
160
+
161
+ try {
162
+ const relatedAgreement = await this.getAgreementForResource(resourceUrl);
163
+
164
+ if (!relatedAgreement) {
165
+ throw new Error(`No agreement found for resource ${resourceUrl}`);
166
+ }
167
+
168
+ const relatedNegotiation = this.negotiations.find(
169
+ (n) => n.contractAgreementId === relatedAgreement?.["@id"],
170
+ );
171
+
172
+ if (!relatedNegotiation) {
173
+ throw new Error(`No negotiation found for resource ${resourceUrl}`);
174
+ }
175
+
176
+ return await this.storeService.fetchProtectedResource(
177
+ resourceUrl,
178
+ this.participantId,
179
+ this.participantConnectorUri,
180
+ relatedNegotiation.counterPartyAddress,
181
+ relatedNegotiation.contractAgreementId,
182
+ );
183
+ } catch (e) {
184
+ console.error(`Failed to load ${resourceUrl}:`, e);
185
+ }
61
186
  }
62
187
 
63
188
  @state()
@@ -118,25 +118,32 @@ export class SolidFactList extends OrbitComponent {
118
118
  },
119
119
  );
120
120
 
121
- const assets: Asset[] = [];
121
+ const bundles = [];
122
122
  for (const agreement of consumerAgreements) {
123
- const asset = this.dspConnector?.instance?.getAsset(
124
- agreement.assetId,
123
+ const asset = this.dspConnector?.instance?.assets.find(
124
+ (a: Asset) => a["@id"] === agreement.assetId,
125
125
  );
126
- assets.push(asset);
127
- }
128
126
 
129
- const bundles = [];
130
- for (const asset of await Promise.all(assets)) {
131
- const bundleUrl = asset?.dataAddress?.baseUrl;
132
- if (bundleUrl) {
133
- bundles.push(this._getProxyValue(bundleUrl));
127
+ if (asset) {
128
+ const bundleUrl = asset?.dataAddress?.baseUrl;
129
+ if (bundleUrl) {
130
+ // FIXME: Getting 403 when calling a provider with agreement id from consumer
131
+ // bundles.push(
132
+ // this.dspConnector.instance.fetchProtectedResource(bundleUrl),
133
+ // );
134
+ // Temp workaround, using ldp store to bypass the issue
135
+ bundles.push(bundleUrl);
136
+ }
134
137
  }
135
138
  }
136
139
 
140
+ const fetchedBundles = (await Promise.all(bundles)).map((bundle) =>
141
+ this._getProxyValue(bundle),
142
+ );
143
+
137
144
  const facts = Array.from(
138
145
  new Set(
139
- (await Promise.all(bundles))
146
+ (await Promise.all(fetchedBundles))
140
147
  .flatMap((bundle: any) => bundle?.facts || [])
141
148
  .map((fact: Fact) => fact["@id"]),
142
149
  ),