Skip to content

Commit 02c256b

Browse files
committed
Merge remote-tracking branch 'origin/main' into pb/solana-vault-ts-sdk
2 parents b22e3ff + edf3aad commit 02c256b

File tree

223 files changed

+13623
-6511
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

223 files changed

+13623
-6511
lines changed

.changeset/cyan-windows-reply.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.changeset/social-showers-see.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

.github/workflows/auto-assign.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Auto Author Assign
22

33
on:
44
pull_request:
5-
types: [opened, reopened, ready_for_review, draft]
5+
types: [opened, reopened, ready_for_review]
66

77
permissions:
88
pull-requests: write

apps/dashboard/framer-rewrites.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = [
1010
"/wallets",
1111
"/account-abstraction",
1212
"/payments",
13+
"/payments/x402",
1314
"/auth",
1415
"/in-app-wallets",
1516
"/transactions",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"use server";
2+
3+
import { createVaultClient, listEoas } from "@thirdweb-dev/vault-sdk";
4+
import { NEXT_PUBLIC_THIRDWEB_VAULT_URL } from "@/constants/public-envs";
5+
import type { ProjectWalletSummary } from "@/lib/server/project-wallet";
6+
7+
interface VaultWalletListItem {
8+
id: string;
9+
address: string;
10+
metadata?: {
11+
label?: string;
12+
projectId?: string;
13+
teamId?: string;
14+
type?: string;
15+
} | null;
16+
}
17+
18+
export async function listProjectServerWallets(params: {
19+
managementAccessToken: string;
20+
projectId: string;
21+
pageSize?: number;
22+
}): Promise<ProjectWalletSummary[]> {
23+
const { managementAccessToken, projectId, pageSize = 100 } = params;
24+
25+
if (!managementAccessToken || !NEXT_PUBLIC_THIRDWEB_VAULT_URL) {
26+
return [];
27+
}
28+
29+
try {
30+
const vaultClient = await createVaultClient({
31+
baseUrl: NEXT_PUBLIC_THIRDWEB_VAULT_URL,
32+
});
33+
34+
const response = await listEoas({
35+
client: vaultClient,
36+
request: {
37+
auth: {
38+
accessToken: managementAccessToken,
39+
},
40+
options: {
41+
page: 0,
42+
// @ts-expect-error - Vault SDK expects snake_case pagination fields
43+
page_size: pageSize,
44+
},
45+
},
46+
});
47+
48+
if (!response.success || !response.data?.items) {
49+
return [];
50+
}
51+
52+
const items = response.data.items as VaultWalletListItem[];
53+
54+
return items
55+
.filter((item) => {
56+
return (
57+
item.metadata?.projectId === projectId &&
58+
(!item.metadata?.type || item.metadata.type === "server-wallet")
59+
);
60+
})
61+
.map<ProjectWalletSummary>((item) => ({
62+
id: item.id,
63+
address: item.address,
64+
label: item.metadata?.label ?? undefined,
65+
}));
66+
} catch (error) {
67+
console.error("Failed to list project server wallets", error);
68+
return [];
69+
}
70+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"use server";
2+
3+
import { configure, sendTokens } from "@thirdweb-dev/api";
4+
import { THIRDWEB_API_HOST } from "@/constants/urls";
5+
6+
configure({
7+
override: {
8+
baseUrl: THIRDWEB_API_HOST,
9+
},
10+
});
11+
12+
export async function sendProjectWalletTokens(options: {
13+
walletAddress: string;
14+
recipientAddress: string;
15+
chainId: number;
16+
quantityWei: string;
17+
publishableKey: string;
18+
teamId: string;
19+
tokenAddress?: string;
20+
secretKey: string;
21+
vaultAccessToken?: string;
22+
}) {
23+
const {
24+
walletAddress,
25+
recipientAddress,
26+
chainId,
27+
quantityWei,
28+
publishableKey,
29+
teamId,
30+
tokenAddress,
31+
secretKey,
32+
vaultAccessToken,
33+
} = options;
34+
35+
if (!secretKey) {
36+
return {
37+
error: "A project secret key is required to send funds.",
38+
ok: false,
39+
} as const;
40+
}
41+
42+
const response = await sendTokens({
43+
body: {
44+
chainId,
45+
from: walletAddress,
46+
recipients: [
47+
{
48+
address: recipientAddress,
49+
quantity: quantityWei,
50+
},
51+
],
52+
...(tokenAddress ? { tokenAddress } : {}),
53+
},
54+
headers: {
55+
"Content-Type": "application/json",
56+
"x-client-id": publishableKey,
57+
"x-secret-key": secretKey,
58+
"x-team-id": teamId,
59+
...(vaultAccessToken ? { "x-vault-access-token": vaultAccessToken } : {}),
60+
},
61+
});
62+
63+
if (response.error || !response.data) {
64+
return {
65+
error: response.error || "Failed to submit transfer request.",
66+
ok: false,
67+
} as const;
68+
}
69+
70+
return {
71+
ok: true,
72+
transactionIds: response.data.result?.transactionIds ?? [],
73+
} as const;
74+
}

apps/dashboard/src/@/actions/stripe-actions.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import "server-only";
22

3-
import { headers } from "next/headers";
3+
import { cookies, headers } from "next/headers";
44
import Stripe from "stripe";
55
import type { Team } from "@/api/team/get-team";
66
import {
@@ -88,6 +88,9 @@ export async function fetchClientSecret(team: Team) {
8888
throw new Error("No customer ID found");
8989
}
9090

91+
// try to get the gclid cookie
92+
const gclid = (await cookies()).get("gclid")?.value;
93+
9194
// Create Checkout Sessions from body params.
9295
const session = await stripe.checkout.sessions.create({
9396
ui_mode: "embedded",
@@ -117,6 +120,8 @@ export async function fetchClientSecret(team: Team) {
117120
missing_payment_method: "cancel",
118121
},
119122
},
123+
// if gclid exists, set it as a metadata field so we can attribute the conversion later
124+
metadata: gclid ? { gclid } : undefined,
120125
},
121126
});
122127

apps/dashboard/src/@/analytics/report.ts

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export function reportContractDeployed(properties: {
2424
publisher: string | undefined;
2525
contractName: string | undefined;
2626
deploymentType?: "asset";
27+
is_testnet: boolean | undefined;
2728
}) {
2829
posthog.capture("contract deployed", properties);
2930
}
@@ -40,6 +41,7 @@ export function reportContractDeployed(properties: {
4041
export function reportContractDeployFailed(properties: {
4142
errorMessage: string;
4243
chainId: number;
44+
is_testnet: boolean | undefined;
4345
publisher: string | undefined;
4446
contractName: string | undefined;
4547
}) {
@@ -171,9 +173,7 @@ export function reportOnboardingCompleted() {
171173
*
172174
*/
173175
export function reportFaucetUsed(properties: { chainId: number }) {
174-
posthog.capture("faucet used", {
175-
chainId: properties.chainId,
176-
});
176+
posthog.capture("faucet used", properties);
177177
}
178178

179179
// ----------------------------
@@ -197,12 +197,7 @@ export function reportChainConfigurationAdded(properties: {
197197
decimals: number;
198198
};
199199
}) {
200-
posthog.capture("chain configuration added", {
201-
chainId: properties.chainId,
202-
chainName: properties.chainName,
203-
nativeCurrency: properties.nativeCurrency,
204-
rpcURLs: properties.rpcURLs,
205-
});
200+
posthog.capture("chain configuration added", properties);
206201
}
207202

208203
// ----------------------------
@@ -227,12 +222,9 @@ export function reportAssetBuySuccessful(properties: {
227222
chainId: number;
228223
contractType: AssetContractType | undefined;
229224
assetType: "nft" | "coin";
225+
is_testnet: boolean | undefined;
230226
}) {
231-
posthog.capture("asset buy successful", {
232-
assetType: properties.assetType,
233-
chainId: properties.chainId,
234-
contractType: properties.contractType,
235-
});
227+
posthog.capture("asset buy successful", properties);
236228
}
237229

238230
type TokenSwapParams = {
@@ -349,16 +341,12 @@ export function reportTokenSwapCancelled(properties: TokenSwapParams) {
349341
*/
350342
export function reportAssetBuyFailed(properties: {
351343
chainId: number;
344+
is_testnet: boolean | undefined;
352345
contractType: AssetContractType | undefined;
353346
assetType: "nft" | "coin";
354347
error: string;
355348
}) {
356-
posthog.capture("asset buy failed", {
357-
assetType: properties.assetType,
358-
chainId: properties.chainId,
359-
contractType: properties.contractType,
360-
error: properties.error,
361-
});
349+
posthog.capture("asset buy failed", properties);
362350
}
363351

364352
/**
@@ -371,14 +359,11 @@ export function reportAssetBuyFailed(properties: {
371359
*/
372360
export function reportAssetBuyCancelled(properties: {
373361
chainId: number;
362+
is_testnet: boolean | undefined;
374363
contractType: AssetContractType | undefined;
375364
assetType: "nft" | "coin";
376365
}) {
377-
posthog.capture("asset buy cancelled", {
378-
assetType: properties.assetType,
379-
chainId: properties.chainId,
380-
contractType: properties.contractType,
381-
});
366+
posthog.capture("asset buy cancelled", properties);
382367
}
383368

384369
// Assets Landing Page ----------------------------
@@ -423,10 +408,7 @@ export function reportAssetCreationStepConfigured(
423408
step: "coin-info" | "token-distribution" | "launch-coin";
424409
},
425410
) {
426-
posthog.capture("asset creation step configured", {
427-
assetType: properties.assetType,
428-
step: properties.step,
429-
});
411+
posthog.capture("asset creation step configured", properties);
430412
}
431413

432414
/**
@@ -440,11 +422,10 @@ export function reportAssetCreationStepConfigured(
440422
export function reportAssetCreationSuccessful(properties: {
441423
assetType: "nft" | "coin";
442424
contractType: AssetContractType;
425+
chainId: number;
426+
is_testnet: boolean | undefined;
443427
}) {
444-
posthog.capture("asset creation successful", {
445-
assetType: properties.assetType,
446-
contractType: properties.contractType,
447-
});
428+
posthog.capture("asset creation successful", properties);
448429
}
449430

450431
type CoinCreationStep =
@@ -466,7 +447,12 @@ type CoinCreationStep =
466447
* @MananTank
467448
*/
468449
export function reportAssetCreationFailed(
469-
properties: { contractType: AssetContractType; error: string } & (
450+
properties: {
451+
contractType: AssetContractType;
452+
error: string;
453+
is_testnet: boolean | undefined;
454+
chainId: number;
455+
} & (
470456
| {
471457
assetType: "nft";
472458
step:
@@ -481,12 +467,7 @@ export function reportAssetCreationFailed(
481467
}
482468
),
483469
) {
484-
posthog.capture("asset creation failed", {
485-
assetType: properties.assetType,
486-
contractType: properties.contractType,
487-
error: properties.error,
488-
step: properties.step,
489-
});
470+
posthog.capture("asset creation failed", properties);
490471
}
491472

492473
type UpsellParams = {
@@ -582,6 +563,7 @@ export function reportPaymentLinkBuyFailed(properties: {
582563
export function reportAssetPageview(properties: {
583564
assetType: "nft" | "coin";
584565
chainId: number;
566+
is_testnet: boolean | undefined;
585567
}) {
586568
posthog.capture("asset pageview", properties);
587569
}
@@ -593,7 +575,10 @@ export function reportAssetPageview(properties: {
593575
* ### Who is responsible for this event?
594576
* @MananTank
595577
*/
596-
export function reportChainPageview(properties: { chainId: number }) {
578+
export function reportChainPageview(properties: {
579+
chainId: number;
580+
is_testnet: boolean | undefined;
581+
}) {
597582
posthog.capture("chain pageview", properties);
598583
}
599584

@@ -686,10 +671,7 @@ export function reportProductFeedback(properties: {
686671
feedback: string;
687672
source: "desktop" | "mobile";
688673
}) {
689-
posthog.capture("product feedback submitted", {
690-
feedback: properties.feedback,
691-
source: properties.source,
692-
});
674+
posthog.capture("product feedback submitted", properties);
693675
}
694676

695677
/**

0 commit comments

Comments
 (0)