[service-utils] Add a usage tracking helper fn to publish events (#1424)

This commit is contained in:
Phillip Ho
2023-08-02 19:05:03 +00:00
committed by GitHub
parent 2283d21027
commit d01e6396d1
6 changed files with 661 additions and 2588 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@thirdweb-dev/service-utils": minor
---
Add helper to publish usage events from backend services
+7 -1
View File
@@ -1 +1,7 @@
### todo
# Service Utils
This repository contains utilities that handle common requirements for thirdweb services.
- `/cf-worker`: for use only in Cloudflare Worker services
- `/node`: for use in self-hosted services
- `/core`: for use in any service
+5
View File
@@ -41,6 +41,7 @@
"devDependencies": {
"@cloudflare/workers-types": "^4.20230724.0",
"@preconstruct/cli": "2.7.0",
"@smithy/types": "^2.0.2",
"@thirdweb-dev/tsconfig": "workspace:*",
"@types/jest": "^29.5.3",
"@types/node": "^18.17.1",
@@ -61,5 +62,9 @@
"build": "tsc && preconstruct build",
"push": "yalc push",
"test": "jest"
},
"dependencies": {
"@aws-sdk/client-sqs": "^3.379.1",
"zod": "^3.20.2"
}
}
+82
View File
@@ -0,0 +1,82 @@
import { z } from "zod";
import {
SendMessageBatchCommand,
SendMessageBatchRequestEntry,
SQSClient,
} from "@aws-sdk/client-sqs";
import { AwsCredentialIdentity } from "@smithy/types";
import { randomUUID } from "crypto";
let sqs: SQSClient | undefined;
function getSqs({
region,
credentials,
}: {
region: string;
credentials?: AwsCredentialIdentity;
}): SQSClient {
if (!sqs) {
sqs = new SQSClient({ region, credentials });
}
return sqs;
}
/**
* Types
*/
const usageEventSchema = z.object({
source: z.enum([
"wallet",
"rpc",
"storage",
"bundler",
"paymaster",
"relayer",
]),
action: z.string(),
accountId: z.string(),
// Optional
apiKeyId: z.string().optional(),
creatorWalletAddress: z.string().optional(),
clientId: z.string().optional(),
walletAddress: z.string().optional(),
chainId: z.number().int().positive().optional(),
provider: z.string().optional(),
mimeType: z.string().optional(),
fileSize: z.number().int().nonnegative().optional(),
fileCid: z.string().optional(),
transactionHash: z.string().optional(),
gasLimit: z.number().nonnegative().optional(),
gasPricePerUnit: z.number().nonnegative().optional(),
});
export type UsageEvent = z.infer<typeof usageEventSchema>;
/**
* Publish usage events. Provide the relevant fields for your application.
*
* @param usageEvents
* @param config
*/
export async function publishUsageEvents(
usageEvents: UsageEvent[],
config: {
queueUrl: string;
region?: string;
credentials?: AwsCredentialIdentity;
},
): Promise<void> {
const { queueUrl, region = "us-west-2", credentials } = config;
const entries = usageEvents.map((event) => ({
Id: randomUUID(),
MessageBody: JSON.stringify(usageEventSchema.parse(event)),
})) as unknown as SendMessageBatchRequestEntry[];
const input = new SendMessageBatchCommand({
QueueUrl: queueUrl,
Entries: entries,
});
await getSqs({ region, credentials }).send(input);
}
+4 -1
View File
@@ -1,2 +1,5 @@
// only exports the public service definitions
// Exports the public service definitions.
export * from "./core/services";
// Exports usage helpers.
export * from "./core/usage";
+558 -2586
View File
File diff suppressed because it is too large Load Diff