@thirdweb-dev/service-utils 0.4.38 → 0.4.39

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.
Files changed (149) hide show
  1. package/dist/cjs/cf-worker/index.js +155 -0
  2. package/dist/cjs/cf-worker/index.js.map +1 -0
  3. package/dist/cjs/cf-worker/usage.js +55 -0
  4. package/dist/cjs/cf-worker/usage.js.map +1 -0
  5. package/dist/cjs/core/api.js +65 -0
  6. package/dist/cjs/core/api.js.map +1 -0
  7. package/dist/cjs/core/authorize/client.js +115 -0
  8. package/dist/cjs/core/authorize/client.js.map +1 -0
  9. package/dist/cjs/core/authorize/index.js +215 -0
  10. package/dist/cjs/core/authorize/index.js.map +1 -0
  11. package/dist/cjs/core/authorize/service.js +58 -0
  12. package/dist/cjs/core/authorize/service.js.map +1 -0
  13. package/dist/cjs/core/authorize/types.js +3 -0
  14. package/dist/cjs/core/authorize/types.js.map +1 -0
  15. package/dist/cjs/core/rateLimit/index.js +64 -0
  16. package/dist/cjs/core/rateLimit/index.js.map +1 -0
  17. package/dist/cjs/core/rateLimit/types.js +3 -0
  18. package/dist/cjs/core/rateLimit/types.js.map +1 -0
  19. package/dist/cjs/core/services.js +71 -0
  20. package/dist/cjs/core/services.js.map +1 -0
  21. package/dist/cjs/core/types.js +3 -0
  22. package/dist/cjs/core/types.js.map +1 -0
  23. package/dist/cjs/core/usage.js +93 -0
  24. package/dist/cjs/core/usage.js.map +1 -0
  25. package/dist/cjs/core/usageLimit/index.js +45 -0
  26. package/dist/cjs/core/usageLimit/index.js.map +1 -0
  27. package/dist/cjs/core/usageLimit/types.js +3 -0
  28. package/dist/cjs/core/usageLimit/types.js.map +1 -0
  29. package/dist/cjs/index.js +10 -0
  30. package/dist/cjs/index.js.map +1 -0
  31. package/dist/cjs/mocks.js +53 -0
  32. package/dist/cjs/mocks.js.map +1 -0
  33. package/dist/cjs/node/index.js +173 -0
  34. package/dist/cjs/node/index.js.map +1 -0
  35. package/dist/cjs/package.json +1 -0
  36. package/dist/esm/cf-worker/index.js +147 -0
  37. package/dist/esm/cf-worker/index.js.map +1 -0
  38. package/dist/esm/cf-worker/usage.js +54 -0
  39. package/dist/esm/cf-worker/usage.js.map +1 -0
  40. package/dist/esm/core/api.js +60 -0
  41. package/dist/esm/core/api.js.map +1 -0
  42. package/dist/esm/core/authorize/client.js +110 -0
  43. package/dist/esm/core/authorize/client.js.map +1 -0
  44. package/dist/esm/core/authorize/index.js +212 -0
  45. package/dist/esm/core/authorize/index.js.map +1 -0
  46. package/dist/esm/core/authorize/service.js +55 -0
  47. package/dist/esm/core/authorize/service.js.map +1 -0
  48. package/dist/esm/core/authorize/types.js +2 -0
  49. package/dist/esm/core/authorize/types.js.map +1 -0
  50. package/dist/esm/core/rateLimit/index.js +61 -0
  51. package/dist/esm/core/rateLimit/index.js.map +1 -0
  52. package/dist/esm/core/rateLimit/types.js +2 -0
  53. package/dist/esm/core/rateLimit/types.js.map +1 -0
  54. package/dist/esm/core/services.js +67 -0
  55. package/dist/esm/core/services.js.map +1 -0
  56. package/dist/esm/core/types.js +2 -0
  57. package/dist/esm/core/types.js.map +1 -0
  58. package/dist/esm/core/usage.js +90 -0
  59. package/dist/esm/core/usage.js.map +1 -0
  60. package/dist/esm/core/usageLimit/index.js +42 -0
  61. package/dist/esm/core/usageLimit/index.js.map +1 -0
  62. package/dist/esm/core/usageLimit/types.js +2 -0
  63. package/dist/esm/core/usageLimit/types.js.map +1 -0
  64. package/dist/esm/index.js +4 -0
  65. package/dist/esm/index.js.map +1 -0
  66. package/dist/esm/mocks.js +50 -0
  67. package/dist/esm/mocks.js.map +1 -0
  68. package/dist/esm/node/index.js +165 -0
  69. package/dist/esm/node/index.js.map +1 -0
  70. package/dist/esm/package.json +1 -0
  71. package/dist/{declarations/src → types}/cf-worker/index.d.ts +8 -8
  72. package/dist/types/cf-worker/index.d.ts.map +1 -0
  73. package/dist/{declarations/src → types}/cf-worker/usage.d.ts +3 -2
  74. package/dist/types/cf-worker/usage.d.ts.map +1 -0
  75. package/dist/{declarations/src → types}/core/api.d.ts +1 -1
  76. package/dist/types/core/api.d.ts.map +1 -0
  77. package/dist/{declarations/src → types}/core/authorize/client.d.ts +2 -2
  78. package/dist/types/core/authorize/client.d.ts.map +1 -0
  79. package/dist/{declarations/src → types}/core/authorize/index.d.ts +2 -2
  80. package/dist/types/core/authorize/index.d.ts.map +1 -0
  81. package/dist/{declarations/src → types}/core/authorize/service.d.ts +2 -2
  82. package/dist/types/core/authorize/service.d.ts.map +1 -0
  83. package/dist/{declarations/src → types}/core/authorize/types.d.ts +1 -1
  84. package/dist/types/core/authorize/types.d.ts.map +1 -0
  85. package/dist/{declarations/src → types}/core/rateLimit/index.d.ts +3 -3
  86. package/dist/types/core/rateLimit/index.d.ts.map +1 -0
  87. package/dist/types/core/rateLimit/types.d.ts.map +1 -0
  88. package/dist/types/core/services.d.ts.map +1 -0
  89. package/dist/types/core/types.d.ts.map +1 -0
  90. package/dist/{declarations/src → types}/core/usage.d.ts +2 -2
  91. package/dist/types/core/usage.d.ts.map +1 -0
  92. package/dist/types/core/usageLimit/index.d.ts +5 -0
  93. package/dist/types/core/usageLimit/index.d.ts.map +1 -0
  94. package/dist/types/core/usageLimit/types.d.ts.map +1 -0
  95. package/dist/types/index.d.ts +3 -0
  96. package/dist/types/index.d.ts.map +1 -0
  97. package/dist/types/mocks.d.ts +5 -0
  98. package/dist/types/mocks.d.ts.map +1 -0
  99. package/dist/{declarations/src → types}/node/index.d.ts +8 -8
  100. package/dist/types/node/index.d.ts.map +1 -0
  101. package/package.json +36 -29
  102. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.d.ts +0 -2
  103. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.d.ts.map +0 -1
  104. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.dev.js +0 -226
  105. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.js +0 -7
  106. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.prod.js +0 -226
  107. package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.esm.js +0 -212
  108. package/cf-worker/package.json +0 -4
  109. package/dist/client-8440b8fb.esm.js +0 -195
  110. package/dist/client-84e46164.cjs.prod.js +0 -203
  111. package/dist/client-a5cc5822.cjs.dev.js +0 -203
  112. package/dist/declarations/src/cf-worker/index.d.ts.map +0 -1
  113. package/dist/declarations/src/cf-worker/usage.d.ts.map +0 -1
  114. package/dist/declarations/src/core/api.d.ts.map +0 -1
  115. package/dist/declarations/src/core/authorize/client.d.ts.map +0 -1
  116. package/dist/declarations/src/core/authorize/index.d.ts.map +0 -1
  117. package/dist/declarations/src/core/authorize/service.d.ts.map +0 -1
  118. package/dist/declarations/src/core/authorize/types.d.ts.map +0 -1
  119. package/dist/declarations/src/core/rateLimit/index.d.ts.map +0 -1
  120. package/dist/declarations/src/core/rateLimit/types.d.ts.map +0 -1
  121. package/dist/declarations/src/core/services.d.ts.map +0 -1
  122. package/dist/declarations/src/core/types.d.ts.map +0 -1
  123. package/dist/declarations/src/core/usage.d.ts.map +0 -1
  124. package/dist/declarations/src/core/usageLimit/index.d.ts +0 -5
  125. package/dist/declarations/src/core/usageLimit/index.d.ts.map +0 -1
  126. package/dist/declarations/src/core/usageLimit/types.d.ts.map +0 -1
  127. package/dist/declarations/src/index.d.ts +0 -3
  128. package/dist/declarations/src/index.d.ts.map +0 -1
  129. package/dist/declarations/src/node/index.d.ts.map +0 -1
  130. package/dist/index-23f268d8.cjs.prod.js +0 -540
  131. package/dist/index-5dc16842.esm.js +0 -535
  132. package/dist/index-88f1ffb6.cjs.dev.js +0 -540
  133. package/dist/thirdweb-dev-service-utils.cjs.d.ts +0 -2
  134. package/dist/thirdweb-dev-service-utils.cjs.d.ts.map +0 -1
  135. package/dist/thirdweb-dev-service-utils.cjs.dev.js +0 -14
  136. package/dist/thirdweb-dev-service-utils.cjs.js +0 -7
  137. package/dist/thirdweb-dev-service-utils.cjs.prod.js +0 -14
  138. package/dist/thirdweb-dev-service-utils.esm.js +0 -1
  139. package/node/dist/thirdweb-dev-service-utils-node.cjs.d.ts +0 -2
  140. package/node/dist/thirdweb-dev-service-utils-node.cjs.d.ts.map +0 -1
  141. package/node/dist/thirdweb-dev-service-utils-node.cjs.dev.js +0 -190
  142. package/node/dist/thirdweb-dev-service-utils-node.cjs.js +0 -7
  143. package/node/dist/thirdweb-dev-service-utils-node.cjs.prod.js +0 -190
  144. package/node/dist/thirdweb-dev-service-utils-node.esm.js +0 -176
  145. package/node/package.json +0 -4
  146. /package/dist/{declarations/src → types}/core/rateLimit/types.d.ts +0 -0
  147. /package/dist/{declarations/src → types}/core/services.d.ts +0 -0
  148. /package/dist/{declarations/src → types}/core/types.d.ts +0 -0
  149. /package/dist/{declarations/src → types}/core/usageLimit/types.d.ts +0 -0
@@ -0,0 +1,55 @@
1
+ export function authorizeService(apiKeyMetadata, serviceConfig, authorizationPayload) {
2
+ const { services } = apiKeyMetadata;
3
+ // validate services
4
+ const service = services.find((srv) => srv.name === serviceConfig.serviceScope);
5
+ if (!service) {
6
+ return {
7
+ authorized: false,
8
+ errorMessage: `Invalid request: Unauthorized service: ${serviceConfig.serviceScope}. You can view the restrictions on this API key in your dashboard: https://thirdweb.com/create-api-key`,
9
+ errorCode: "SERVICE_UNAUTHORIZED",
10
+ status: 403,
11
+ };
12
+ }
13
+ // validate service actions
14
+ if (serviceConfig.serviceAction) {
15
+ const isActionAllowed = service.actions.includes(serviceConfig.serviceAction);
16
+ if (!isActionAllowed) {
17
+ return {
18
+ authorized: false,
19
+ errorMessage: `Invalid request: Unauthorized action: ${serviceConfig.serviceScope} ${serviceConfig.serviceAction}. You can view the restrictions on this API key in your dashboard: https://thirdweb.com/create-api-key`,
20
+ errorCode: "SERVICE_ACTION_UNAUTHORIZED",
21
+ status: 403,
22
+ };
23
+ }
24
+ }
25
+ // validate service target addresses
26
+ // the service has to pass in the target address for this to be validated
27
+ if (authorizationPayload?.targetAddress) {
28
+ const checkedAddresses = Array.isArray(authorizationPayload.targetAddress)
29
+ ? authorizationPayload.targetAddress
30
+ : [authorizationPayload.targetAddress];
31
+ const allAllowed = service.targetAddresses.includes("*");
32
+ if (!allAllowed &&
33
+ checkedAddresses.some((ta) => !service.targetAddresses.includes(ta))) {
34
+ return {
35
+ authorized: false,
36
+ errorMessage: `Invalid request: Unauthorized address: ${serviceConfig.serviceScope} ${checkedAddresses}. You can view the restrictions on this API key in your dashboard: https://thirdweb.com/create-api-key`,
37
+ errorCode: "SERVICE_TARGET_ADDRESS_UNAUTHORIZED",
38
+ status: 403,
39
+ };
40
+ }
41
+ }
42
+ return {
43
+ authorized: true,
44
+ apiKeyMeta: apiKeyMetadata,
45
+ accountMeta: {
46
+ id: apiKeyMetadata.accountId,
47
+ name: "",
48
+ creatorWalletAddress: apiKeyMetadata.creatorWalletAddress,
49
+ limits: apiKeyMetadata.limits,
50
+ rateLimits: apiKeyMetadata.rateLimits,
51
+ usage: apiKeyMetadata.usage,
52
+ },
53
+ };
54
+ }
55
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../src/core/authorize/service.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,gBAAgB,CAC9B,cAA8B,EAC9B,aAAgC,EAChC,oBAAkD;IAElD,MAAM,EAAE,QAAQ,EAAE,GAAG,cAAc,CAAC;IACpC,oBAAoB;IACpB,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAC3B,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,aAAa,CAAC,YAAY,CACjD,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,0CAA0C,aAAa,CAAC,YAAY,yGAAyG;YAC3L,SAAS,EAAE,sBAAsB;YACjC,MAAM,EAAE,GAAG;SACZ,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,aAAa,CAAC,aAAa,EAAE,CAAC;QAChC,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAC9C,aAAa,CAAC,aAAa,CAC5B,CAAC;QACF,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,YAAY,EAAE,yCAAyC,aAAa,CAAC,YAAY,IAAI,aAAa,CAAC,aAAa,yGAAyG;gBACzN,SAAS,EAAE,6BAA6B;gBACxC,MAAM,EAAE,GAAG;aACZ,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,yEAAyE;IACzE,IAAI,oBAAoB,EAAE,aAAa,EAAE,CAAC;QACxC,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAC,aAAa,CAAC;YACxE,CAAC,CAAC,oBAAoB,CAAC,aAAa;YACpC,CAAC,CAAC,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAEzC,MAAM,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAEzD,IACE,CAAC,UAAU;YACX,gBAAgB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EACpE,CAAC;YACD,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,YAAY,EAAE,0CAA0C,aAAa,CAAC,YAAY,IAAI,gBAAgB,yGAAyG;gBAC/M,SAAS,EAAE,qCAAqC;gBAChD,MAAM,EAAE,GAAG;aACZ,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,UAAU,EAAE,IAAI;QAChB,UAAU,EAAE,cAAc;QAC1B,WAAW,EAAE;YACX,EAAE,EAAE,cAAc,CAAC,SAAS;YAC5B,IAAI,EAAE,EAAE;YACR,oBAAoB,EAAE,cAAc,CAAC,oBAAoB;YACzD,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,UAAU,EAAE,cAAc,CAAC,UAAU;YACrC,KAAK,EAAE,cAAc,CAAC,KAAK;SAC5B;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/authorize/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ import { updateRateLimitedAt } from "../api.js";
2
+ const RATE_LIMIT_WINDOW_SECONDS = 10;
3
+ export async function rateLimit(args) {
4
+ const { authzResult, serviceConfig, redis, sampleRate = 1.0 } = args;
5
+ const shouldSampleRequest = Math.random() < sampleRate;
6
+ if (!shouldSampleRequest || !authzResult.authorized) {
7
+ return {
8
+ rateLimited: false,
9
+ requestCount: 0,
10
+ rateLimit: 0,
11
+ };
12
+ }
13
+ const { apiKeyMeta, accountMeta } = authzResult;
14
+ const accountId = apiKeyMeta?.accountId || accountMeta?.id;
15
+ const { serviceScope } = serviceConfig;
16
+ const limitPerSecond = apiKeyMeta?.rateLimits?.[serviceScope] ??
17
+ accountMeta?.rateLimits?.[serviceScope];
18
+ if (!limitPerSecond) {
19
+ // No rate limit is provided. Assume the request is not rate limited.
20
+ return {
21
+ rateLimited: false,
22
+ requestCount: 0,
23
+ rateLimit: 0,
24
+ };
25
+ }
26
+ // Gets the 10-second window for the current timestamp.
27
+ const timestampWindow = Math.floor(Date.now() / (1000 * RATE_LIMIT_WINDOW_SECONDS)) *
28
+ RATE_LIMIT_WINDOW_SECONDS;
29
+ const key = `rate-limit:${serviceScope}:${accountId}:${timestampWindow}`;
30
+ // Increment and get the current request count in this window.
31
+ const requestCount = await redis.incr(key);
32
+ if (requestCount === 1) {
33
+ // For the first increment, set an expiration to clean up this key.
34
+ await redis.expire(key, RATE_LIMIT_WINDOW_SECONDS);
35
+ }
36
+ // Get the limit for this window accounting for the sample rate.
37
+ const limitPerWindow = limitPerSecond * sampleRate * RATE_LIMIT_WINDOW_SECONDS;
38
+ if (requestCount > limitPerWindow) {
39
+ // Report rate limit hits.
40
+ if (apiKeyMeta?.id) {
41
+ await updateRateLimitedAt(apiKeyMeta.id, serviceConfig);
42
+ }
43
+ // Reject requests when they've exceeded 2x the rate limit.
44
+ if (requestCount > 2 * limitPerWindow) {
45
+ return {
46
+ rateLimited: true,
47
+ requestCount,
48
+ rateLimit: limitPerWindow,
49
+ status: 429,
50
+ errorMessage: `You've exceeded your ${serviceScope} rate limit at ${limitPerSecond} reqs/sec. To get higher rate limits, contact us at https://thirdweb.com/contact-us.`,
51
+ errorCode: "RATE_LIMIT_EXCEEDED",
52
+ };
53
+ }
54
+ }
55
+ return {
56
+ rateLimited: false,
57
+ requestCount,
58
+ rateLimit: limitPerWindow,
59
+ };
60
+ }
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/rateLimit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAIxE,MAAM,yBAAyB,GAAG,EAAE,CAAC;AAQrC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAU/B;IACC,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;IAErE,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC;IACvD,IAAI,CAAC,mBAAmB,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QACpD,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;SACb,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;IAChD,MAAM,SAAS,GAAG,UAAU,EAAE,SAAS,IAAI,WAAW,EAAE,EAAE,CAAC;IAE3D,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CAAC;IACvC,MAAM,cAAc,GAClB,UAAU,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC;QACtC,WAAW,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC,CAAC;IAE1C,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,qEAAqE;QACrE,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;SACb,CAAC;IACJ,CAAC;IAED,uDAAuD;IACvD,MAAM,eAAe,GACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,GAAG,yBAAyB,CAAC,CAAC;QAC3D,yBAAyB,CAAC;IAC5B,MAAM,GAAG,GAAG,cAAc,YAAY,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;IAEzE,8DAA8D;IAC9D,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACvB,mEAAmE;QACnE,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;IACrD,CAAC;IAED,gEAAgE;IAChE,MAAM,cAAc,GAClB,cAAc,GAAG,UAAU,GAAG,yBAAyB,CAAC;IAE1D,IAAI,YAAY,GAAG,cAAc,EAAE,CAAC;QAClC,0BAA0B;QAC1B,IAAI,UAAU,EAAE,EAAE,EAAE,CAAC;YACnB,MAAM,mBAAmB,CAAC,UAAU,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAC1D,CAAC;QAED,2DAA2D;QAC3D,IAAI,YAAY,GAAG,CAAC,GAAG,cAAc,EAAE,CAAC;YACtC,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,YAAY;gBACZ,SAAS,EAAE,cAAc;gBACzB,MAAM,EAAE,GAAG;gBACX,YAAY,EAAE,wBAAwB,YAAY,kBAAkB,cAAc,sFAAsF;gBACxK,SAAS,EAAE,qBAAqB;aACjC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO;QACL,WAAW,EAAE,KAAK;QAClB,YAAY;QACZ,SAAS,EAAE,cAAc;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/rateLimit/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ export const SERVICE_DEFINITIONS = {
2
+ storage: {
3
+ name: "storage",
4
+ title: "Storage",
5
+ description: "IPFS Upload and Download",
6
+ actions: [
7
+ {
8
+ name: "read",
9
+ title: "Download",
10
+ description: "Download a file from Storage",
11
+ },
12
+ {
13
+ name: "write",
14
+ title: "Upload",
15
+ description: "Upload a file to Storage",
16
+ },
17
+ ],
18
+ },
19
+ rpc: {
20
+ name: "rpc",
21
+ title: "RPC",
22
+ description: "Accelerated RPC Edge",
23
+ // all actions allowed
24
+ actions: [],
25
+ },
26
+ bundler: {
27
+ name: "bundler",
28
+ title: "Account Abstraction",
29
+ description: "Bundler & Paymaster services",
30
+ // all actions allowed
31
+ actions: [],
32
+ },
33
+ relayer: {
34
+ name: "relayer",
35
+ title: "Gasless Relayer",
36
+ description: "Enable gasless transactions",
37
+ // all actions allowed
38
+ actions: [],
39
+ },
40
+ embeddedWallets: {
41
+ name: "embeddedWallets",
42
+ title: "In-App Wallets",
43
+ description: "E-mail and social login wallets for easy web3 onboarding",
44
+ // all actions allowed
45
+ actions: [],
46
+ },
47
+ pay: {
48
+ name: "pay",
49
+ title: "Pay",
50
+ description: "Pay for a blockchain transaction with any currency",
51
+ // all actions allowed
52
+ actions: [],
53
+ },
54
+ chainsaw: {
55
+ name: "chainsaw",
56
+ title: "Chainsaw",
57
+ description: "Indexed data for any EVM chain",
58
+ // all actions allowed
59
+ actions: [],
60
+ },
61
+ };
62
+ export const SERVICE_NAMES = Object.keys(SERVICE_DEFINITIONS);
63
+ export const SERVICES = Object.values(SERVICE_DEFINITIONS);
64
+ export function getServiceByName(name) {
65
+ return SERVICE_DEFINITIONS[name];
66
+ }
67
+ //# sourceMappingURL=services.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../../src/core/services.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,WAAW,EAAE,0BAA0B;QACvC,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,UAAU;gBACjB,WAAW,EAAE,8BAA8B;aAC5C;YACD;gBACE,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE,0BAA0B;aACxC;SACF;KACF;IACD,GAAG,EAAE;QACH,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,sBAAsB;QACnC,sBAAsB;QACtB,OAAO,EAAE,EAAE;KACZ;IACD,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,qBAAqB;QAC5B,WAAW,EAAE,8BAA8B;QAC3C,sBAAsB;QACtB,OAAO,EAAE,EAAE;KACZ;IACD,OAAO,EAAE;QACP,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,6BAA6B;QAC1C,sBAAsB;QACtB,OAAO,EAAE,EAAE;KACZ;IACD,eAAe,EAAE;QACf,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE,0DAA0D;QACvE,sBAAsB;QACtB,OAAO,EAAE,EAAE;KACZ;IACD,GAAG,EAAE;QACH,IAAI,EAAE,KAAK;QACX,KAAK,EAAE,KAAK;QACZ,WAAW,EAAE,oDAAoD;QACjE,sBAAsB;QACtB,OAAO,EAAE,EAAE;KACZ;IACD,QAAQ,EAAE;QACR,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,gCAAgC;QAC7C,sBAAsB;QACtB,OAAO,EAAE,EAAE;KACZ;CACO,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CACtC,mBAAmB,CACoB,CAAC;AAE1C,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAa3D,MAAM,UAAU,gBAAgB,CAAC,IAAiB;IAChD,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,90 @@
1
+ import { z } from "zod";
2
+ export const usageEventSchema = z.object({
3
+ source: z.enum([
4
+ "ecosystemWallets",
5
+ "embeddedWallets",
6
+ "rpc",
7
+ "storage",
8
+ "bundler",
9
+ "paymaster",
10
+ "relayer",
11
+ "connectWallet",
12
+ "checkout",
13
+ "engine",
14
+ "pay",
15
+ "rpcV2",
16
+ ]),
17
+ action: z.string(),
18
+ /**
19
+ * The following fields are optional.
20
+ */
21
+ accountId: z.string().optional(),
22
+ isClientEvent: z.boolean().optional(),
23
+ apiKeyId: z.string().optional(),
24
+ creatorWalletAddress: z.string().optional(),
25
+ clientId: z.string().optional(),
26
+ walletAddress: z.string().optional(),
27
+ walletType: z.string().optional(),
28
+ chainId: z.number().int().positive().optional(),
29
+ provider: z.string().optional(),
30
+ mimeType: z.string().optional(),
31
+ fileSize: z.number().int().nonnegative().optional(),
32
+ fileCid: z.string().optional(),
33
+ evmMethod: z.string().optional(),
34
+ userOpHash: z.string().optional(),
35
+ gasLimit: z.number().nonnegative().optional(),
36
+ gasPricePerUnit: z.string().optional(),
37
+ transactionFeeUsd: z.number().optional(),
38
+ transactionHash: z.string().optional(),
39
+ sdkName: z.string().optional(),
40
+ sdkVersion: z.string().optional(),
41
+ sdkPlatform: z.string().optional(),
42
+ sdkOS: z.string().optional(),
43
+ productName: z.string().optional(),
44
+ transactionValue: z.string().optional(),
45
+ pathname: z.string().optional(),
46
+ contractAddress: z.string().optional(),
47
+ errorCode: z.string().optional(),
48
+ httpStatusCode: z.number().int().nonnegative().optional(),
49
+ functionName: z.string().optional(),
50
+ extension: z.string().optional(),
51
+ retryCount: z.number().int().nonnegative().optional(),
52
+ policyId: z.string().optional(),
53
+ msSinceQueue: z.number().nonnegative().optional(),
54
+ msSinceSend: z.number().nonnegative().optional(),
55
+ msTotalDuration: z.number().nonnegative().optional(),
56
+ swapId: z.string().optional(),
57
+ tokenAddress: z.string().optional(),
58
+ amountWei: z.string().optional(),
59
+ amountUSDCents: z.number().nonnegative().optional(),
60
+ httpMethod: z
61
+ .enum([
62
+ "GET",
63
+ "POST",
64
+ "PUT",
65
+ "DELETE",
66
+ "PATCH",
67
+ "HEAD",
68
+ "CONNECT",
69
+ "OPTIONS",
70
+ "TRACE",
71
+ ])
72
+ .optional(),
73
+ // Used to identify the ecosystem that the an ecosystem wallet belongs too
74
+ ecosystemId: z.string().optional(),
75
+ ecosystemPartnerId: z.string().optional(),
76
+ authenticationMethod: z.string().optional(),
77
+ chainName: z.string().optional(),
78
+ tokenSymbol: z.string().optional(),
79
+ dstChainId: z.number().optional(),
80
+ dstTokenAddress: z.string().optional(),
81
+ dstChainName: z.string().optional(),
82
+ dstTokenSymbol: z.string().optional(),
83
+ msLatency: z.number().optional(),
84
+ toAmountUSDCents: z.number().optional(),
85
+ secondaryProvider: z.string().optional(),
86
+ onRampId: z.string().optional(),
87
+ evmRequestParams: z.string().optional(),
88
+ providerIp: z.string().optional(),
89
+ });
90
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../../src/core/usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export async function usageLimit(authzResult, serviceConfig) {
2
+ if (!authzResult.authorized) {
3
+ return {
4
+ usageLimited: false,
5
+ };
6
+ }
7
+ const { apiKeyMeta, accountMeta } = authzResult;
8
+ const { limits, usage } = apiKeyMeta || accountMeta || {};
9
+ const { serviceScope } = serviceConfig;
10
+ if (!usage ||
11
+ !(serviceScope in usage) ||
12
+ !limits ||
13
+ !(serviceScope in limits)) {
14
+ // No usage limit is provided. Assume the request is not limited.
15
+ return {
16
+ usageLimited: false,
17
+ };
18
+ }
19
+ if (serviceScope === "storage" &&
20
+ (usage.storage?.sumFileSizeBytes ?? 0) > (limits.storage ?? 0)) {
21
+ return {
22
+ usageLimited: true,
23
+ status: 402,
24
+ errorMessage: `You've used all of your total usage credits for Storage Pinning. Please add your payment method at https://thirdweb.com/dashboard/settings/billing.`,
25
+ errorCode: "PAYMENT_METHOD_REQUIRED",
26
+ };
27
+ }
28
+ if (serviceScope === "embeddedWallets" &&
29
+ (usage.embeddedWallets?.countWalletAddresses ?? 0) >
30
+ (limits.embeddedWallets ?? 0)) {
31
+ return {
32
+ usageLimited: true,
33
+ status: 402,
34
+ errorMessage: `You've used all of your total usage credits for Embedded Wallets. Please add your payment method at https://thirdweb.com/dashboard/settings/billing.`,
35
+ errorCode: "PAYMENT_METHOD_REQUIRED",
36
+ };
37
+ }
38
+ return {
39
+ usageLimited: false,
40
+ };
41
+ }
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/usageLimit/index.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,WAAgC,EAChC,aAAgC;IAEhC,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC;QAC5B,OAAO;YACL,YAAY,EAAE,KAAK;SACpB,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;IAChD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,IAAI,WAAW,IAAI,EAAE,CAAC;IAC1D,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CAAC;IAEvC,IACE,CAAC,KAAK;QACN,CAAC,CAAC,YAAY,IAAI,KAAK,CAAC;QACxB,CAAC,MAAM;QACP,CAAC,CAAC,YAAY,IAAI,MAAM,CAAC,EACzB,CAAC;QACD,iEAAiE;QACjE,OAAO;YACL,YAAY,EAAE,KAAK;SACpB,CAAC;IACJ,CAAC;IAED,IACE,YAAY,KAAK,SAAS;QAC1B,CAAC,KAAK,CAAC,OAAO,EAAE,gBAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,EAC9D,CAAC;QACD,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,GAAG;YACX,YAAY,EAAE,qJAAqJ;YACnK,SAAS,EAAE,yBAAyB;SACrC,CAAC;IACJ,CAAC;IAED,IACE,YAAY,KAAK,iBAAiB;QAClC,CAAC,KAAK,CAAC,eAAe,EAAE,oBAAoB,IAAI,CAAC,CAAC;YAChD,CAAC,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC,EAC/B,CAAC;QACD,OAAO;YACL,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,GAAG;YACX,YAAY,EAAE,sJAAsJ;YACpK,SAAS,EAAE,yBAAyB;SACrC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,YAAY,EAAE,KAAK;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/usageLimit/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ // Exports the public service definitions.
2
+ export * from "./core/services.js";
3
+ export { authorizeBundleId, authorizeDomain, } from "./core/authorize/client.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,cAAc,oBAAoB,CAAC;AAEnC,OAAO,EACL,iBAAiB,EACjB,eAAe,GAChB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,50 @@
1
+ export const validApiKeyMeta = {
2
+ id: "1",
3
+ key: "your-api-key",
4
+ creatorWalletAddress: "creator-address",
5
+ secretHash: "secret-hash",
6
+ walletAddresses: [],
7
+ domains: ["example.com", "*.example.com"],
8
+ bundleIds: [],
9
+ redirectUrls: [],
10
+ accountId: "test-account-id",
11
+ accountStatus: "noCustomer",
12
+ accountPlan: "free",
13
+ services: [
14
+ {
15
+ name: "storage",
16
+ targetAddresses: ["target1", "target2"],
17
+ actions: ["action1", "action2"],
18
+ },
19
+ {
20
+ name: "service2",
21
+ targetAddresses: ["target3"],
22
+ actions: ["action3"],
23
+ },
24
+ {
25
+ name: "bundler",
26
+ targetAddresses: ["*"],
27
+ actions: ["action3"],
28
+ },
29
+ ],
30
+ limits: {
31
+ storage: 100,
32
+ },
33
+ rateLimits: {
34
+ rpc: 25,
35
+ },
36
+ };
37
+ export const validServiceConfig = {
38
+ apiUrl: "https://api.example.com",
39
+ serviceScope: "storage",
40
+ serviceApiKey: "service-api-key",
41
+ serviceAction: "action1",
42
+ enforceAuth: true,
43
+ };
44
+ export const validBundlerServiceConfig = {
45
+ apiUrl: "https://api.example.com",
46
+ serviceScope: "bundler",
47
+ serviceApiKey: "service-api-key",
48
+ enforceAuth: true,
49
+ };
50
+ //# sourceMappingURL=mocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mocks.js","sourceRoot":"","sources":["../../src/mocks.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAmB;IAC7C,EAAE,EAAE,GAAG;IACP,GAAG,EAAE,cAAc;IACnB,oBAAoB,EAAE,iBAAiB;IACvC,UAAU,EAAE,aAAa;IACzB,eAAe,EAAE,EAAE;IACnB,OAAO,EAAE,CAAC,aAAa,EAAE,eAAe,CAAC;IACzC,SAAS,EAAE,EAAE;IACb,YAAY,EAAE,EAAE;IAChB,SAAS,EAAE,iBAAiB;IAC5B,aAAa,EAAE,YAAY;IAC3B,WAAW,EAAE,MAAM;IACnB,QAAQ,EAAE;QACR;YACE,IAAI,EAAE,SAAS;YACf,eAAe,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;YACvC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;SAChC;QACD;YACE,IAAI,EAAE,UAAU;YAChB,eAAe,EAAE,CAAC,SAAS,CAAC;YAC5B,OAAO,EAAE,CAAC,SAAS,CAAC;SACrB;QACD;YACE,IAAI,EAAE,SAAS;YACf,eAAe,EAAE,CAAC,GAAG,CAAC;YACtB,OAAO,EAAE,CAAC,SAAS,CAAC;SACrB;KACF;IACD,MAAM,EAAE;QACN,OAAO,EAAE,GAAG;KACb;IACD,UAAU,EAAE;QACV,GAAG,EAAE,EAAE;KACR;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,MAAM,EAAE,yBAAyB;IACjC,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,iBAAiB;IAChC,aAAa,EAAE,SAAS;IACxB,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,yBAAyB,GAAsB;IAC1D,MAAM,EAAE,yBAAyB;IACjC,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,iBAAiB;IAChC,WAAW,EAAE,IAAI;CAClB,CAAC"}
@@ -0,0 +1,165 @@
1
+ import { createHash } from "node:crypto";
2
+ import { authorize } from "../core/authorize/index.js";
3
+ export * from "../core/usage.js";
4
+ export * from "../core/rateLimit/index.js";
5
+ export * from "../core/services.js";
6
+ export * from "../core/usageLimit/index.js";
7
+ /**
8
+ *
9
+ * @param {AuthInput['req']} authInput.req - The incoming request from which information will be pulled from. These information includes (checks are in order and terminates on first match):
10
+ * - clientId: Checks header `x-client-id`, search param `clientId`
11
+ * - bundleId: Checks header `x-bundle-id`, search param `bundleId`
12
+ * - secretKey: Checks header `x-secret-key`
13
+ * - origin (the requesting domain): Checks header `origin`, `referer`
14
+ * @param {AuthInput['clientId']} authInput.clientId - Overrides any clientId found on the `req` object
15
+ * @param {AuthInput['targetAddress']} authInput.targetAddress - Only used in smart wallets to determine if the request is authorized to interact with the target address.
16
+ * @param {NodeServiceConfig['enforceAuth']} serviceConfig - Always `true` unless you need to turn auth off. Tells the service whether or not to enforce auth.
17
+ * @param {NodeServiceConfig['apiUrl']} serviceConfig.apiUrl - The url of the api server to fetch information for verification. `https://api.thirdweb.com` for production and `https://api.staging.thirdweb.com` for staging
18
+ * @param {NodeServiceConfig['serviceApiKey']} serviceConfig.serviceApiKey - secret key to be used authenticate the caller of the api-server. Check the api-server's env variable for the keys.
19
+ * @param {NodeServiceConfig['serviceScope']} serviceConfig.serviceScope - The service that we are requesting authorization for. E.g. `relayer`, `rpc`, 'bundler', 'storage' etc.
20
+ * @param {NodeServiceConfig['serviceAction']} serviceConfig.serviceAction - Needed when the `serviceScope` is `storage`. Can be either `read` or `write`.
21
+ * @param {NodeServiceConfig['useWalletAuth']} serviceConfig.useWalletAuth - If true it pings the `wallet/me` or else, `account/me`. You most likely can leave this as false.
22
+ * @returns {AuthorizationResult} authorizationResult - contains if the request is authorized, and information about the account if it is authorized. Otherwise, it contains the error message and status code.
23
+ */
24
+ export async function authorizeNode(authInput, serviceConfig) {
25
+ let authData;
26
+ try {
27
+ authData = extractAuthorizationData(authInput);
28
+ }
29
+ catch (e) {
30
+ if (e instanceof Error && e.message === "KEY_CONFLICT") {
31
+ return {
32
+ authorized: false,
33
+ status: 400,
34
+ errorMessage: "Please pass either a client id or a secret key.",
35
+ errorCode: "KEY_CONFLICT",
36
+ };
37
+ }
38
+ return {
39
+ authorized: false,
40
+ status: 500,
41
+ errorMessage: "Internal Server Error",
42
+ errorCode: "INTERNAL_SERVER_ERROR",
43
+ };
44
+ }
45
+ return await authorize(authData, serviceConfig);
46
+ }
47
+ function getHeader(headers, headerName) {
48
+ const header = headers[headerName];
49
+ if (Array.isArray(header)) {
50
+ return header?.[0] ?? null;
51
+ }
52
+ return header ?? null;
53
+ }
54
+ export function extractAuthorizationData(authInput) {
55
+ let requestUrl;
56
+ try {
57
+ requestUrl = new URL(authInput.req.url || "", `http://${authInput.req.headers.host}`);
58
+ }
59
+ catch (error) {
60
+ console.log("** Node URL Error **", error);
61
+ throw error;
62
+ }
63
+ const headers = authInput.req.headers;
64
+ const secretKey = getHeader(headers, "x-secret-key");
65
+ // prefer clientId that is explicitly passed in
66
+ let clientId = authInput.clientId ?? null;
67
+ if (!clientId) {
68
+ // next preference is clientId from header
69
+ clientId = getHeader(headers, "x-client-id");
70
+ }
71
+ // next preference is search param
72
+ if (!clientId) {
73
+ clientId = requestUrl.searchParams.get("clientId");
74
+ }
75
+ // bundle id from header is first preference
76
+ let bundleId = getHeader(headers, "x-bundle-id");
77
+ // next preference is search param
78
+ if (!bundleId) {
79
+ bundleId = requestUrl.searchParams.get("bundleId");
80
+ }
81
+ let origin = getHeader(headers, "origin");
82
+ // if origin header is not available we'll fall back to referrer;
83
+ if (!origin) {
84
+ origin = getHeader(headers, "referer");
85
+ }
86
+ // if we have an origin at this point, normalize it
87
+ if (origin) {
88
+ try {
89
+ origin = new URL(origin).host;
90
+ }
91
+ catch (e) {
92
+ console.warn("failed to parse origin", origin, e);
93
+ }
94
+ }
95
+ // handle if we a secret key is passed in the headers
96
+ let secretKeyHash = null;
97
+ if (secretKey) {
98
+ // hash the secret key
99
+ secretKeyHash = hashSecretKey(secretKey);
100
+ // derive the client id from the secret key hash
101
+ const derivedClientId = deriveClientIdFromSecretKeyHash(secretKeyHash);
102
+ // if we already have a client id passed in we need to make sure they match
103
+ if (clientId && clientId !== derivedClientId) {
104
+ throw new Error("KEY_CONFLICT");
105
+ }
106
+ // otherwise set the client id to the derived client id (client id based off of secret key)
107
+ clientId = derivedClientId;
108
+ }
109
+ let jwt = null;
110
+ let useWalletAuth = null;
111
+ // check for authorization header on the request
112
+ const authorizationHeader = getHeader(headers, "authorization");
113
+ if (authorizationHeader) {
114
+ const [type, token] = authorizationHeader.split(" ");
115
+ if (type?.toLowerCase() === "bearer" && !!token) {
116
+ jwt = token;
117
+ const walletAuthHeader = getHeader(headers, "x-authorize-wallet");
118
+ // IK a stringified boolean is not ideal, but it's required to pass it in the headers.
119
+ if (walletAuthHeader?.toLowerCase() === "true") {
120
+ useWalletAuth = walletAuthHeader;
121
+ }
122
+ }
123
+ }
124
+ return {
125
+ jwt,
126
+ hashedJWT: jwt ? hashSecretKey(jwt) : null,
127
+ secretKeyHash,
128
+ secretKey,
129
+ clientId,
130
+ origin,
131
+ bundleId,
132
+ targetAddress: authInput.targetAddress,
133
+ useWalletAuth,
134
+ };
135
+ }
136
+ export function hashSecretKey(secretKey) {
137
+ return createHash("sha256").update(secretKey).digest("hex");
138
+ }
139
+ export function deriveClientIdFromSecretKeyHash(secretKeyHash) {
140
+ return secretKeyHash.slice(0, 32);
141
+ }
142
+ export function logHttpRequest({ clientId, req, res, isAuthed, statusMessage, latencyMs, }) {
143
+ try {
144
+ const authorizationData = extractAuthorizationData({ req, clientId });
145
+ const headers = req.headers;
146
+ console.log(JSON.stringify({
147
+ method: req.method,
148
+ pathname: req.url,
149
+ hasSecretKey: !!authorizationData.secretKey,
150
+ hasClientId: !!authorizationData.clientId,
151
+ hasJwt: !!authorizationData.jwt,
152
+ clientId: authorizationData.clientId,
153
+ isAuthed,
154
+ status: res.statusCode,
155
+ statusMessage,
156
+ sdkName: headers["x-sdk-name"] ?? undefined,
157
+ sdkVersion: headers["x-sdk-version"] ?? undefined,
158
+ platform: headers["x-sdk-platform"] ?? undefined,
159
+ os: headers["x-sdk-os"] ?? undefined,
160
+ latencyMs,
161
+ }));
162
+ }
163
+ catch { }
164
+ }
165
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAOzC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAIvD,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAO5C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAoB,EACpB,aAAgC;IAEhC,IAAI,QAA4B,CAAC;IACjC,IAAI,CAAC;QACH,QAAQ,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,OAAO,KAAK,cAAc,EAAE,CAAC;YACvD,OAAO;gBACL,UAAU,EAAE,KAAK;gBACjB,MAAM,EAAE,GAAG;gBACX,YAAY,EAAE,iDAAiD;gBAC/D,SAAS,EAAE,cAAc;aAC1B,CAAC;QACJ,CAAC;QACD,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,GAAG;YACX,YAAY,EAAE,uBAAuB;YACrC,SAAS,EAAE,uBAAuB;SACnC,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,SAAS,CAChB,OAA4B,EAC5B,UAAkB;IAElB,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC7B,CAAC;IACD,OAAO,MAAM,IAAI,IAAI,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,SAAoB;IAEpB,IAAI,UAAe,CAAC;IAEpB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,GAAG,CAClB,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EACvB,UAAU,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CACvC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;IACtC,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACrD,+CAA+C;IAC/C,IAAI,QAAQ,GAAG,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;IAE1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,0CAA0C;QAC1C,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED,kCAAkC;IAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;IACD,4CAA4C;IAC5C,IAAI,QAAQ,GAAG,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAEjD,kCAAkC;IAClC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC1C,iEAAiE;IACjE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;IACD,mDAAmD;IACnD,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;QAChC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,IAAI,SAAS,EAAE,CAAC;QACd,sBAAsB;QACtB,aAAa,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QACzC,gDAAgD;QAChD,MAAM,eAAe,GAAG,+BAA+B,CAAC,aAAa,CAAC,CAAC;QACvE,2EAA2E;QAC3E,IAAI,QAAQ,IAAI,QAAQ,KAAK,eAAe,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;QAClC,CAAC;QACD,2FAA2F;QAC3F,QAAQ,GAAG,eAAe,CAAC;IAC7B,CAAC;IAED,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,IAAI,aAAa,GAAkB,IAAI,CAAC;IACxC,gDAAgD;IAChD,MAAM,mBAAmB,GAAG,SAAS,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAChE,IAAI,mBAAmB,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,IAAI,EAAE,WAAW,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YAChD,GAAG,GAAG,KAAK,CAAC;YACZ,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAC;YAClE,sFAAsF;YACtF,IAAI,gBAAgB,EAAE,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;gBAC/C,aAAa,GAAG,gBAAgB,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,GAAG;QACH,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;QAC1C,aAAa;QACb,SAAS;QACT,QAAQ;QACR,MAAM;QACN,QAAQ;QACR,aAAa,EAAE,SAAS,CAAC,aAAa;QACtC,aAAa;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,aAAqB;IACnE,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAC7B,QAAQ,EACR,GAAG,EACH,GAAG,EACH,QAAQ,EACR,aAAa,EACb,SAAS,GAQV;IACC,IAAI,CAAC;QACH,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;QAE5B,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CAAC;YACb,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,GAAG;YACjB,YAAY,EAAE,CAAC,CAAC,iBAAiB,CAAC,SAAS;YAC3C,WAAW,EAAE,CAAC,CAAC,iBAAiB,CAAC,QAAQ;YACzC,MAAM,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG;YAC/B,QAAQ,EAAE,iBAAiB,CAAC,QAAQ;YACpC,QAAQ;YACR,MAAM,EAAE,GAAG,CAAC,UAAU;YACtB,aAAa;YACb,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI,SAAS;YAC3C,UAAU,EAAE,OAAO,CAAC,eAAe,CAAC,IAAI,SAAS;YACjD,QAAQ,EAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,SAAS;YAChD,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,SAAS;YACpC,SAAS;SACV,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
@@ -0,0 +1 @@
1
+ {"type": "module","sideEffects":false}
@@ -1,13 +1,13 @@
1
1
  import type { ExecutionContext, KVNamespace, Response } from "@cloudflare/workers-types";
2
- import type { CoreServiceConfig } from "../core/api";
3
2
  import type { Request } from "@cloudflare/workers-types";
4
- import type { AuthorizationInput } from "../core/authorize";
5
- import type { AuthorizationResult } from "../core/authorize/types";
6
- import type { CoreAuthInput } from "../core/types";
7
- export * from "./usage";
8
- export * from "../core/services";
9
- export * from "../core/rateLimit";
10
- export * from "../core/usageLimit";
3
+ import type { CoreServiceConfig } from "../core/api.js";
4
+ import type { AuthorizationInput } from "../core/authorize/index.js";
5
+ import type { AuthorizationResult } from "../core/authorize/types.js";
6
+ import type { CoreAuthInput } from "../core/types.js";
7
+ export * from "./usage.js";
8
+ export * from "../core/services.js";
9
+ export * from "../core/rateLimit/index.js";
10
+ export * from "../core/usageLimit/index.js";
11
11
  export type WorkerServiceConfig = CoreServiceConfig & {
12
12
  kvStore: KVNamespace;
13
13
  ctx: ExecutionContext;