Skip to content
This repository has been archived by the owner on May 16, 2024. It is now read-only.

Commit

Permalink
TD1119 Part 2 Add create primary sale workflow to SDK (#414)
Browse files Browse the repository at this point in the history
* oas gen

Signed-off-by: Frank Li <b439988l@gmail.com>

* remove create project func

Signed-off-by: Frank Li <b439988l@gmail.com>

* remove create project example

Signed-off-by: Frank Li <b439988l@gmail.com>

* add create primary sale workflow

Signed-off-by: Frank Li <b439988l@gmail.com>

* update api

Signed-off-by: Frank Li <b439988l@gmail.com>

* fix fees missed mapping

Signed-off-by: Frank Li <b439988l@gmail.com>

---------

Signed-off-by: Frank Li <b439988l@gmail.com>
  • Loading branch information
frankisawesome authored Feb 7, 2024
1 parent 4e99252 commit f70ed54
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 58 deletions.
117 changes: 60 additions & 57 deletions openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1733,6 +1733,63 @@
}
}
},
"/v1/primary_sales/signable-primary-sale-details": {
"post": {
"description": "[Experimental] Signable Create Primary Sale. This endpoint is experimental and may change in the future.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"primary-sales"
],
"summary": "[Experimental] Signable Create Primary Sale",
"operationId": "SignableCreatePrimarySale",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleParamsBody"
}
}
],
"responses": {
"200": {
"description": "OK response.",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleOKBody"
}
},
"400": {
"description": "Bad Request (400)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleBadRequestBody"
}
},
"404": {
"description": "The specified resource was not found (404)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleNotFoundBody"
}
},
"500": {
"description": "Internal Server Error (500)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleInternalServerErrorBody"
}
},
"501": {
"description": "Not Implemented Error (501)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleNotImplementedBody"
}
}
}
}
},
"/v1/primary_sales/{id}": {
"get": {
"description": "[Experimental] Get a single primary sale by ID. This endpoint is experimental and may change in the future.",
Expand Down Expand Up @@ -2179,63 +2236,6 @@
}
}
},
"/v1/signable-primary-sale-details": {
"post": {
"description": "[Experimental] Signable Create Primary Sale. This endpoint is experimental and may change in the future.",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"primary-sales"
],
"summary": "[Experimental] Signable Create Primary Sale",
"operationId": "SignableCreatePrimarySale",
"parameters": [
{
"name": "body",
"in": "body",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleParamsBody"
}
}
],
"responses": {
"200": {
"description": "OK response.",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleOKBody"
}
},
"400": {
"description": "Bad Request (400)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleBadRequestBody"
}
},
"404": {
"description": "The specified resource was not found (404)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleNotFoundBody"
}
},
"500": {
"description": "Internal Server Error (500)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleInternalServerErrorBody"
}
},
"501": {
"description": "Not Implemented Error (501)",
"schema": {
"$ref": "#/definitions/signableCreatePrimarySaleNotImplementedBody"
}
}
}
}
},
"/v1/signable-registration": {
"post": {
"description": "Get operator signature to allow clients to register the user",
Expand Down Expand Up @@ -8846,6 +8846,7 @@
"INVALID",
"IN_PROGRESS",
"ACCEPTED",
"FAILED",
"REJECTED",
"EXPIRED"
]
Expand Down Expand Up @@ -9488,6 +9489,7 @@
"INVALID",
"IN_PROGRESS",
"ACCEPTED",
"FAILED",
"REJECTED",
"EXPIRED"
]
Expand Down Expand Up @@ -11428,6 +11430,7 @@
"INVALID",
"IN_PROGRESS",
"ACCEPTED",
"FAILED",
"REJECTED",
"EXPIRED"
]
Expand Down
19 changes: 19 additions & 0 deletions src/ImmutableX.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import {
OrdersApi,
OrdersApiGetOrderV3Request,
OrdersApiListOrdersV3Request,
PrimarySalesApiSignableCreatePrimarySaleRequest,
ProjectsApi,
TokensApi,
TokensApiGetTokenRequest,
Expand Down Expand Up @@ -951,4 +952,22 @@ export class ImmutableX {
throw formatError(err);
});
}

/**
* Create a PrimarySale
* @param walletConnection - the pair of L1/L2 signers
* @param request - the request object to be provided in the API request
* @returns a promise that resolves with the created Trade
* @throws {@link index.IMXError}
*/
public createPrimarySale(
walletConnection: WalletConnection,
request: PrimarySalesApiSignableCreatePrimarySaleRequest,
) {
return this.workflows
.createPrimarySale(walletConnection, request)
.catch(err => {
throw formatError(err);
});
}
}
2 changes: 1 addition & 1 deletion src/api/domain/primary-sales-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ export const PrimarySalesApiAxiosParamCreator = function (configuration?: Config
* @throws {RequiredError}
*/
signableCreatePrimarySale: async (body?: SignableCreatePrimarySaleParamsBody, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/v1/signable-primary-sale-details`;
const localVarPath = `/v1/primary_sales/signable-primary-sale-details`;
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
Expand Down
1 change: 1 addition & 0 deletions src/api/models/accept-primary-sale-okbody-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const AcceptPrimarySaleOKBodyResultStatusEnum = {
Invalid: 'INVALID',
InProgress: 'IN_PROGRESS',
Accepted: 'ACCEPTED',
Failed: 'FAILED',
Rejected: 'REJECTED',
Expired: 'EXPIRED'
} as const;
Expand Down
1 change: 1 addition & 0 deletions src/api/models/create-primary-sale-created-body-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const CreatePrimarySaleCreatedBodyResultStatusEnum = {
Invalid: 'INVALID',
InProgress: 'IN_PROGRESS',
Accepted: 'ACCEPTED',
Failed: 'FAILED',
Rejected: 'REJECTED',
Expired: 'EXPIRED'
} as const;
Expand Down
1 change: 1 addition & 0 deletions src/api/models/get-primary-sale-okbody-result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ export const GetPrimarySaleOKBodyResultStatusEnum = {
Invalid: 'INVALID',
InProgress: 'IN_PROGRESS',
Accepted: 'ACCEPTED',
Failed: 'FAILED',
Rejected: 'REJECTED',
Expired: 'EXPIRED'
} as const;
Expand Down
79 changes: 79 additions & 0 deletions src/workflows/primarySales.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
CreatePrimarySaleBadRequestBody,
CreatePrimarySaleCreatedBody,
CreatePrimarySaleForbiddenBody,
CreatePrimarySaleNotFoundBody,
CreatePrimarySaleUnauthorizedBody,
PrimarySalesApi,
PrimarySalesApiCreatePrimarySaleRequest,
PrimarySalesApiSignableCreatePrimarySaleRequest,
} from '../api';
import { WalletConnection } from '../types';
import { signRaw } from '../utils';

type CreatePrimarySaleWorkflowParams = WalletConnection & {
request: PrimarySalesApiSignableCreatePrimarySaleRequest;
primarySalesApi: PrimarySalesApi;
};

type CreatePrimarySaleResponse =
| CreatePrimarySaleBadRequestBody
| CreatePrimarySaleCreatedBody
| CreatePrimarySaleForbiddenBody
| CreatePrimarySaleUnauthorizedBody
| CreatePrimarySaleNotFoundBody;

export async function CreatePrimarySaleWorkflow({
ethSigner,
starkSigner,
request,
primarySalesApi,
}: CreatePrimarySaleWorkflowParams): Promise<CreatePrimarySaleResponse> {
const ethAddress = await ethSigner.getAddress();

const signablePrimarySaleResponse =
await primarySalesApi.signableCreatePrimarySale(request);

const { signable_message: signableMessage, payload_hash: payloadHash } =
signablePrimarySaleResponse.data;

const ethSignature = await signRaw(signableMessage, ethSigner);

const starkSignature = await starkSigner.signMessage(payloadHash);

const resp = signablePrimarySaleResponse.data;

const primarySaleParams: PrimarySalesApiCreatePrimarySaleRequest = {
body: {
buyer_ether_key: resp.buyer_ether_key,
buyer_stark_key: resp.buyer_stark_key,
buyer_vault_id: resp.buyer_vault_id,
studio_ether_key: resp.studio_ether_key,
studio_data: resp.studio_data,
payment_amount: resp.payment_amount,
payment_asset_id: resp.payment_asset_id,
payment_recipient_ether_key: resp.payment_recipient_ether_key,
payment_recipient_stark_key: resp.payment_recipient_stark_key,
payment_recipient_vault_id: resp.payment_recipient_vault_id,
items_recipient_ether_key: resp.items_recipient_ether_key,
expiration_timestamp: resp.expiration_timestamp,
fees: resp.fees,
nonce: resp.nonce,
stark_signature: starkSignature,
},
};

const createPrimarySaleResp = await primarySalesApi.createPrimarySale(
primarySaleParams,
{
headers: {
'x-imx-eth-address': ethAddress,
'x-imx-eth-signature': ethSignature,
},
},
);

return {
...createPrimarySaleResp.data,
};
}
18 changes: 18 additions & 0 deletions src/workflows/workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
MetadataRefreshesApi,
CreateMetadataRefreshRequest,
ExchangesApi,
PrimarySalesApiSignableCreatePrimarySaleRequest,
PrimarySalesApi,
} from '../api';
import {
UnsignedMintRequest,
Expand Down Expand Up @@ -62,6 +64,7 @@ import { generateIMXAuthorisationHeaders } from '../utils';
import { ImmutableXConfiguration } from '../config';
import { exchangeTransfersWorkflow } from './exchangeTransfers';
import axios, { AxiosResponse } from 'axios';
import { CreatePrimarySaleWorkflow } from './primarySales';

export class Workflows {
private readonly depositsApi: DepositsApi;
Expand All @@ -78,6 +81,7 @@ export class Workflows {
private readonly metadataApi: MetadataApi;
private readonly metadataRefreshesApi: MetadataRefreshesApi;
private readonly exchangesApi: ExchangesApi;
private readonly primarySalesApi: PrimarySalesApi;

private isChainValid(chainID: number) {
return chainID === this.config.ethConfiguration.chainID;
Expand All @@ -101,6 +105,7 @@ export class Workflows {
this.metadataApi = new MetadataApi(apiConfiguration);
this.metadataRefreshesApi = new MetadataRefreshesApi(apiConfiguration);
this.exchangesApi = new ExchangesApi(apiConfiguration);
this.primarySalesApi = new PrimarySalesApi(apiConfiguration);
}

private async validateChain(signer: Signer) {
Expand Down Expand Up @@ -509,4 +514,17 @@ export class Workflows {
createMetadataRefreshRequest: request,
});
}

public async createPrimarySale(
walletConnection: WalletConnection,
request: PrimarySalesApiSignableCreatePrimarySaleRequest,
) {
await this.validateChain(walletConnection.ethSigner);

return CreatePrimarySaleWorkflow({
...walletConnection,
request,
primarySalesApi: this.primarySalesApi,
});
}
}

0 comments on commit f70ed54

Please sign in to comment.