Skip to content

Commit e523b62

Browse files
authored
Use ethers fetchJson (#1029)
* remove isomorphic-unfetch dependency in favor of ethers * add coverage folder to eslint and prettier ignore * bump version
1 parent 1cf27a2 commit e523b62

5 files changed

Lines changed: 27 additions & 93 deletions

File tree

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module.exports = {
66
node: true,
77
},
88
root: true,
9-
ignorePatterns: ["docs", "lib", "src/typechain"],
9+
ignorePatterns: ["docs", "lib", "coverage", "src/typechain"],
1010
reportUnusedDisableDirectives: true,
1111
parser: "@typescript-eslint/parser",
1212
plugins: ["@typescript-eslint", "import", "prettier"],

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
lib
22
docs
33
.nyc_output
4+
coverage
45
src/typechain

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opensea-js",
3-
"version": "6.0.2",
3+
"version": "6.0.3",
44
"description": "JavaScript SDK for the OpenSea marketplace helps developers build new experiences using NFTs and our marketplace data!",
55
"license": "MIT",
66
"author": "OpenSea Developers",
@@ -38,8 +38,7 @@
3838
"types": "lib/index.d.ts",
3939
"dependencies": {
4040
"@opensea/seaport-js": "^2.0.0",
41-
"ethers": "^5.7.2",
42-
"isomorphic-unfetch": "^4.0.2"
41+
"ethers": "^5.7.2"
4342
},
4443
"devDependencies": {
4544
"@typechain/ethers-v5": "^11.0.0",

src/api.ts

Lines changed: 22 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import "isomorphic-unfetch";
1+
import { ethers } from "ethers";
22
import { API_BASE_MAINNET, API_BASE_TESTNET, API_PATH } from "./constants";
33
import {
44
BuildOfferResponse,
@@ -382,36 +382,27 @@ export class OpenSeaAPI {
382382
*/
383383
public async get<T>(apiPath: string, query: object = {}): Promise<T> {
384384
const qs = this.objectToSearchParams(query);
385-
const url = `${apiPath}?${qs}`;
386-
387-
const response = await this._fetch(url);
388-
return response.json();
385+
const url = `${this.apiBaseUrl}${apiPath}?${qs}`;
386+
return await this._fetch({ url });
389387
}
390388

391389
/**
392390
* POST JSON data to API, sending auth token in headers
393391
* @param apiPath Path to URL endpoint under API
394392
* @param body Data to send. Will be JSON.stringified
395-
* @param opts RequestInit opts, similar to Fetch API. If it contains
396-
* a body, it won't be stringified.
393+
* @param opts ethers ConnectionInfo, similar to Fetch API.
397394
*/
398395
public async post<T>(
399396
apiPath: string,
400397
body?: object,
401-
opts: RequestInit = {}
398+
opts?: ethers.utils.ConnectionInfo
402399
): Promise<T> {
403-
const fetchOpts = {
404-
method: "POST",
405-
body: body ? JSON.stringify(body) : undefined,
406-
headers: {
407-
Accept: "application/json",
408-
"Content-Type": "application/json",
409-
},
400+
const options = {
401+
url: `${this.apiBaseUrl}${apiPath}`,
410402
...opts,
411403
};
412404

413-
const response = await this._fetch(apiPath, fetchOpts);
414-
return response.json();
405+
return await this._fetch(options, body);
415406
}
416407

417408
private objectToSearchParams(params: object = {}) {
@@ -430,86 +421,29 @@ export class OpenSeaAPI {
430421

431422
/**
432423
* Get from an API Endpoint, sending auth token in headers
433-
* @param apiPath Path to URL endpoint under API
434-
* @param opts RequestInit opts, similar to Fetch API
424+
* @param opts ethers ConnectionInfo, similar to Fetch API
425+
* @param body Optional body to send. If set, will POST, otherwise GET
435426
*/
436-
private async _fetch(apiPath: string, opts: RequestInit = {}) {
437-
const apiBase = this.apiBaseUrl;
438-
const apiKey = this.apiKey;
439-
const finalUrl = apiBase + apiPath;
440-
const finalOpts = {
427+
private async _fetch(opts: ethers.utils.ConnectionInfo, body?: object) {
428+
const headers = {
429+
"x-app-id": "opensea-js",
430+
...(this.apiKey ? { "X-API-KEY": this.apiKey } : {}),
431+
...opts.headers,
432+
};
433+
const req = {
441434
...opts,
442-
headers: {
443-
...(apiKey ? { "X-API-KEY": apiKey } : {}),
444-
"x-app-id": "opensea-js",
445-
...(opts.headers ?? {}),
446-
},
435+
headers,
447436
};
448437

449438
this.logger(
450-
`Sending request: ${finalUrl} ${JSON.stringify(finalOpts).substr(
451-
0,
452-
100
453-
)}...`
439+
`Sending request: ${opts.url} ${JSON.stringify(req).slice(0, 200)}...`
454440
);
455441

456-
return fetch(finalUrl, finalOpts).then(async (res) =>
457-
this._handleApiResponse(res)
442+
return await ethers.utils.fetchJson(
443+
req,
444+
body ? JSON.stringify(body) : undefined
458445
);
459446
}
460-
461-
private async _handleApiResponse(response: Response) {
462-
if (response.ok) {
463-
this.logger(`Got success: ${response.status}`);
464-
return response;
465-
}
466-
467-
let result;
468-
let errorMessage;
469-
try {
470-
result = await response.text();
471-
result = JSON.parse(result);
472-
} catch {
473-
// Result will be undefined or text
474-
}
475-
476-
this.logger(`Got error ${response.status}: ${JSON.stringify(result)}`);
477-
478-
switch (response.status) {
479-
case 400:
480-
errorMessage =
481-
result && result.errors
482-
? result.errors.join(", ")
483-
: `Invalid request: ${JSON.stringify(result)}`;
484-
break;
485-
case 401:
486-
case 403:
487-
errorMessage = `Unauthorized. Full message was '${JSON.stringify(
488-
result
489-
)}'`;
490-
break;
491-
case 404:
492-
errorMessage = `Not found. Full message was '${JSON.stringify(
493-
result
494-
)}'`;
495-
break;
496-
case 500:
497-
errorMessage = `Internal server error. OpenSea has been alerted, but if the problem persists please contact us via Discord: https://discord.gg/opensea - full message was ${JSON.stringify(
498-
result
499-
)}`;
500-
break;
501-
case 503:
502-
errorMessage = `Service unavailable. Please try again in a few minutes. If the problem persists please contact us via Discord: https://discord.gg/opensea - full message was ${JSON.stringify(
503-
result
504-
)}`;
505-
break;
506-
default:
507-
errorMessage = `Message: ${JSON.stringify(result)}`;
508-
break;
509-
}
510-
511-
throw new Error(`API Error ${response.status}: ${errorMessage}`);
512-
}
513447
}
514448

515449
function _throwOrContinue(error: unknown, retries: number) {

test/api/api.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ suite("API", () => {
5858
try {
5959
await mainAPI.get(`/asset/${BAYC_CONTRACT_ADDRESS}/202020202020`);
6060
} catch (error) {
61-
assert.include((error as Error).message, "Not found");
61+
assert.include((error as Error).message, "status=404");
6262
}
6363
});
6464
});

0 commit comments

Comments
 (0)