opticedge-cloud-utils 1.0.32 → 1.0.34

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.
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './db/mongo2';
4
4
  export * from './db/mongo3';
5
5
  export * from './types/card';
6
6
  export * from './types/notify';
7
+ export * from './types/payment';
7
8
  export * from './types/pokemontcg';
8
9
  export * from './types/pricecharting';
9
10
  export * from './types/user';
@@ -11,4 +12,5 @@ export * from './utils/env';
11
12
  export * from './utils/regex';
12
13
  export * from './utils/secrets';
13
14
  export * from './utils/task';
14
- export * from './utils/thirdweb';
15
+ export * from './utils/tw-utils';
16
+ export * from './utils/tw-wallet';
package/dist/index.js CHANGED
@@ -20,6 +20,7 @@ __exportStar(require("./db/mongo2"), exports);
20
20
  __exportStar(require("./db/mongo3"), exports);
21
21
  __exportStar(require("./types/card"), exports);
22
22
  __exportStar(require("./types/notify"), exports);
23
+ __exportStar(require("./types/payment"), exports);
23
24
  __exportStar(require("./types/pokemontcg"), exports);
24
25
  __exportStar(require("./types/pricecharting"), exports);
25
26
  __exportStar(require("./types/user"), exports);
@@ -27,4 +28,5 @@ __exportStar(require("./utils/env"), exports);
27
28
  __exportStar(require("./utils/regex"), exports);
28
29
  __exportStar(require("./utils/secrets"), exports);
29
30
  __exportStar(require("./utils/task"), exports);
30
- __exportStar(require("./utils/thirdweb"), exports);
31
+ __exportStar(require("./utils/tw-utils"), exports);
32
+ __exportStar(require("./utils/tw-wallet"), exports);
@@ -0,0 +1 @@
1
+ export type PaymentEnvironment = 'SANDBOX' | 'PRODUCTION';
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export declare function isValidWebhookSignature(secret: string, body: string, signature: string): boolean;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isValidWebhookSignature = isValidWebhookSignature;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ function isValidWebhookSignature(secret, body, signature) {
9
+ const computedSignature = crypto_1.default.createHmac('sha256', secret).update(body).digest('hex');
10
+ return computedSignature === signature;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const tw_utils_1 = require("./tw-utils");
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ describe('isValidWebhookSignature', () => {
9
+ const secret = 'test_secret';
10
+ const body = '{"message":"hello"}';
11
+ it('returns true for a valid signature', () => {
12
+ const validSignature = crypto_1.default.createHmac('sha256', secret).update(body).digest('hex');
13
+ expect((0, tw_utils_1.isValidWebhookSignature)(secret, body, validSignature)).toBe(true);
14
+ });
15
+ it('returns false for an invalid signature', () => {
16
+ const invalidSignature = 'invalidsignature123';
17
+ expect((0, tw_utils_1.isValidWebhookSignature)(secret, body, invalidSignature)).toBe(false);
18
+ });
19
+ it('returns false if body or secret is tampered', () => {
20
+ const originalSignature = crypto_1.default.createHmac('sha256', secret).update(body).digest('hex');
21
+ // wrong body
22
+ expect((0, tw_utils_1.isValidWebhookSignature)(secret, '{"message":"tampered"}', originalSignature)).toBe(false);
23
+ // wrong secret
24
+ expect((0, tw_utils_1.isValidWebhookSignature)('wrong_secret', body, originalSignature)).toBe(false);
25
+ });
26
+ });
@@ -0,0 +1 @@
1
+ export declare function pregenerateInAppWallet(projectId: string, twClientId: string, twSecretKeyName: string, email: string): Promise<string | null>;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.pregenerateInAppWallet = pregenerateInAppWallet;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const secrets_1 = require("./secrets");
9
+ async function pregenerateInAppWallet(projectId, twClientId, twSecretKeyName, email) {
10
+ const TW_SECRET_KEY = await (0, secrets_1.getSecret)(projectId, twSecretKeyName);
11
+ try {
12
+ const response = await axios_1.default.post('https://in-app-wallet.thirdweb.com/api/v1/pregenerate', { strategy: 'email', email }, {
13
+ headers: {
14
+ 'x-secret-key': TW_SECRET_KEY,
15
+ 'x-client-id': twClientId,
16
+ 'Content-Type': 'application/json'
17
+ },
18
+ timeout: 5000
19
+ });
20
+ const wallet = response.data.wallet;
21
+ if (!wallet || !wallet.address) {
22
+ console.error('Invalid wallet response:', response.data);
23
+ return null;
24
+ }
25
+ console.log('Wallet pregeneration response:', wallet.address);
26
+ return wallet.address;
27
+ }
28
+ catch (error) {
29
+ console.error('Error pregenerating wallet:', error);
30
+ return null;
31
+ }
32
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const axios_1 = __importDefault(require("axios"));
40
+ const tw_wallet_1 = require("./tw-wallet");
41
+ const secrets = __importStar(require("./secrets"));
42
+ jest.mock('axios');
43
+ jest.mock('opticedge-cloud-utils');
44
+ jest.mock('./secrets');
45
+ const mockedAxios = axios_1.default;
46
+ const mockedGetSecret = secrets.getSecret;
47
+ describe('pregenerateInAppWallet', () => {
48
+ const mockProjectId = 'test-project';
49
+ const mockClientId = 'test-client-id';
50
+ const mockSecretKeyName = 'test-key';
51
+ const mockEmail = 'user@example.com';
52
+ const mockWalletAddress = '0xabc123';
53
+ const mockSecretValue = 'mock-secret-key';
54
+ beforeEach(() => {
55
+ jest.clearAllMocks();
56
+ });
57
+ it('returns wallet address on success', async () => {
58
+ mockedGetSecret.mockResolvedValue(mockSecretValue);
59
+ mockedAxios.post.mockResolvedValue({
60
+ data: {
61
+ wallet: {
62
+ address: mockWalletAddress
63
+ }
64
+ }
65
+ });
66
+ const result = await (0, tw_wallet_1.pregenerateInAppWallet)(mockProjectId, mockClientId, mockSecretKeyName, mockEmail);
67
+ expect(mockedGetSecret).toHaveBeenCalledWith(mockProjectId, mockSecretKeyName);
68
+ expect(mockedAxios.post).toHaveBeenCalledWith('https://in-app-wallet.thirdweb.com/api/v1/pregenerate', { strategy: 'email', email: mockEmail }, {
69
+ headers: {
70
+ 'x-secret-key': mockSecretValue,
71
+ 'x-client-id': mockClientId,
72
+ 'Content-Type': 'application/json'
73
+ },
74
+ timeout: 5000
75
+ });
76
+ expect(result).toBe(mockWalletAddress);
77
+ });
78
+ it('returns null if wallet.address is missing', async () => {
79
+ mockedGetSecret.mockResolvedValue(mockSecretValue);
80
+ mockedAxios.post.mockResolvedValue({
81
+ data: {
82
+ wallet: {} // Missing address
83
+ }
84
+ });
85
+ const result = await (0, tw_wallet_1.pregenerateInAppWallet)(mockProjectId, mockClientId, mockSecretKeyName, mockEmail);
86
+ expect(result).toBeNull();
87
+ });
88
+ it('returns null on axios error', async () => {
89
+ mockedGetSecret.mockResolvedValue(mockSecretValue);
90
+ mockedAxios.post.mockRejectedValue(new Error('Network error'));
91
+ const result = await (0, tw_wallet_1.pregenerateInAppWallet)(mockProjectId, mockClientId, mockSecretKeyName, mockEmail);
92
+ expect(result).toBeNull();
93
+ });
94
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opticedge-cloud-utils",
3
- "version": "1.0.32",
3
+ "version": "1.0.34",
4
4
  "description": "Common utilities for cloud functions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -17,6 +17,7 @@
17
17
  "dependencies": {
18
18
  "@google-cloud/secret-manager": "^6.0.1",
19
19
  "@google-cloud/tasks": "^6.1.0",
20
+ "axios": "^1.10.0",
20
21
  "google-auth-library": "^9.15.1",
21
22
  "mongodb": "^6.16.0"
22
23
  },
package/src/index.ts CHANGED
@@ -4,6 +4,7 @@ export * from './db/mongo2'
4
4
  export * from './db/mongo3'
5
5
  export * from './types/card'
6
6
  export * from './types/notify'
7
+ export * from './types/payment'
7
8
  export * from './types/pokemontcg'
8
9
  export * from './types/pricecharting'
9
10
  export * from './types/user'
@@ -11,4 +12,5 @@ export * from './utils/env'
11
12
  export * from './utils/regex'
12
13
  export * from './utils/secrets'
13
14
  export * from './utils/task'
14
- export * from './utils/thirdweb'
15
+ export * from './utils/tw-utils'
16
+ export * from './utils/tw-wallet'
@@ -0,0 +1 @@
1
+ export type PaymentEnvironment = 'SANDBOX' | 'PRODUCTION'
package/src/types/user.ts CHANGED
@@ -2,5 +2,5 @@ export enum UserCollectorType {
2
2
  'Non-member' = -1,
3
3
  Elite,
4
4
  Rookie,
5
- Free,
6
- }
5
+ Free
6
+ }
@@ -1,4 +1,4 @@
1
- import { isValidWebhookSignature } from './thirdweb'
1
+ import { isValidWebhookSignature } from './tw-utils'
2
2
  import crypto from 'crypto'
3
3
 
4
4
  describe('isValidWebhookSignature', () => {
@@ -0,0 +1,89 @@
1
+ import axios from 'axios'
2
+ import { pregenerateInAppWallet } from './tw-wallet'
3
+ import * as secrets from './secrets'
4
+
5
+ jest.mock('axios')
6
+ jest.mock('opticedge-cloud-utils')
7
+ jest.mock('./secrets')
8
+
9
+ const mockedAxios = axios as jest.Mocked<typeof axios>
10
+ const mockedGetSecret = secrets.getSecret as jest.Mock
11
+
12
+ describe('pregenerateInAppWallet', () => {
13
+ const mockProjectId = 'test-project'
14
+ const mockClientId = 'test-client-id'
15
+ const mockSecretKeyName = 'test-key'
16
+ const mockEmail = 'user@example.com'
17
+ const mockWalletAddress = '0xabc123'
18
+ const mockSecretValue = 'mock-secret-key'
19
+
20
+ beforeEach(() => {
21
+ jest.clearAllMocks()
22
+ })
23
+
24
+ it('returns wallet address on success', async () => {
25
+ mockedGetSecret.mockResolvedValue(mockSecretValue)
26
+ mockedAxios.post.mockResolvedValue({
27
+ data: {
28
+ wallet: {
29
+ address: mockWalletAddress
30
+ }
31
+ }
32
+ })
33
+
34
+ const result = await pregenerateInAppWallet(
35
+ mockProjectId,
36
+ mockClientId,
37
+ mockSecretKeyName,
38
+ mockEmail
39
+ )
40
+
41
+ expect(mockedGetSecret).toHaveBeenCalledWith(mockProjectId, mockSecretKeyName)
42
+ expect(mockedAxios.post).toHaveBeenCalledWith(
43
+ 'https://in-app-wallet.thirdweb.com/api/v1/pregenerate',
44
+ { strategy: 'email', email: mockEmail },
45
+ {
46
+ headers: {
47
+ 'x-secret-key': mockSecretValue,
48
+ 'x-client-id': mockClientId,
49
+ 'Content-Type': 'application/json'
50
+ },
51
+ timeout: 5000
52
+ }
53
+ )
54
+
55
+ expect(result).toBe(mockWalletAddress)
56
+ })
57
+
58
+ it('returns null if wallet.address is missing', async () => {
59
+ mockedGetSecret.mockResolvedValue(mockSecretValue)
60
+ mockedAxios.post.mockResolvedValue({
61
+ data: {
62
+ wallet: {} // Missing address
63
+ }
64
+ })
65
+
66
+ const result = await pregenerateInAppWallet(
67
+ mockProjectId,
68
+ mockClientId,
69
+ mockSecretKeyName,
70
+ mockEmail
71
+ )
72
+
73
+ expect(result).toBeNull()
74
+ })
75
+
76
+ it('returns null on axios error', async () => {
77
+ mockedGetSecret.mockResolvedValue(mockSecretValue)
78
+ mockedAxios.post.mockRejectedValue(new Error('Network error'))
79
+
80
+ const result = await pregenerateInAppWallet(
81
+ mockProjectId,
82
+ mockClientId,
83
+ mockSecretKeyName,
84
+ mockEmail
85
+ )
86
+
87
+ expect(result).toBeNull()
88
+ })
89
+ })
@@ -0,0 +1,38 @@
1
+ import axios from 'axios'
2
+ import { getSecret } from './secrets'
3
+
4
+ export async function pregenerateInAppWallet(
5
+ projectId: string,
6
+ twClientId: string,
7
+ twSecretKeyName: string,
8
+ email: string
9
+ ): Promise<string | null> {
10
+ const TW_SECRET_KEY = await getSecret(projectId, twSecretKeyName)
11
+
12
+ try {
13
+ const response = await axios.post(
14
+ 'https://in-app-wallet.thirdweb.com/api/v1/pregenerate',
15
+ { strategy: 'email', email },
16
+ {
17
+ headers: {
18
+ 'x-secret-key': TW_SECRET_KEY,
19
+ 'x-client-id': twClientId,
20
+ 'Content-Type': 'application/json'
21
+ },
22
+ timeout: 5000
23
+ }
24
+ )
25
+
26
+ const wallet = response.data.wallet
27
+ if (!wallet || !wallet.address) {
28
+ console.error('Invalid wallet response:', response.data)
29
+ return null
30
+ }
31
+
32
+ console.log('Wallet pregeneration response:', wallet.address)
33
+ return wallet.address
34
+ } catch (error) {
35
+ console.error('Error pregenerating wallet:', error)
36
+ return null
37
+ }
38
+ }
File without changes