diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 1f5a484..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/hypercerts-api"] - path = lib/hypercerts-api - url = http://github.com/hypercerts-org/hypercerts-api diff --git a/lib/hypercerts-api b/lib/hypercerts-api deleted file mode 160000 index 8c970ab..0000000 --- a/lib/hypercerts-api +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8c970abf10af5291b6e8137fc6be371d4d3cfe83 diff --git a/package.json b/package.json index da304a7..7624c0d 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ }, "scripts": { "build": "pnpm types:json && pnpm codegen:api && rollup -c", - "codegen:api": "npx orval --input ./lib/hypercerts-api/src/__generated__/swagger.json --output ./src/__generated__/api.ts", + "codegen:api": "npx orval --input https://api.hypercerts.org/swagger.json --output ./src/__generated__/api.ts", "clean": "rm -rf ./dist", "prebuild": "pnpm clean", "prepack": "pnpm build", diff --git a/src/__generated__/api.ts b/src/__generated__/api.ts index 738eadf..68bac42 100644 --- a/src/__generated__/api.ts +++ b/src/__generated__/api.ts @@ -10,6 +10,46 @@ import type { AxiosRequestConfig, AxiosResponse } from 'axios' +export type DeleteBlueprint200AnyOfSix = { + data?: unknown; + errors?: unknown; + message: string; + success: boolean; +}; + +export type DeleteBlueprint200AnyOfFourErrors = { + blueprint?: unknown; + signature: string; +}; + +export type DeleteBlueprint200AnyOfFour = { + data?: unknown; + errors: DeleteBlueprint200AnyOfFourErrors; + message: string; + success: boolean; +}; + +export type DeleteBlueprint200AnyOfTwoErrors = { + blueprint: string; + signature?: unknown; +}; + +export type DeleteBlueprint200AnyOfTwo = { + data?: unknown; + errors: DeleteBlueprint200AnyOfTwoErrors; + message: string; + success: boolean; +}; + +export type DeleteBlueprint200AnyOf = { + data: unknown; + errors: unknown; + message: string; + success: boolean; +}; + +export type DeleteBlueprint200 = DeleteBlueprint200AnyOf | DeleteBlueprint200AnyOfTwo | DeleteBlueprint200AnyOfFour | DeleteBlueprint200AnyOfSix; + export type DeleteHyperboardParams = { adminAddress: string; signature: string; @@ -108,37 +148,117 @@ export type StoreOrder201AnyOf = { export type StoreOrder201 = StoreOrder201AnyOf | StoreOrder201AnyOfTwo | StoreOrder201AnyOfFour; -/** - * Interface for validating an allow list dump. - */ +export type StoreMetadata201AnyOfFourErrors = { + metadata: string; +}; + +export type StoreMetadata201AnyOfFour = { + data?: unknown; + errors: StoreMetadata201AnyOfFourErrors; + message: string; + success: boolean; + valid?: unknown; +}; + +export type StoreMetadata201 = StoreMetadata201AnyOf | StoreMetadata201AnyOfTwo | StoreMetadata201AnyOfFour; + +export type StoreMetadata201AnyOfTwoData = { + cid: string; +}; + +export type StoreMetadata201AnyOfTwo = { + data: StoreMetadata201AnyOfTwoData; + errors?: unknown; + message?: unknown; + success: boolean; + valid?: unknown; +}; + +export type StoreMetadata201AnyOf = { + data?: unknown; + errors: unknown; + message: string; + success: boolean; + valid: boolean; +}; + +export type ProcessSignatureRequests200 = { + message: string; + success: boolean; +}; + +export type CancelSignatureRequest200 = { + message: string; + success: boolean; +}; + +export type UploadBody = { + /** - Array of files to upload (max 5 files, 10MB each) */ + files?: Blob[]; + /** - Optional JSON string with additional metadata */ + jsonData?: string; +}; + export interface ValidateAllowListRequest { allowList: string; totalUnits?: string; } -/** - * Interface for storing an allow list dump on IPFS - */ export interface StoreAllowListRequest { allowList: string; totalUnits?: string; } +export interface BlueprintQueueMintRequest { + chain_id: number; + minter_address: string; + signature: string; + tx_hash: string; +} + +export interface BlueprintDeleteRequest { + admin_address: string; + chain_id: number; + signature: string; +} + +export interface BlueprintCreateRequest { + admin_address: string; + chain_id: number; + form_values: unknown; + minter_address: string; + signature: string; +} + +export type BlueprintResponseData = { + blueprint_id: number; +}; + +export interface BlueprintResponse { + data?: BlueprintResponseData; + errors?: RecordStringStringOrStringArray; + message?: string; + success: boolean; +} + export type HyperboardUpdateRequestCollectionsItemHypercertsItem = { factor: number; hypercertId: string; }; +export type HyperboardUpdateRequestCollectionsItemBlueprintsItem = { + blueprintId: number; + factor: number; +}; + export type HyperboardUpdateRequestCollectionsItem = { + blueprints: HyperboardUpdateRequestCollectionsItemBlueprintsItem[]; description: string; hypercerts: HyperboardUpdateRequestCollectionsItemHypercertsItem[]; id?: string; title: string; }; -/** - * Interface for updating a hyperboard - */ export interface HyperboardUpdateRequest { adminAddress: string; backgroundImg?: string; @@ -155,16 +275,19 @@ export type HyperboardCreateRequestCollectionsItemHypercertsItem = { hypercertId: string; }; +export type HyperboardCreateRequestCollectionsItemBlueprintsItem = { + blueprintId: number; + factor: number; +}; + export type HyperboardCreateRequestCollectionsItem = { + blueprints: HyperboardCreateRequestCollectionsItemBlueprintsItem[]; description: string; hypercerts: HyperboardCreateRequestCollectionsItemHypercertsItem[]; id?: string; title: string; }; -/** - * Interface for creating a hyperboard - */ export interface HyperboardCreateRequest { adminAddress: string; backgroundImg?: string; @@ -175,31 +298,17 @@ export interface HyperboardCreateRequest { title: string; } -export type ApiResponseIdStringOrNullErrors = RecordStringStringOrStringArray | Error[]; - -/** - * @nullable - */ -export type ApiResponseIdStringOrNullData = { +export type HyperboardResponseData = { id: string; -} | null; +}; -/** - * Interface for a generic API response. - */ -export interface ApiResponseIdStringOrNull { - /** @nullable */ - data?: ApiResponseIdStringOrNullData; - errors?: ApiResponseIdStringOrNullErrors; +export interface HyperboardResponse { + data?: HyperboardResponseData; + errors?: RecordStringStringOrStringArray; message?: string; success: boolean; } -/** - * Response for a created hyperboard - */ -export type HyperboardCreateResponse = ApiResponseIdStringOrNull; - export interface ValidateOrderRequest { chainId: number; tokenIds: string[]; @@ -292,35 +401,25 @@ export const OrderValidatorCode = { NUMBER_902: 902, } as const; -/** - * Interface for validating metadata. - */ export interface ValidateMetadataRequest { metadata: HypercertMetadata; } -/** - * Interface for a validation response. - */ -export type ValidationResponse = ApiResponseValidationResult; - -export type ApiResponseValidationResultErrors = RecordStringStringOrStringArray | Error[]; - -/** - * Interface for a validation response. - */ -export interface ValidationResult { +export interface ValidationResponse { data?: unknown; errors?: RecordStringStringOrStringArray; + message?: string; + success: boolean; valid: boolean; } -/** - * Interface for a generic API response. - */ -export interface ApiResponseValidationResult { - data?: ValidationResult; - errors?: ApiResponseValidationResultErrors; +export type StorageResponseData = { + cid: string; +}; + +export interface StorageResponse { + data?: StorageResponseData; + errors?: RecordStringStringOrStringArray; message?: string; success: boolean; } @@ -341,7 +440,7 @@ export interface HypercertMetadata { description: string; /** An url pointing to the external website of the project */ external_url?: string; - hypercert?: HypercertClaimdata361; + hypercert?: HypercertClaimdata; /** A URI pointing to a resource with mime type image/* representing the asset to which this token represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive. */ image: string; /** Identifies the asset to which this token represents */ @@ -353,18 +452,12 @@ export interface HypercertMetadata { version?: string; } -/** - * Interface for storing metadata and allow list dump on IPFS. - */ export interface StoreMetadataWithAllowlistRequest { allowList: string; metadata: HypercertMetadata; totalUnits?: string; } -/** - * Interface for storing metadata on IPFS. - */ export interface StoreMetadataRequest { metadata: HypercertMetadata; } @@ -372,7 +465,7 @@ export interface StoreMetadataRequest { /** * Work time period. The value is UNIX time in seconds from epoch. */ -export type HypercertClaimdata361WorkTimeframe = { +export type HypercertClaimdataWorkTimeframe = { display_value?: string; name?: string; value?: number[]; @@ -382,7 +475,7 @@ export type HypercertClaimdata361WorkTimeframe = { /** * Scopes of work */ -export type HypercertClaimdata361WorkScope = { +export type HypercertClaimdataWorkScope = { display_value?: string; excludes?: string[]; name?: string; @@ -393,7 +486,7 @@ export type HypercertClaimdata361WorkScope = { /** * Rights */ -export type HypercertClaimdata361Rights = { +export type HypercertClaimdataRights = { display_value?: string; excludes?: string[]; name?: string; @@ -404,7 +497,7 @@ export type HypercertClaimdata361Rights = { /** * Impact time period. The value is UNIX time in seconds from epoch. */ -export type HypercertClaimdata361ImpactTimeframe = { +export type HypercertClaimdataImpactTimeframe = { display_value?: string; name?: string; value?: number[]; @@ -414,7 +507,7 @@ export type HypercertClaimdata361ImpactTimeframe = { /** * Scopes of impact */ -export type HypercertClaimdata361ImpactScope = { +export type HypercertClaimdataImpactScope = { display_value?: string; excludes?: string[]; name?: string; @@ -425,7 +518,7 @@ export type HypercertClaimdata361ImpactScope = { /** * Contributors */ -export type HypercertClaimdata361Contributors = { +export type HypercertClaimdataContributors = { display_value?: string; name?: string; value?: string[]; @@ -435,98 +528,126 @@ export type HypercertClaimdata361Contributors = { /** * Properties of an impact claim */ -export interface HypercertClaimdata361 { +export interface HypercertClaimdata { /** Contributors */ - contributors: HypercertClaimdata361Contributors; + contributors: HypercertClaimdataContributors; /** Scopes of impact */ - impact_scope: HypercertClaimdata361ImpactScope; + impact_scope: HypercertClaimdataImpactScope; /** Impact time period. The value is UNIX time in seconds from epoch. */ - impact_timeframe: HypercertClaimdata361ImpactTimeframe; + impact_timeframe: HypercertClaimdataImpactTimeframe; /** Rights */ - rights?: HypercertClaimdata361Rights; + rights?: HypercertClaimdataRights; /** Scopes of work */ - work_scope: HypercertClaimdata361WorkScope; + work_scope: HypercertClaimdataWorkScope; /** Work time period. The value is UNIX time in seconds from epoch. */ - work_timeframe: HypercertClaimdata361WorkTimeframe; + work_timeframe: HypercertClaimdataWorkTimeframe; [key: string]: unknown; } -/** - * Interface for a storage response. - */ -export type StorageResponse = ApiResponseCidString; - -export type ApiResponseCidStringErrors = RecordStringStringOrStringArray | Error[]; +export interface CancelSignatureRequest { + chain_id: number; + owner_address: string; + signature: string; +} -export type ApiResponseCidStringData = { +export type UploadResponseDataResultsItem = { cid: string; + fileName: string; +}; + +export type UploadResponseDataFailedItem = { + error: string; + fileName: string; +}; + +export type UploadResponseData = { + failed: UploadResponseDataFailedItem[]; + results: UploadResponseDataResultsItem[]; }; /** - * Interface for a generic API response. + * Construct a type with a set of properties K of type T */ -export interface ApiResponseCidString { - data?: ApiResponseCidStringData; - errors?: ApiResponseCidStringErrors; - message?: string; +export interface RecordStringString {[key: string]: string} + +export type UploadStatus = typeof UploadStatus[keyof typeof UploadStatus]; + + +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const UploadStatus = { + all: 'all', + some: 'some', + none: 'none', +} as const; + +export interface UploadResponse { + data?: UploadResponseData; + errors?: RecordStringString; + message: string; success: boolean; + uploadStatus: UploadStatus; } /** - * Interface for a user add or update request. */ -export interface AddOrUpdateUserRequest { - avatar: string; +export type MultisigUserUpsertRequestType = typeof MultisigUserUpsertRequestType[keyof typeof MultisigUserUpsertRequestType]; + + +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const MultisigUserUpsertRequestType = { + multisig: 'multisig', +} as const; + +export interface MultisigUserUpsertRequest { chain_id: number; - display_name: string; - signature: string; + messageHash: string; + /** */ + type: MultisigUserUpsertRequestType; } -export type ApiResponseErrors = RecordStringStringOrStringArray | Error[]; +export type AddOrUpdateUserRequest = EOAUserUpsertRequest | MultisigUserUpsertRequest; /** - * Interface for a generic API response. */ -export interface ApiResponse { - data?: unknown; - errors?: ApiResponseErrors; - message?: string; - success: boolean; -} +export type EOAUserUpsertRequestType = typeof EOAUserUpsertRequestType[keyof typeof EOAUserUpsertRequestType]; -export type ApiResponseAddressStringOrNullErrors = RecordStringStringOrStringArray | Error[]; -/** - * @nullable - */ -export type ApiResponseAddressStringOrNullData = { +// eslint-disable-next-line @typescript-eslint/no-redeclare +export const EOAUserUpsertRequestType = { + eoa: 'eoa', +} as const; + +export interface EOAUserUpsertRequest { + avatar?: string; + chain_id: number; + display_name?: string; + signature: string; + /** */ + type: EOAUserUpsertRequestType; +} + +export type UserResponseData = { address: string; -} | null; +}; /** - * Interface for a generic API response. + * Construct a type with a set of properties K of type T */ -export interface ApiResponseAddressStringOrNull { - /** @nullable */ - data?: ApiResponseAddressStringOrNullData; - errors?: ApiResponseAddressStringOrNullErrors; +export interface RecordStringStringOrStringArray {[key: string]: string | string[]} + +export interface BaseResponse { + errors?: RecordStringStringOrStringArray; message?: string; success: boolean; } -export type AddOrUpdateUserResponse = ApiResponseAddressStringOrNull; - -export interface Error { - message: string; - name: string; - stack?: string; +export interface UserResponse { + data?: UserResponseData; + errors?: RecordStringStringOrStringArray; + message?: string; + success: boolean; } -/** - * Construct a type with a set of properties K of type T - */ -export interface RecordStringStringOrStringArray {[key: string]: string | string[]} - @@ -534,7 +655,7 @@ export interface RecordStringStringOrStringArray {[key: string]: string | string /** * Add or update a user */ -export const addOrUpdateUser = >( +export const addOrUpdateUser = >( address: string, addOrUpdateUserRequest: AddOrUpdateUserRequest, options?: AxiosRequestConfig ): Promise => { @@ -544,13 +665,52 @@ export const addOrUpdateUser = >( + uploadBody?: UploadBody, options?: AxiosRequestConfig + ): Promise => {const formData = new FormData(); +if(uploadBody?.files !== undefined) { + uploadBody.files.forEach(value => formData.append('files', value)); + } +if(uploadBody?.jsonData !== undefined) { + formData.append('jsonData', uploadBody.jsonData) + } + + return axios.post( + `/v1/upload`, + formData,options + ); + } + +export const cancelSignatureRequest = >( + safeAddress: string, + messageHash: string, + cancelSignatureRequest: CancelSignatureRequest, options?: AxiosRequestConfig + ): Promise => { + return axios.post( + `/v1/signature-requests/${safeAddress}-${messageHash}/cancel`, + cancelSignatureRequest,options + ); + } + +export const processSignatureRequests = >( + options?: AxiosRequestConfig + ): Promise => { + return axios.post( + `/v1/signature-requests/process`,undefined,options + ); + } + /** * Submits a new hypercert metadata object for validation and storage on IPFS. When an allowlist URI is provided the service will validate the allowlist data before storing the metadata. Note that this might lead to a race condition when uploading metadata and the allowlist separately in rapid succession. In that case we recommend using POST /metadata/with-allowlist instead. */ -export const storeMetadata = >( +export const storeMetadata = >( storeMetadataRequest: StoreMetadataRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -565,7 +725,7 @@ The service will parse and validate the allow list data and the metadata. After successful validation, the allow list data will be uploaded to IPFS and the URI of the allowlist will be attached to the hypercert metadata. If an allow list URI is already present, the service will return an error. */ -export const storeMetadataWithAllowlist = >( +export const storeMetadataWithAllowlist = >( storeMetadataWithAllowlistRequest: StoreMetadataWithAllowlistRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -577,7 +737,7 @@ export const storeMetadataWithAllowlist = >( +export const validateMetadata = >( validateMetadataRequest: ValidateMetadataRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -589,7 +749,7 @@ export const validateMetadata = >( +export const validateMetadataWithAllowlist = >( storeMetadataWithAllowlistRequest: StoreMetadataWithAllowlistRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -649,7 +809,7 @@ export const validateOrder = >( /** * Create a new hyperboard. Creates the collections passed to it automatically. */ -export const createHyperboard = >( +export const createHyperboard = >( hyperboardCreateRequest: HyperboardCreateRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -658,7 +818,7 @@ export const createHyperboard = >( +export const updateHyperboard = >( hyperboardId: string, hyperboardUpdateRequest: HyperboardUpdateRequest, options?: AxiosRequestConfig ): Promise => { @@ -668,7 +828,7 @@ export const updateHyperboard = >( +export const deleteHyperboard = >( hyperboardId: string, params: DeleteHyperboardParams, options?: AxiosRequestConfig ): Promise => { @@ -679,13 +839,42 @@ export const deleteHyperboard = >( ); } +export const createBlueprint = >( + blueprintCreateRequest: BlueprintCreateRequest, options?: AxiosRequestConfig + ): Promise => { + return axios.post( + `/v1/blueprints`, + blueprintCreateRequest,options + ); + } + +export const deleteBlueprint = >( + blueprintId: number, + blueprintDeleteRequest: BlueprintDeleteRequest, options?: AxiosRequestConfig + ): Promise => { + return axios.delete( + `/v1/blueprints/${blueprintId}`,{data: + blueprintDeleteRequest, ...options} + ); + } + +export const mintBlueprint = >( + blueprintId: number, + blueprintQueueMintRequest: BlueprintQueueMintRequest, options?: AxiosRequestConfig + ): Promise => { + return axios.post( + `/v1/blueprints/mint/${blueprintId}`, + blueprintQueueMintRequest,options + ); + } + /** * Submits a new allowlist for validation and storage on IPFS. While we maintain a database of allowlists, the allowlist itself is stored on IPFS. Try to keep a backup of the allowlist for recovery purposes. Provide the dump of the OpenZeppelin MerkleTree and the total units. */ -export const storeAllowList = >( +export const storeAllowList = >( storeAllowListRequest: StoreAllowListRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -699,7 +888,7 @@ export const storeAllowList = >( Provide the dump of the OpenZeppelin MerkleTree and the total units. */ -export const validateAllowList = >( +export const validateAllowList = >( validateAllowListRequest: ValidateAllowListRequest, options?: AxiosRequestConfig ): Promise => { return axios.post( @@ -708,17 +897,23 @@ export const validateAllowList = -export type StoreMetadataResult = AxiosResponse -export type StoreMetadataWithAllowlistResult = AxiosResponse -export type ValidateMetadataResult = AxiosResponse -export type ValidateMetadataWithAllowlistResult = AxiosResponse +export type AddOrUpdateUserResult = AxiosResponse +export type UploadResult = AxiosResponse +export type CancelSignatureRequestResult = AxiosResponse +export type ProcessSignatureRequestsResult = AxiosResponse +export type StoreMetadataResult = AxiosResponse +export type StoreMetadataWithAllowlistResult = AxiosResponse +export type ValidateMetadataResult = AxiosResponse +export type ValidateMetadataWithAllowlistResult = AxiosResponse export type StoreOrderResult = AxiosResponse export type DeleteOrderResult = AxiosResponse export type UpdateOrderNonceResult = AxiosResponse export type ValidateOrderResult = AxiosResponse -export type CreateHyperboardResult = AxiosResponse -export type UpdateHyperboardResult = AxiosResponse -export type DeleteHyperboardResult = AxiosResponse -export type StoreAllowListResult = AxiosResponse -export type ValidateAllowListResult = AxiosResponse +export type CreateHyperboardResult = AxiosResponse +export type UpdateHyperboardResult = AxiosResponse +export type DeleteHyperboardResult = AxiosResponse +export type CreateBlueprintResult = AxiosResponse +export type DeleteBlueprintResult = AxiosResponse +export type MintBlueprintResult = AxiosResponse +export type StoreAllowListResult = AxiosResponse +export type ValidateAllowListResult = AxiosResponse diff --git a/src/utils/formatter.ts b/src/utils/formatter.ts index f994a3a..75cd9ec 100644 --- a/src/utils/formatter.ts +++ b/src/utils/formatter.ts @@ -48,7 +48,10 @@ const formatHypercertData = ({ external_url?: string; image: string; version: string; - properties?: { trait_type: string; value?: string; [k: string]: unknown }[]; + properties?: ( + | { trait_type: string; value: string } + | { trait_type: string; type: string; src: string; name: string } + )[]; impactScope: string[]; excludedImpactScope: string[]; workScope: string[]; diff --git a/test/utils/formatter.test.ts b/test/utils/formatter.test.ts index f492d5c..a28f8ec 100644 --- a/test/utils/formatter.test.ts +++ b/test/utils/formatter.test.ts @@ -17,7 +17,10 @@ const testData: Partial = { workScope: ["test work scope"], workTimeframeStart: Math.floor(new Date().getTime()) / 1000, workTimeframeEnd: Math.floor(new Date().getTime()) / 1000, - properties: [{ trait_type: "test trait type", value: "aaa" }], + properties: [ + { trait_type: "test trait type", value: "aaa" }, + { trait_type: "test trait type", type: "image", src: "https://example.com", name: "test name" }, + ], rights: ["test right 1", "test right 2"], version: "0.0.1", }; diff --git a/vitest.config.ts b/vitest.config.ts index 9cd55fe..f69360e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -10,10 +10,10 @@ export default defineConfig({ // If you want a coverage reports even if your tests are failing, include the reportOnFailure option reportOnFailure: true, thresholds: { - lines: 72, + lines: 73, branches: 84, - functions: 66, - statements: 72, + functions: 76, + statements: 77, }, include: ["src/**/*.ts"], exclude: [ @@ -21,7 +21,7 @@ export default defineConfig({ "**/*.types.ts", "**/types.ts", "src/indexer/*.ts", - "lib/*", + "src/__generated__/*.ts", ], }, },