Skip to content

Commit 634ab5d

Browse files
cache SA, filter rotated access tokens
1 parent 44d7f6e commit 634ab5d

File tree

9 files changed

+108
-27
lines changed

9 files changed

+108
-27
lines changed

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/components/ProjectSidebarLayout.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { EngineIcon } from "../../../../(dashboard)/(chain)/components/server/ic
1212
import { InsightIcon } from "../../../../(dashboard)/(chain)/components/server/icons/InsightIcon";
1313
import { PayIcon } from "../../../../(dashboard)/(chain)/components/server/icons/PayIcon";
1414
import { SmartAccountIcon } from "../../../../(dashboard)/(chain)/components/server/icons/SmartAccountIcon";
15+
import { Badge } from "../../../../../../@/components/ui/badge";
1516
import { NebulaIcon } from "../../../../../nebula-app/(app)/icons/NebulaIcon";
1617

1718
export function ProjectSidebarLayout(props: {
@@ -62,7 +63,11 @@ export function ProjectSidebarLayout(props: {
6263
},
6364
{
6465
href: `${layoutPath}/engine`,
65-
label: "Engine",
66+
label: (
67+
<span className="flex items-center gap-2">
68+
Engine <Badge>New</Badge>
69+
</span>
70+
),
6671
icon: EngineIcon,
6772
tracking: tracking("engine"),
6873
},

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/analytics/analytics-page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ export function TransactionsAnalyticsPageContent(props: {
1212
interval?: string | undefined | string[];
1313
};
1414
project: Project;
15-
hasTransactions: boolean;
15+
showAnalytics: boolean;
1616
wallets?: Wallet[];
1717
teamSlug: string;
1818
}) {
1919
return (
2020
<ResponsiveSearchParamsProvider value={props.searchParams}>
2121
<div className="flex grow flex-col gap-6">
22-
{props.hasTransactions && (
22+
{props.showAnalytics && (
2323
<>
2424
<div className="flex justify-end">
2525
<TransactionAnalyticsFilter />

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/analytics/ftux.client.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ interface Props {
1515
wallets: Wallet[];
1616
hasTransactions: boolean;
1717
teamSlug: string;
18+
testTxWithWallet?: string | undefined;
1819
}
1920

2021
export const EngineChecklist: React.FC<Props> = (props) => {
@@ -60,6 +61,7 @@ export const EngineChecklist: React.FC<Props> = (props) => {
6061
wallets={props.wallets}
6162
project={props.project}
6263
userAccessToken={userAccessToken}
64+
teamSlug={props.teamSlug}
6365
/>
6466
),
6567
completed: props.hasTransactions,
@@ -76,6 +78,18 @@ export const EngineChecklist: React.FC<Props> = (props) => {
7678
props.teamSlug,
7779
]);
7880

81+
if (props.testTxWithWallet) {
82+
return (
83+
<SendTestTransaction
84+
wallets={props.wallets}
85+
project={props.project}
86+
userAccessToken={userAccessToken}
87+
walletId={props.testTxWithWallet}
88+
teamSlug={props.teamSlug}
89+
/>
90+
);
91+
}
92+
7993
if (finalSteps.length === 1) {
8094
return null;
8195
}

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/analytics/send-test-tx.client.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ type FormValues = z.infer<typeof formSchema>;
4040
export function SendTestTransaction(props: {
4141
wallets?: Wallet[];
4242
project: Project;
43+
teamSlug: string;
4344
userAccessToken?: string;
4445
expanded?: boolean;
46+
walletId?: string;
4547
}) {
4648
const thirdwebClient = useThirdwebClient();
4749
const queryClient = useQueryClient();
@@ -52,7 +54,13 @@ export function SendTestTransaction(props: {
5254
resolver: zodResolver(formSchema),
5355
defaultValues: {
5456
accessToken: props.userAccessToken ?? "",
55-
walletIndex: "0",
57+
walletIndex:
58+
props.wallets && props.walletId
59+
? props.wallets
60+
.findIndex((w) => w.id === props.walletId)
61+
?.toString()
62+
.replace("-1", "0")
63+
: "0",
5664
chainId: 84532,
5765
},
5866
});
@@ -126,6 +134,9 @@ export function SendTestTransaction(props: {
126134
return (
127135
<div className="mt-3 w-full rounded-md border bg-background p-6">
128136
<form onSubmit={form.handleSubmit(onSubmit)}>
137+
{props.walletId && (
138+
<h3 className="mb-4 font-medium text-lg">Send a test transaction</h3>
139+
)}
129140
<p className="flex items-center gap-2 text-sm text-warning-text">
130141
<LockIcon className="h-4 w-4" />
131142
Every wallet action requires your Vault access token.
@@ -182,7 +193,7 @@ export function SendTestTransaction(props: {
182193
<div className="flex items-center gap-2">
183194
<SmartAccountCell wallet={wallet} />
184195
<span className="text-muted-foreground text-sm">
185-
{selectedWallet.metadata.label}
196+
{wallet.metadata.label}
186197
</span>
187198
</div>
188199
</SelectItem>
@@ -251,10 +262,16 @@ export function SendTestTransaction(props: {
251262
variant="primary"
252263
className="w-full md:w-auto"
253264
onClick={() => {
254-
router.refresh();
265+
if (props.walletId) {
266+
router.replace(
267+
`/team/${props.teamSlug}/${props.project.slug}/engine/cloud`,
268+
);
269+
} else {
270+
router.refresh();
271+
}
255272
}}
256273
>
257-
Complete Setup
274+
{props.walletId ? "Close" : "Complete Setup"}
258275
</Button>
259276
)}
260277
</div>

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/page.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export default async function TransactionsAnalyticsPage(props: {
1818
from?: string | string[] | undefined;
1919
to?: string | string[] | undefined;
2020
interval?: string | string[] | undefined;
21+
testTxWithWallet?: string | string[] | undefined;
2122
}>;
2223
}) {
2324
const [params, searchParams, authToken] = await Promise.all([
@@ -84,8 +85,9 @@ export default async function TransactionsAnalyticsPage(props: {
8485
hasTransactions={hasTransactions}
8586
project={project}
8687
wallets={wallets ?? []}
88+
testTxWithWallet={searchParams.testTxWithWallet as string | undefined}
8789
/>
88-
{hasTransactions && (
90+
{hasTransactions && !searchParams.testTxWithWallet && (
8991
<TransactionAnalyticsSummary
9092
initialData={initialData}
9193
teamId={project.teamId}
@@ -97,7 +99,7 @@ export default async function TransactionsAnalyticsPage(props: {
9799
teamSlug={params.team_slug}
98100
searchParams={searchParams}
99101
project={project}
100-
hasTransactions={hasTransactions}
102+
showAnalytics={hasTransactions && !searchParams.testTxWithWallet}
101103
wallets={wallets}
102104
/>
103105
</div>

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/server-wallets/components/create-server-wallet.client.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { createEoa } from "@thirdweb-dev/vault-sdk";
1515
import { Loader2, WalletIcon } from "lucide-react";
1616
import { useState } from "react";
1717
import { toast } from "sonner";
18+
import { engineCloudProxy } from "../../../../../../../../../@/actions/proxies";
1819
import { initVaultClient } from "../../lib/vault.client";
1920

2021
export default function CreateServerWallet(props: {
@@ -57,6 +58,22 @@ export default function CreateServerWallet(props: {
5758
throw new Error("Failed to create eoa");
5859
}
5960

61+
// no need to await this, it's not blocking
62+
engineCloudProxy({
63+
pathname: "/cache/smart-account",
64+
method: "POST",
65+
headers: {
66+
"Content-Type": "application/json",
67+
"x-team-id": props.project.teamId,
68+
"x-client-id": props.project.publishableKey,
69+
},
70+
body: JSON.stringify({
71+
signerAddress: eoa.data.address,
72+
}),
73+
}).catch((err) => {
74+
console.warn("failed to cache server wallet", err);
75+
});
76+
6077
router.refresh();
6178
setModalOpen(false);
6279

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/server-wallets/components/try-it-out.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ curl -X POST "${THIRDWEB_ENGINE_CLOUD_URL}/write/contract" \\
113113
-H "x-vault-access-token: <your-vault-access-token>" \\
114114
-d '{
115115
"executionOptions": {
116-
"type": "AA",
117-
"signerAddress": "<your-signer-address>",
116+
"from": "<your-server-wallet-address>",
118117
"chainId": "84532"
119118
},
120119
"params": [
@@ -138,8 +137,7 @@ const response = await fetch(
138137
},
139138
body: JSON.stringify({
140139
"executionOptions": {
141-
"type": "AA",
142-
"signerAddress": "<your-signer-address>",
140+
"from": "<your-server-wallet-address>",
143141
"chainId": "84532"
144142
},
145143
"params": [
@@ -165,8 +163,7 @@ headers = {
165163
}
166164
payload = {
167165
"executionOptions": {
168-
"type": "AA",
169-
"signerAddress": "<your-signer-address>",
166+
"from": "<your-server-wallet-address>",
170167
"chainId": "84532"
171168
},
172169
"params": [
@@ -203,9 +200,8 @@ func main() {
203200
204201
type RequestBody struct {
205202
ExecutionOptions struct {
206-
Type string \`json:"type"\`
207-
SignerAddress string \`json:"signerAddress"\`
208-
ChainId string \`json:"chainId"\`
203+
From string \`json:"from"\`
204+
ChainId string \`json:"chainId"\`
209205
} \`json:"executionOptions"\`
210206
Params []Param \`json:"params"\`
211207
}
@@ -219,8 +215,7 @@ func main() {
219215
},
220216
},
221217
}
222-
requestBody.ExecutionOptions.Type = "AA"
223-
requestBody.ExecutionOptions.SignerAddress = "<your-signer-address>"
218+
requestBody.ExecutionOptions.From = "<your-server-wallet-address>"
224219
requestBody.ExecutionOptions.ChainId = "84532"
225220
226221
jsonData, _ := json.Marshal(requestBody)
@@ -263,8 +258,7 @@ class Program
263258
{
264259
executionOptions = new
265260
{
266-
type = "AA",
267-
signerAddress = "<your-signer-address>",
261+
from = "<your-server-wallet-address>",
268262
chainId = "84532"
269263
},
270264
@params = new[]

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/server-wallets/wallet-table/wallet-table-ui.client.tsx

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ import { getThirdwebClient } from "@/constants/thirdweb.server";
1919
import { useQuery } from "@tanstack/react-query";
2020
import { formatDistanceToNowStrict } from "date-fns";
2121
import { format } from "date-fns/format";
22+
import { SendIcon } from "lucide-react";
2223
import { useState } from "react";
2324
import {
2425
DEFAULT_ACCOUNT_FACTORY_V0_7,
2526
predictSmartAccountAddress,
2627
} from "thirdweb/wallets/smart";
28+
import { Button } from "../../../../../../../../../@/components/ui/button";
29+
import { useDashboardRouter } from "../../../../../../../../../@/lib/DashboardRouter";
2730
import { useV5DashboardChain } from "../../../../../../../../../lib/v5-adapter";
2831
import CreateServerWallet from "../components/create-server-wallet.client";
2932
import type { Wallet } from "./types";
@@ -76,8 +79,9 @@ export function ServerWalletsTableUI({
7679
<TableRow>
7780
<TableHead>Address</TableHead>
7881
<TableHead>Label</TableHead>
79-
<TableHead>Created At</TableHead>
80-
<TableHead>Updated At</TableHead>
82+
<TableHead className="text-right">Created At</TableHead>
83+
<TableHead className="text-right">Updated At</TableHead>
84+
<TableHead className="text-right">Send test tx</TableHead>
8185
</TableRow>
8286
</TableHeader>
8387
<TableBody>
@@ -98,12 +102,19 @@ export function ServerWalletsTableUI({
98102
)}
99103
</TableCell>
100104
<TableCell>{wallet.metadata.label || "none"}</TableCell>
101-
<TableCell>
105+
<TableCell className="text-right">
102106
<WalletDateCell date={wallet.createdAt} />
103107
</TableCell>
104-
<TableCell>
108+
<TableCell className="text-right">
105109
<WalletDateCell date={wallet.updatedAt} />
106110
</TableCell>
111+
<TableCell className="flex justify-end">
112+
<SendTestTransaction
113+
wallet={wallet}
114+
project={project}
115+
teamSlug={teamSlug}
116+
/>
117+
</TableCell>
107118
</TableRow>
108119
))
109120
)}
@@ -157,3 +168,24 @@ function WalletDateCell({ date }: { date: string }) {
157168
</ToolTipLabel>
158169
);
159170
}
171+
172+
function SendTestTransaction(props: {
173+
wallet: Wallet;
174+
teamSlug: string;
175+
project: Project;
176+
}) {
177+
const router = useDashboardRouter();
178+
return (
179+
<Button
180+
variant="secondary"
181+
size="sm"
182+
onClick={() => {
183+
router.push(
184+
`/team/${props.teamSlug}/${props.project.slug}/engine/cloud?testTxWithWallet=${props.wallet.id}`,
185+
);
186+
}}
187+
>
188+
<SendIcon className="size-4" />
189+
</Button>
190+
);
191+
}

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/engine/cloud/vault/components/list-access-tokens.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export default function ListAccessTokens(props: {
143143
t.metadata?.purpose?.toString() !==
144144
SERVER_WALLET_MANAGEMENT_ACCESS_TOKEN_PURPOSE,
145145
)
146-
.filter((t) => !t.revokedAt),
146+
.filter((t) => !t.revokedAt && !t.isRotated),
147147
};
148148
// Return stub data for now
149149
},

0 commit comments

Comments
 (0)