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

Commit

Permalink
Implement getOrdersForPageAsync for browsers
Browse files Browse the repository at this point in the history
  • Loading branch information
albrow committed Jan 17, 2020
1 parent f6e2946 commit 966a4d3
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
23 changes: 23 additions & 0 deletions browser/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,17 @@ func (cw *MeshWrapper) GetStats() (js.Value, error) {
return js.ValueOf(stats), nil
}

// GetOrders converts raw JavaScript parameters into the appropriate type, calls
// core.App.GetOrders, converts the result into basic JavaScript types (string,
// int, etc.) and returns it.
func (cw *MeshWrapper) GetOrders(page int, perPage int, snapshotID string) (js.Value, error) {
ordersResponse, err := cw.app.GetOrders(page, perPage, snapshotID)
if err != nil {
return js.Undefined(), err
}
return js.ValueOf(ordersResponse), nil
}

// JSValue satisfies the js.Wrapper interface. The return value is a JavaScript
// object consisting of named functions. They act like methods by capturing the
// MeshWrapper through a closure.
Expand Down Expand Up @@ -269,6 +280,18 @@ func (cw *MeshWrapper) JSValue() js.Value {
return cw.GetStats()
})
}),
// getOrdersForPageAsync(page: number, perPage: number, snapshotID?: string): Promise<GetOrdersResponse>
"getOrdersForPageAsync": js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return wrapInPromise(func() (interface{}, error) {
// snapshotID is optional in the JavaScript function. Check if it is
// null or undefined.
snapshotID := ""
if !isNullOrUndefined(args[2]) {
snapshotID = args[2].String()
}
return cw.GetOrders(args[0].Int(), args[1].Int(), snapshotID)
})
}),
// addOrdersAsync(orders: Array<SignedOrder>): Promise<ValidationResults>
"addOrdersAsync": js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return wrapInPromise(func() (interface{}, error) {
Expand Down
61 changes: 61 additions & 0 deletions browser/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,30 @@ export interface Stats {
ethRPCRateLimitExpiredRequests: number;
}

interface WrapperOrderInfo {
orderHash: string;
signedOrder: WrapperSignedOrder;
fillableTakerAssetAmount: string;
}

export interface OrderInfo {
orderHash: string;
signedOrder: SignedOrder;
fillableTakerAssetAmount: BigNumber;
}

interface WrapperGetOrdersResponse {
snapshotID: string;
snapshotTimestamp: number;
ordersInfos: WrapperOrderInfo[];
}

export interface GetOrdersResponse {
snapshotID: string;
snapshotTimestamp: number;
ordersInfos: OrderInfo[];
}

export enum Verbosity {
Panic = 0,
Fatal = 1,
Expand All @@ -275,6 +299,7 @@ interface MeshWrapper {
onError(handler: (err: Error) => void): void;
onOrderEvents(handler: (events: WrapperOrderEvent[]) => void): void;
getStatsAsync(): Promise<WrapperStats>;
getOrdersForPageAsync(page: number, perPage: number, snapshotID?: string): Promise<WrapperGetOrdersResponse>;
addOrdersAsync(orders: WrapperSignedOrder[], pinned: boolean): Promise<WrapperValidationResults>;
}

Expand Down Expand Up @@ -761,6 +786,25 @@ export class Mesh {
return wrapperStatsToStats(wrapperStats);
}

/**
* Get page of 0x signed orders stored on the Mesh node at the specified snapshot
* @param page Page index at which to retrieve orders
* @param perPage Number of signedOrders to fetch per paginated request
* @param snapshotID The DB snapshot at which to fetch orders. If omitted, a new snapshot is created
* @returns the snapshotID, snapshotTimestamp and all orders, their hashes and fillableTakerAssetAmounts
*/
public async getOrdersForPageAsync(page: number, perPage: number, snapshotID?: string): Promise<GetOrdersResponse> {
await waitForLoadAsync();
if (this._wrapper === undefined) {
// If this is called after startAsync, this._wrapper is always
// defined. This check is here just in case and satisfies the
// compiler.
return Promise.reject(new Error('Mesh is still loading. Try again soon.'));
}
const wrapperOrderResponse = await this._wrapper.getOrdersForPageAsync(page, perPage, snapshotID);
return wrapperGetOrdersResponseToGetOrdersResponse(wrapperOrderResponse);
}

/**
* Validates and adds the given orders to Mesh. If an order is successfully
* added, Mesh will share it with any peers in the network and start
Expand Down Expand Up @@ -1003,6 +1047,23 @@ function wrapperStatsToStats(wrapperStats: WrapperStats): Stats {
};
}

function wrapperGetOrdersResponseToGetOrdersResponse(
wrapperGetOrdersResponse: WrapperGetOrdersResponse,
): GetOrdersResponse {
return {
...wrapperGetOrdersResponse,
ordersInfos: wrapperGetOrdersResponse.ordersInfos.map(wrapperOrderInfoToOrderInfo),
};
}

function wrapperOrderInfoToOrderInfo(wrapperOrderInfo: WrapperOrderInfo): OrderInfo {
return {
...wrapperOrderInfo,
fillableTakerAssetAmount: new BigNumber(wrapperOrderInfo.fillableTakerAssetAmount),
signedOrder: wrapperSignedOrderToSignedOrder(wrapperOrderInfo.signedOrder),
};
}

function wrapperValidationResultsToValidationResults(
wrapperValidationResults: WrapperValidationResults,
): ValidationResults {
Expand Down
11 changes: 11 additions & 0 deletions common/types/types_js.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ func (s *Stats) JSValue() js.Value {
statsJS := js.Global().Get("JSON").Call("parse", string(encodedStats))
return statsJS
}

func (r *GetOrdersResponse) JSValue() js.Value {
// TODO(albrow): Optimize this. Remove other uses of the JSON
// encoding/decoding hack.
encodedResponse, err := json.Marshal(r)
if err != nil {
panic(err)
}
responseJS := js.Global().Get("JSON").Call("parse", string(encodedResponse))
return responseJS
}
17 changes: 14 additions & 3 deletions integration-tests/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,20 @@ provider.start();
// canceled, or filled. We will check for certain events to be logged in the
// integration tests.
mesh.onOrderEvents((events: Array<OrderEvent>) => {
for (let event of events) {
console.log(JSON.stringify(event));
}
(async () => {
for (let event of events) {
// Check the happy path for getOrdersForPageAsync. There should
// be two orders.
const firstOrdersResponse = await mesh.getOrdersForPageAsync(0, 1, '');
console.log(JSON.stringify(firstOrdersResponse));
const secondOrdersResponse = await mesh.getOrdersForPageAsync(1, 1, firstOrdersResponse.snapshotID);
console.log(JSON.stringify(secondOrdersResponse));

// Log the event. The Go code will be watching the logs for
// this.
console.log(JSON.stringify(event));
}
})().catch(err => console.error(err));
});

// Start Mesh *after* we set up the handlers.
Expand Down

0 comments on commit 966a4d3

Please sign in to comment.