@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.
- package/dist/cjs/core-sdk.d.ts +5 -5
- package/dist/cjs/core-sdk.d.ts.map +1 -1
- package/dist/cjs/core-sdk.js +20 -10
- package/dist/cjs/core-sdk.js.map +1 -1
- package/dist/cjs/offers/index.d.ts +1 -0
- package/dist/cjs/offers/index.d.ts.map +1 -1
- package/dist/cjs/offers/index.js +1 -0
- package/dist/cjs/offers/index.js.map +1 -1
- package/dist/cjs/offers/renderContractualAgreement.d.ts +41 -0
- package/dist/cjs/offers/renderContractualAgreement.d.ts.map +1 -0
- package/dist/cjs/offers/renderContractualAgreement.js +156 -0
- package/dist/cjs/offers/renderContractualAgreement.js.map +1 -0
- package/dist/cjs/offers/subgraph.d.ts.map +1 -1
- package/dist/cjs/offers/subgraph.js.map +1 -1
- package/dist/cjs/subgraph.d.ts +3782 -54
- package/dist/cjs/subgraph.d.ts.map +1 -1
- package/dist/cjs/subgraph.js +207 -169
- package/dist/cjs/subgraph.js.map +1 -1
- package/dist/cjs/utils/tokenInfoManager.d.ts +16 -0
- package/dist/cjs/utils/tokenInfoManager.d.ts.map +1 -0
- package/dist/cjs/utils/tokenInfoManager.js +97 -0
- package/dist/cjs/utils/tokenInfoManager.js.map +1 -0
- package/dist/esm/core-sdk.d.ts +5 -5
- package/dist/esm/core-sdk.d.ts.map +1 -1
- package/dist/esm/core-sdk.js +17 -10
- package/dist/esm/core-sdk.js.map +1 -1
- package/dist/esm/offers/index.d.ts +1 -0
- package/dist/esm/offers/index.d.ts.map +1 -1
- package/dist/esm/offers/index.js +1 -0
- package/dist/esm/offers/index.js.map +1 -1
- package/dist/esm/offers/renderContractualAgreement.d.ts +41 -0
- package/dist/esm/offers/renderContractualAgreement.d.ts.map +1 -0
- package/dist/esm/offers/renderContractualAgreement.js +132 -0
- package/dist/esm/offers/renderContractualAgreement.js.map +1 -0
- package/dist/esm/offers/subgraph.d.ts.map +1 -1
- package/dist/esm/offers/subgraph.js.map +1 -1
- package/dist/esm/subgraph.d.ts +3782 -54
- package/dist/esm/subgraph.d.ts.map +1 -1
- package/dist/esm/subgraph.js +205 -167
- package/dist/esm/subgraph.js.map +1 -1
- package/dist/esm/utils/tokenInfoManager.d.ts +16 -0
- package/dist/esm/utils/tokenInfoManager.d.ts.map +1 -0
- package/dist/esm/utils/tokenInfoManager.js +83 -0
- package/dist/esm/utils/tokenInfoManager.js.map +1 -0
- package/package.json +5 -4
- package/src/core-sdk.ts +34 -15
- package/src/metadata/product-v1.graphql +3 -0
- package/src/offers/index.ts +1 -0
- package/src/offers/queries.graphql +29 -0
- package/src/offers/renderContractualAgreement.ts +203 -0
- package/src/offers/subgraph.ts +0 -1
- package/src/subgraph.ts +3885 -167
- 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(
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
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
|
|
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 {
|
package/src/offers/index.ts
CHANGED
|
@@ -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
|
+
}
|