four-flap-meme-sdk 4.3.9 → 4.3.10

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.
@@ -10,7 +10,7 @@ describe('FourClient private API rate-limit fallback', () => {
10
10
  vi.stubGlobal('fetch', vi.fn(async (input) => {
11
11
  const url = String(input);
12
12
  calls.push(url);
13
- if (url.includes('bscfourapi.emit.tools')) {
13
+ if (url.includes('bscfourapi.emit.tools') || url.includes('api.emit.tools')) {
14
14
  return new Response(JSON.stringify({ code: -1013, msg: 'Too many requests, banned for 15 minutes' }), {
15
15
  status: 429,
16
16
  });
@@ -49,6 +49,25 @@ describe('FourClient private API rate-limit fallback', () => {
49
49
  expect(calls.some((url) => url.includes('example.com'))).toBe(true);
50
50
  expect(calls.some((url) => url.includes('bscfourapi.emit.tools'))).toBe(true);
51
51
  });
52
+ it('retries generateNonce on EC2 after Cloudflare proxies are banned', async () => {
53
+ const calls = [];
54
+ vi.stubGlobal('fetch', vi.fn(async (input) => {
55
+ const url = typeof input === 'string' ? input : input instanceof URL ? input.href : String(input);
56
+ calls.push(url);
57
+ if (url.includes('api.emit.tools')) {
58
+ return new Response(JSON.stringify({ code: 0, data: 'nonce-ec2' }));
59
+ }
60
+ return new Response(JSON.stringify({ code: -1013, msg: 'Too many requests, banned for 15 minutes' }), {
61
+ status: 429,
62
+ });
63
+ }));
64
+ await expect(new FourClient().generateNonce({
65
+ accountAddress: `0x${'11'.repeat(20)}`,
66
+ verifyType: 'LOGIN',
67
+ networkCode: 'BSC',
68
+ })).resolves.toBe('nonce-ec2');
69
+ expect(calls.some((url) => url.includes('api.emit.tools'))).toBe(true);
70
+ });
52
71
  it('retries generateNonce when the proxy returns HTML', async () => {
53
72
  vi.stubGlobal('fetch', vi.fn(async (input) => {
54
73
  const url = String(input);
@@ -58,6 +77,11 @@ describe('FourClient private API rate-limit fallback', () => {
58
77
  headers: { 'Content-Type': 'text/html' },
59
78
  });
60
79
  }
80
+ if (url.includes('api.emit.tools')) {
81
+ return new Response(JSON.stringify({ code: -1013, msg: 'Too many requests, banned for 15 minutes' }), {
82
+ status: 429,
83
+ });
84
+ }
61
85
  return new Response(JSON.stringify({ code: 0, data: 'nonce-2' }));
62
86
  }));
63
87
  await expect(new FourClient().generateNonce({
@@ -109,8 +109,10 @@ async function hashBlob(blob) {
109
109
  }
110
110
  /** Four.meme 限流:-1038 每日上传配额,-1013 15 分钟封禁 */
111
111
  const RATE_LIMIT_CODES = new Set([-1038, -1013]);
112
- /** Cloudflare Worker 代理(独立出口 IP,主线路被封时换这条) */
112
+ /** Cloudflare Worker 代理(与 Pages 同源反代同属 CF 出口,可能连坐) */
113
113
  const FOUR_MEME_PROXY_API = 'https://bscfourapi.emit.tools';
114
+ /** emit-api EC2 反代(新加坡出口,CF 被 -1013 后换这条) */
115
+ const FOUR_MEME_EC2_PROXY_API = 'https://api.emit.tools/v1/four-meme-api';
114
116
  /**
115
117
  * Four.meme 官方 API。浏览器走这条才是用户自己的 IP,不会被共用代理连坐封禁。
116
118
  * 官网 CORS 允许 Authorization,不允许 meme-web-access;浏览器直连时改用前者。
@@ -121,7 +123,13 @@ export class FourClient {
121
123
  uploadUrls;
122
124
  constructor(cfg) {
123
125
  this.baseUrl = cfg?.baseUrl || FOUR_MEME_PROXY_API;
124
- const urls = [this.baseUrl, ...(cfg?.uploadFallbackUrls || []), FOUR_MEME_PROXY_API, FOUR_MEME_OFFICIAL_API];
126
+ const urls = [
127
+ this.baseUrl,
128
+ ...(cfg?.uploadFallbackUrls || []),
129
+ FOUR_MEME_PROXY_API,
130
+ FOUR_MEME_EC2_PROXY_API,
131
+ FOUR_MEME_OFFICIAL_API,
132
+ ];
125
133
  // 浏览器先打官网(用户 IP);Node 仍先走调用方传入的代理
126
134
  this.uploadUrls = this.isBrowserEnv()
127
135
  ? [...new Set([FOUR_MEME_OFFICIAL_API, ...urls])]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "four-flap-meme-sdk",
3
- "version": "4.3.9",
3
+ "version": "4.3.10",
4
4
  "description": "SDK for Flap bonding curve and four.meme TokenManager",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",