@bosonprotocol/core-sdk 1.12.0-alpha.7 → 1.12.0-alpha.9

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.
Files changed (53) hide show
  1. package/dist/cjs/core-sdk.d.ts +5 -5
  2. package/dist/cjs/core-sdk.d.ts.map +1 -1
  3. package/dist/cjs/core-sdk.js +20 -10
  4. package/dist/cjs/core-sdk.js.map +1 -1
  5. package/dist/cjs/offers/index.d.ts +1 -0
  6. package/dist/cjs/offers/index.d.ts.map +1 -1
  7. package/dist/cjs/offers/index.js +1 -0
  8. package/dist/cjs/offers/index.js.map +1 -1
  9. package/dist/cjs/offers/renderContractualAgreement.d.ts +41 -0
  10. package/dist/cjs/offers/renderContractualAgreement.d.ts.map +1 -0
  11. package/dist/cjs/offers/renderContractualAgreement.js +156 -0
  12. package/dist/cjs/offers/renderContractualAgreement.js.map +1 -0
  13. package/dist/cjs/offers/subgraph.d.ts.map +1 -1
  14. package/dist/cjs/offers/subgraph.js.map +1 -1
  15. package/dist/cjs/subgraph.d.ts +3782 -54
  16. package/dist/cjs/subgraph.d.ts.map +1 -1
  17. package/dist/cjs/subgraph.js +207 -169
  18. package/dist/cjs/subgraph.js.map +1 -1
  19. package/dist/cjs/utils/tokenInfoManager.d.ts +16 -0
  20. package/dist/cjs/utils/tokenInfoManager.d.ts.map +1 -0
  21. package/dist/cjs/utils/tokenInfoManager.js +97 -0
  22. package/dist/cjs/utils/tokenInfoManager.js.map +1 -0
  23. package/dist/esm/core-sdk.d.ts +5 -5
  24. package/dist/esm/core-sdk.d.ts.map +1 -1
  25. package/dist/esm/core-sdk.js +17 -10
  26. package/dist/esm/core-sdk.js.map +1 -1
  27. package/dist/esm/offers/index.d.ts +1 -0
  28. package/dist/esm/offers/index.d.ts.map +1 -1
  29. package/dist/esm/offers/index.js +1 -0
  30. package/dist/esm/offers/index.js.map +1 -1
  31. package/dist/esm/offers/renderContractualAgreement.d.ts +41 -0
  32. package/dist/esm/offers/renderContractualAgreement.d.ts.map +1 -0
  33. package/dist/esm/offers/renderContractualAgreement.js +132 -0
  34. package/dist/esm/offers/renderContractualAgreement.js.map +1 -0
  35. package/dist/esm/offers/subgraph.d.ts.map +1 -1
  36. package/dist/esm/offers/subgraph.js.map +1 -1
  37. package/dist/esm/subgraph.d.ts +3782 -54
  38. package/dist/esm/subgraph.d.ts.map +1 -1
  39. package/dist/esm/subgraph.js +205 -167
  40. package/dist/esm/subgraph.js.map +1 -1
  41. package/dist/esm/utils/tokenInfoManager.d.ts +16 -0
  42. package/dist/esm/utils/tokenInfoManager.d.ts.map +1 -0
  43. package/dist/esm/utils/tokenInfoManager.js +83 -0
  44. package/dist/esm/utils/tokenInfoManager.js.map +1 -0
  45. package/package.json +5 -4
  46. package/src/core-sdk.ts +34 -15
  47. package/src/metadata/product-v1.graphql +3 -0
  48. package/src/offers/index.ts +1 -0
  49. package/src/offers/queries.graphql +29 -0
  50. package/src/offers/renderContractualAgreement.ts +203 -0
  51. package/src/offers/subgraph.ts +0 -1
  52. package/src/subgraph.ts +3885 -167
  53. package/src/utils/tokenInfoManager.ts +97 -0
package/src/core-sdk.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ITokenInfo, TokenInfoManager } from "./utils/tokenInfoManager";
1
2
  import {
2
3
  Web3LibAdapter,
3
4
  TransactionResponse,
@@ -31,6 +32,7 @@ export class CoreSDK {
31
32
  private _subgraphUrl: string;
32
33
  private _protocolDiamond: string;
33
34
  private _chainId: number;
35
+ private _tokenInfoManager: TokenInfoManager;
34
36
 
35
37
  /**
36
38
  * Creates an instance of `CoreSDK`
@@ -647,22 +649,21 @@ export class CoreSDK {
647
649
  * @param exchangeToken - Address exchange token.
648
650
  * @returns Decimals, name and symbol.
649
651
  */
650
- public async getExchangeTokenInfo(exchangeToken: string): Promise<{
651
- name: string;
652
- decimals: number;
653
- symbol: string;
654
- }> {
655
- const args = {
656
- web3Lib: this._web3Lib,
657
- contractAddress: exchangeToken
658
- };
659
- const [decimals, name, symbol] = await Promise.all([
660
- erc20.handler.getDecimals(args),
661
- erc20.handler.getName(args),
662
- erc20.handler.getSymbol(args)
663
- ]);
652
+ public async getExchangeTokenInfo(
653
+ exchangeToken: string
654
+ ): Promise<ITokenInfo> {
655
+ if (this._chainId === undefined) {
656
+ this._chainId = await this._web3Lib.getChainId();
657
+ }
658
+
659
+ if (this._tokenInfoManager === undefined) {
660
+ this._tokenInfoManager = new TokenInfoManager(
661
+ this._chainId,
662
+ this._web3Lib
663
+ );
664
+ }
664
665
 
665
- return { decimals, name, symbol };
666
+ return this._tokenInfoManager.getExchangeTokenInfo(exchangeToken);
666
667
  }
667
668
 
668
669
  /**
@@ -1150,4 +1151,22 @@ export class CoreSDK {
1150
1151
  ...args
1151
1152
  });
1152
1153
  }
1154
+
1155
+ public async renderContractualAgreementForOffer(
1156
+ offerId: BigNumberish
1157
+ ): Promise<string> {
1158
+ const offerData = await offers.subgraph.getOfferById(
1159
+ this._subgraphUrl,
1160
+ offerId
1161
+ );
1162
+ return offers.renderContractualAgreementForOffer(offerData);
1163
+ }
1164
+
1165
+ public async renderContractualAgreement(
1166
+ template: string,
1167
+ offerData: offers.CreateOfferArgs
1168
+ ): Promise<string> {
1169
+ const tokenInfo = await this.getExchangeTokenInfo(offerData.exchangeToken);
1170
+ return offers.renderContractualAgreement(template, offerData, tokenInfo);
1171
+ }
1153
1172
  }
@@ -107,6 +107,9 @@ fragment BaseProductV1MetadataEntityFields on ProductV1MetadataEntity {
107
107
  productV1Seller {
108
108
  ...BaseProductV1SellerFields
109
109
  }
110
+ exchangePolicy {
111
+ ...BaseProductV1ExchangePolicyFields
112
+ }
110
113
  }
111
114
 
112
115
  fragment BaseProductV1ProductFields on ProductV1Product {
@@ -6,6 +6,7 @@ export * as iface from "./interface";
6
6
  export * as storage from "./storage";
7
7
  export * from "./types";
8
8
  export * from "./getOfferStatus";
9
+ export * from "./renderContractualAgreement";
9
10
 
10
11
  export const validation = {
11
12
  createOfferArgsSchema: utils.validation.createOfferArgsSchema
@@ -89,5 +89,34 @@ fragment BaseOfferFields on Offer {
89
89
  externalUrl
90
90
  schemaUrl
91
91
  type
92
+ ... on ProductV1MetadataEntity {
93
+ image
94
+ attributes {
95
+ traitType
96
+ value
97
+ displayType
98
+ }
99
+ createdAt
100
+ voided
101
+ validFromDate
102
+ validUntilDate
103
+ quantityAvailable
104
+ uuid
105
+ product {
106
+ ...BaseProductV1ProductFields
107
+ }
108
+ variations {
109
+ ...BaseProductV1VariationFields
110
+ }
111
+ productV1Seller {
112
+ ...BaseProductV1SellerFields
113
+ }
114
+ exchangePolicy {
115
+ ...BaseProductV1ExchangePolicyFields
116
+ }
117
+ shipping {
118
+ ...BaseProductV1ShippingOptionFields
119
+ }
120
+ }
92
121
  }
93
122
  }
@@ -0,0 +1,203 @@
1
+ import * as yup from "yup";
2
+ import { ITokenInfo } from "./../utils/tokenInfoManager";
3
+ import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
4
+ import { offers, subgraph } from "..";
5
+ import { utils } from "@bosonprotocol/common";
6
+ import Mustache from "mustache";
7
+ import { formatUnits } from "ethers/lib/utils";
8
+ import { productV1 } from "@bosonprotocol/metadata";
9
+
10
+ export type TemplateRenderingData = offers.CreateOfferArgs & {
11
+ priceValue: string; // Convert in decimals value
12
+ sellerDepositValue: string; // Convert in decimals value
13
+ buyerCancelPenaltyValue: string; // Convert in decimals value
14
+ agentFeeValue: string; // Convert in decimals value
15
+ exchangeTokenSymbol: string;
16
+ sellerContactMethod: string;
17
+ disputeResolverContactMethod: string;
18
+ toISOString: () => void;
19
+ msecToDay: () => void;
20
+ };
21
+
22
+ export class InvalidOfferDataError extends Error {
23
+ constructor(public missingProperties: string[]) {
24
+ super(
25
+ `InvalidOfferData - missing properties: [${missingProperties.join(",")}]`
26
+ );
27
+ }
28
+ }
29
+
30
+ export const baseOfferDataSchema: yup.SchemaOf<BaseOfferData> = yup.object({
31
+ price: yup.mixed().required(),
32
+ sellerDeposit: yup.mixed().required(),
33
+ agentId: yup.mixed().required(),
34
+ buyerCancelPenalty: yup.mixed().required(),
35
+ quantityAvailable: yup.mixed().required(),
36
+ validFromDateInMS: yup.mixed().required(),
37
+ validUntilDateInMS: yup.mixed().required(),
38
+ voucherRedeemableFromDateInMS: yup.mixed().required(),
39
+ voucherRedeemableUntilDateInMS: yup.mixed().required(),
40
+ fulfillmentPeriodDurationInMS: yup.mixed().required(),
41
+ resolutionPeriodDurationInMS: yup.mixed().required(),
42
+ exchangeToken: yup.string().required(),
43
+ disputeResolverId: yup.mixed().required(),
44
+ metadataUri: yup.string().required(),
45
+ metadataHash: yup.string().required()
46
+ });
47
+
48
+ export type BaseOfferData = {
49
+ price: BigNumberish;
50
+ sellerDeposit: BigNumberish;
51
+ agentId: BigNumberish;
52
+ buyerCancelPenalty: BigNumberish;
53
+ quantityAvailable: BigNumberish;
54
+ validFromDateInMS: BigNumberish;
55
+ validUntilDateInMS: BigNumberish;
56
+ voucherRedeemableFromDateInMS: BigNumberish;
57
+ voucherRedeemableUntilDateInMS: BigNumberish;
58
+ fulfillmentPeriodDurationInMS: BigNumberish;
59
+ resolutionPeriodDurationInMS: BigNumberish;
60
+ exchangeToken: string;
61
+ disputeResolverId: BigNumberish;
62
+ metadataUri: string;
63
+ metadataHash: string;
64
+ };
65
+
66
+ function checkOfferDataIsValid(
67
+ offerData: unknown,
68
+ throwIfInvalid = false
69
+ ): boolean {
70
+ if (offerData === undefined || offerData === null) {
71
+ throw new Error("InvalidOfferData - undefined");
72
+ }
73
+ if (typeof offerData !== "object") {
74
+ throw new Error("InvalidOfferData - expecting an object");
75
+ }
76
+ try {
77
+ baseOfferDataSchema.validateSync(offerData, { abortEarly: false });
78
+ } catch (e) {
79
+ const missingProperties = [];
80
+ const getMissingProp = (error) => {
81
+ return error.match(/(.*) is a required field/)[1] || error;
82
+ };
83
+ if (throwIfInvalid) {
84
+ if (e.errors) {
85
+ e.errors.forEach((error: string) => {
86
+ missingProperties.push(getMissingProp(error));
87
+ });
88
+ } else {
89
+ missingProperties.push(getMissingProp(e));
90
+ }
91
+ throw new InvalidOfferDataError(missingProperties);
92
+ }
93
+ return false;
94
+ }
95
+ return true;
96
+ }
97
+
98
+ function convertExistingOfferData(
99
+ offerDataSubGraph: subgraph.OfferFieldsFragment
100
+ ): { offerData: offers.CreateOfferArgs; tokenInfo: ITokenInfo } {
101
+ return {
102
+ offerData: {
103
+ ...offerDataSubGraph,
104
+ validFromDateInMS: offerDataSubGraph.validFromDate,
105
+ validUntilDateInMS: offerDataSubGraph.validUntilDate,
106
+ voucherRedeemableFromDateInMS:
107
+ offerDataSubGraph.voucherRedeemableFromDate,
108
+ voucherRedeemableUntilDateInMS:
109
+ offerDataSubGraph.voucherRedeemableUntilDate,
110
+ fulfillmentPeriodDurationInMS:
111
+ offerDataSubGraph.fulfillmentPeriodDuration,
112
+ resolutionPeriodDurationInMS: offerDataSubGraph.resolutionPeriodDuration,
113
+ exchangeToken: offerDataSubGraph.exchangeToken.address
114
+ },
115
+ tokenInfo: {
116
+ ...offerDataSubGraph.exchangeToken,
117
+ decimals: parseInt(offerDataSubGraph.exchangeToken.decimals)
118
+ }
119
+ };
120
+ }
121
+
122
+ export async function prepareRenderingData(
123
+ offerData: offers.CreateOfferArgs,
124
+ tokenInfo: ITokenInfo
125
+ ): Promise<TemplateRenderingData> {
126
+ return {
127
+ ...offerData,
128
+ priceValue: formatUnits(offerData.price, tokenInfo.decimals),
129
+ exchangeTokenSymbol: tokenInfo.symbol,
130
+ sellerDepositValue: formatUnits(
131
+ offerData.sellerDeposit,
132
+ tokenInfo.decimals
133
+ ),
134
+ agentFeeValue: "0", // TODO: get the agentFee of the specified offerData.agentId
135
+ buyerCancelPenaltyValue: formatUnits(
136
+ offerData.buyerCancelPenalty,
137
+ tokenInfo.decimals
138
+ ),
139
+ sellerContactMethod: "TBD", // TODO: what is the sellerContactMethod?
140
+ disputeResolverContactMethod: "TBD", // TODO: what is the disputeResolverContactMethod?
141
+ toISOString: function () {
142
+ return function (num, render) {
143
+ return new Date(parseInt(render(num))).toISOString();
144
+ };
145
+ },
146
+ msecToDay: function () {
147
+ return function (num, render) {
148
+ return BigNumber.from(render(num))
149
+ .div(utils.timestamp.MSEC_PER_DAY)
150
+ .toString();
151
+ };
152
+ }
153
+ };
154
+ }
155
+
156
+ // inject a template + all offer details
157
+ export async function renderContractualAgreement(
158
+ template: string,
159
+ offerData: offers.CreateOfferArgs,
160
+ tokenInfo: ITokenInfo
161
+ ): Promise<string> {
162
+ // Check the passed offerData is matching the required type
163
+ checkOfferDataIsValid(offerData, true);
164
+ const preparedData = await prepareRenderingData(offerData, tokenInfo);
165
+ return Mustache.render(template, preparedData);
166
+ }
167
+
168
+ export async function renderContractualAgreementForOffer(
169
+ existingOfferData: subgraph.OfferFieldsFragment
170
+ ): Promise<string> {
171
+ if (!existingOfferData) {
172
+ throw new Error(`offerData is undefined`);
173
+ }
174
+ if (!existingOfferData.metadata) {
175
+ throw new Error(`Offer Metadata is undefined`);
176
+ }
177
+ if (existingOfferData.metadata.type !== subgraph.MetadataType.ProductV1) {
178
+ throw new Error(
179
+ `Invalid Offer Metadata: Type is not supported: '${existingOfferData.metadata.type}'`
180
+ );
181
+ }
182
+ if (
183
+ !(existingOfferData.metadata as productV1.ProductV1Metadata).exchangePolicy
184
+ ) {
185
+ throw new Error(`Invalid Offer Metadata: exchangePolicy is not defined`);
186
+ }
187
+ if (
188
+ !(existingOfferData.metadata as productV1.ProductV1Metadata).exchangePolicy
189
+ .template
190
+ ) {
191
+ throw new Error(
192
+ `Invalid Offer Metadata: exchangePolicy.template is not defined`
193
+ );
194
+ }
195
+ const template = (existingOfferData.metadata as productV1.ProductV1Metadata)
196
+ .exchangePolicy.template;
197
+ const convertedOfferArgs = convertExistingOfferData(existingOfferData);
198
+ return renderContractualAgreement(
199
+ template,
200
+ convertedOfferArgs.offerData,
201
+ convertedOfferArgs.tokenInfo
202
+ );
203
+ }
@@ -21,7 +21,6 @@ export async function getOfferById(
21
21
  offerId: offerId.toString(),
22
22
  ...queryVars
23
23
  });
24
-
25
24
  return offer;
26
25
  }
27
26