tapimo 0.5.3 → 0.7.0
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/App.d.ts +15830 -7220
- package/dist/App.d.ts.map +1 -1
- package/dist/App.js +9 -1
- package/dist/App.js.map +1 -1
- package/dist/Scope.d.ts +4 -0
- package/dist/Scope.d.ts.map +1 -1
- package/dist/Scope.js +5 -0
- package/dist/Scope.js.map +1 -1
- package/dist/admin/App.d.ts +1011 -412
- package/dist/admin/App.d.ts.map +1 -1
- package/dist/admin/App.js +4 -0
- package/dist/admin/App.js.map +1 -1
- package/dist/admin/apps/api-keys.d.ts +2 -1
- package/dist/admin/apps/api-keys.d.ts.map +1 -1
- package/dist/admin/apps/early-access.d.ts +148 -0
- package/dist/admin/apps/early-access.d.ts.map +1 -0
- package/dist/admin/apps/early-access.js +133 -0
- package/dist/admin/apps/early-access.js.map +1 -0
- package/dist/admin/apps/organizations.d.ts +124 -1
- package/dist/admin/apps/organizations.d.ts.map +1 -1
- package/dist/admin/apps/organizations.js +97 -6
- package/dist/admin/apps/organizations.js.map +1 -1
- package/dist/admin/apps/verified-tokens.d.ts +526 -1
- package/dist/admin/apps/verified-tokens.d.ts.map +1 -1
- package/dist/admin/apps/verified-tokens.js +214 -1
- package/dist/admin/apps/verified-tokens.js.map +1 -1
- package/dist/admin/ui.generated.d.ts +1 -1
- package/dist/admin/ui.generated.d.ts.map +1 -1
- package/dist/admin/ui.generated.js +95 -75
- package/dist/admin/ui.generated.js.map +1 -1
- package/dist/analytics/Analytics.d.ts.map +1 -1
- package/dist/analytics/Analytics.js +20 -0
- package/dist/analytics/Analytics.js.map +1 -1
- package/dist/analytics/tables/requestEvents.d.ts +18 -0
- package/dist/analytics/tables/requestEvents.d.ts.map +1 -1
- package/dist/analytics/tables/requestEvents.js +36 -7
- package/dist/analytics/tables/requestEvents.js.map +1 -1
- package/dist/apps/data/App.d.ts +6260 -4924
- package/dist/apps/data/App.d.ts.map +1 -1
- package/dist/apps/data/App.js +11 -6
- package/dist/apps/data/App.js.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts +34 -1
- package/dist/apps/data/FundingQuoteProviders.d.ts.map +1 -1
- package/dist/apps/data/FundingQuoteProviders.js +194 -16
- package/dist/apps/data/FundingQuoteProviders.js.map +1 -1
- package/dist/apps/data/FxOracle.d.ts +71 -0
- package/dist/apps/data/FxOracle.d.ts.map +1 -0
- package/dist/apps/data/FxOracle.js +97 -0
- package/dist/apps/data/FxOracle.js.map +1 -0
- package/dist/apps/data/index.d.ts +1 -0
- package/dist/apps/data/index.d.ts.map +1 -1
- package/dist/apps/data/index.js +1 -0
- package/dist/apps/data/index.js.map +1 -1
- package/dist/apps/data/routes/activities.d.ts +3599 -1382
- package/dist/apps/data/routes/activities.d.ts.map +1 -1
- package/dist/apps/data/routes/activities.js +250 -88
- package/dist/apps/data/routes/activities.js.map +1 -1
- package/dist/apps/data/routes/addresses.d.ts +872 -251
- package/dist/apps/data/routes/addresses.d.ts.map +1 -1
- package/dist/apps/data/routes/addresses.js +11 -9
- package/dist/apps/data/routes/addresses.js.map +1 -1
- package/dist/apps/data/routes/balances.d.ts +77 -26
- package/dist/apps/data/routes/balances.d.ts.map +1 -1
- package/dist/apps/data/routes/balances.js +88 -45
- package/dist/apps/data/routes/balances.js.map +1 -1
- package/dist/apps/data/routes/blocks.d.ts +39 -39
- package/dist/apps/data/routes/coingecko.d.ts +54 -54
- package/dist/apps/data/routes/exchanges.d.ts +856 -105
- package/dist/apps/data/routes/exchanges.d.ts.map +1 -1
- package/dist/apps/data/routes/exchanges.js +518 -76
- package/dist/apps/data/routes/exchanges.js.map +1 -1
- package/dist/apps/data/routes/fee-amm.d.ts +81 -67
- package/dist/apps/data/routes/fee-amm.d.ts.map +1 -1
- package/dist/apps/data/routes/fee-amm.js +76 -91
- package/dist/apps/data/routes/fee-amm.js.map +1 -1
- package/dist/apps/data/routes/funding.d.ts +80 -36
- package/dist/apps/data/routes/funding.d.ts.map +1 -1
- package/dist/apps/data/routes/funding.js +65 -31
- package/dist/apps/data/routes/funding.js.map +1 -1
- package/dist/apps/data/routes/receipts.d.ts +392 -315
- package/dist/apps/data/routes/receipts.d.ts.map +1 -1
- package/dist/apps/data/routes/receipts.js +152 -77
- package/dist/apps/data/routes/receipts.js.map +1 -1
- package/dist/apps/data/routes/tokens.d.ts +167 -174
- package/dist/apps/data/routes/tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/tokens.js +15 -13
- package/dist/apps/data/routes/tokens.js.map +1 -1
- package/dist/apps/data/routes/transactions.d.ts +277 -536
- package/dist/apps/data/routes/transactions.d.ts.map +1 -1
- package/dist/apps/data/routes/transactions.js +96 -77
- package/dist/apps/data/routes/transactions.js.map +1 -1
- package/dist/apps/data/routes/transfers.d.ts +157 -81
- package/dist/apps/data/routes/transfers.d.ts.map +1 -1
- package/dist/apps/data/routes/transfers.js +272 -130
- package/dist/apps/data/routes/transfers.js.map +1 -1
- package/dist/apps/data/routes/valuation.d.ts +307 -0
- package/dist/apps/data/routes/valuation.d.ts.map +1 -0
- package/dist/apps/data/routes/valuation.js +292 -0
- package/dist/apps/data/routes/valuation.js.map +1 -0
- package/dist/apps/data/routes/verified-tokens.d.ts +36 -36
- package/dist/apps/data/routes/verified-tokens.d.ts.map +1 -1
- package/dist/apps/data/routes/verified-tokens.js +7 -5
- package/dist/apps/data/routes/verified-tokens.js.map +1 -1
- package/dist/apps/data/routes/webhooks.d.ts +103 -123
- package/dist/apps/data/routes/webhooks.d.ts.map +1 -1
- package/dist/apps/data/routes/webhooks.js +124 -25
- package/dist/apps/data/routes/webhooks.js.map +1 -1
- package/dist/apps/index.d.ts +2 -1
- package/dist/apps/index.d.ts.map +1 -1
- package/dist/apps/index.js +2 -1
- package/dist/apps/index.js.map +1 -1
- package/dist/apps/management/App.d.ts +8554 -1692
- package/dist/apps/management/App.d.ts.map +1 -1
- package/dist/apps/management/App.js +12 -1
- package/dist/apps/management/App.js.map +1 -1
- package/dist/apps/management/routes/api-keys.d.ts +7 -0
- package/dist/apps/management/routes/api-keys.d.ts.map +1 -1
- package/dist/apps/management/routes/api-keys.js +17 -3
- package/dist/apps/management/routes/api-keys.js.map +1 -1
- package/dist/apps/management/routes/billing.d.ts +157 -162
- package/dist/apps/management/routes/billing.d.ts.map +1 -1
- package/dist/apps/management/routes/billing.js +31 -23
- package/dist/apps/management/routes/billing.js.map +1 -1
- package/dist/apps/management/routes/faucet.d.ts +232 -0
- package/dist/apps/management/routes/faucet.d.ts.map +1 -0
- package/dist/apps/management/routes/faucet.js +154 -0
- package/dist/apps/management/routes/faucet.js.map +1 -0
- package/dist/apps/management/routes/invitations.d.ts +60 -60
- package/dist/apps/management/routes/invite-links.d.ts +49 -20
- package/dist/apps/management/routes/invite-links.d.ts.map +1 -1
- package/dist/apps/management/routes/invite-links.js +26 -1
- package/dist/apps/management/routes/invite-links.js.map +1 -1
- package/dist/apps/management/routes/me.d.ts +6 -6
- package/dist/apps/management/routes/members.d.ts +6 -6
- package/dist/apps/management/routes/orgs.d.ts +42 -42
- package/dist/apps/management/routes/orgs.d.ts.map +1 -1
- package/dist/apps/management/routes/orgs.js +5 -0
- package/dist/apps/management/routes/orgs.js.map +1 -1
- package/dist/apps/management/routes/projects.d.ts +44 -44
- package/dist/apps/management/routes/usage.d.ts +3 -0
- package/dist/apps/management/routes/usage.d.ts.map +1 -1
- package/dist/apps/management/routes/usage.js +4 -0
- package/dist/apps/management/routes/usage.js.map +1 -1
- package/dist/apps/management/routes/verified-token-requests.d.ts +697 -0
- package/dist/apps/management/routes/verified-token-requests.d.ts.map +1 -0
- package/dist/apps/management/routes/verified-token-requests.js +271 -0
- package/dist/apps/management/routes/verified-token-requests.js.map +1 -0
- package/dist/apps/management/routes/webhooks.d.ts +6977 -0
- package/dist/apps/management/routes/webhooks.d.ts.map +1 -0
- package/dist/apps/management/routes/webhooks.js +573 -0
- package/dist/apps/management/routes/webhooks.js.map +1 -0
- package/dist/apps/mpp/App.d.ts +363 -0
- package/dist/apps/mpp/App.d.ts.map +1 -0
- package/dist/apps/mpp/App.js +72 -0
- package/dist/apps/mpp/App.js.map +1 -0
- package/dist/apps/mpp/Mpp.d.ts +178 -0
- package/dist/apps/mpp/Mpp.d.ts.map +1 -0
- package/dist/apps/mpp/Mpp.js +183 -0
- package/dist/apps/mpp/Mpp.js.map +1 -0
- package/dist/apps/mpp/index.d.ts +3 -0
- package/dist/apps/mpp/index.d.ts.map +1 -0
- package/dist/apps/mpp/index.js +3 -0
- package/dist/apps/mpp/index.js.map +1 -0
- package/dist/apps/relay/App.d.ts.map +1 -1
- package/dist/apps/relay/App.js +56 -9
- package/dist/apps/relay/App.js.map +1 -1
- package/dist/db/Db.d.ts +6 -0
- package/dist/db/Db.d.ts.map +1 -1
- package/dist/db/Db.js +110 -0
- package/dist/db/Db.js.map +1 -1
- package/dist/db/Schema.d.ts +53 -0
- package/dist/db/Schema.d.ts.map +1 -1
- package/dist/db/Schema.js +56 -0
- package/dist/db/Schema.js.map +1 -1
- package/dist/db/tables/earlyAccess.d.ts +50 -0
- package/dist/db/tables/earlyAccess.d.ts.map +1 -0
- package/dist/db/tables/earlyAccess.js +63 -0
- package/dist/db/tables/earlyAccess.js.map +1 -0
- package/dist/db/tables/enabledBillingSources.d.ts +73 -0
- package/dist/db/tables/enabledBillingSources.d.ts.map +1 -0
- package/dist/db/tables/enabledBillingSources.js +69 -0
- package/dist/db/tables/enabledBillingSources.js.map +1 -0
- package/dist/db/tables/invitations.d.ts.map +1 -1
- package/dist/db/tables/invitations.js +3 -0
- package/dist/db/tables/invitations.js.map +1 -1
- package/dist/db/tables/inviteLinks.d.ts +10 -2
- package/dist/db/tables/inviteLinks.d.ts.map +1 -1
- package/dist/db/tables/inviteLinks.js +10 -1
- package/dist/db/tables/inviteLinks.js.map +1 -1
- package/dist/db/tables/organizations.d.ts +5 -2
- package/dist/db/tables/organizations.d.ts.map +1 -1
- package/dist/db/tables/organizations.js +13 -2
- package/dist/db/tables/organizations.js.map +1 -1
- package/dist/db/tables/sponsoredTransactions.d.ts +2 -0
- package/dist/db/tables/sponsoredTransactions.d.ts.map +1 -1
- package/dist/db/tables/sponsoredTransactions.js +2 -0
- package/dist/db/tables/sponsoredTransactions.js.map +1 -1
- package/dist/db/tables/verifiedTokenRequests.d.ts +94 -0
- package/dist/db/tables/verifiedTokenRequests.d.ts.map +1 -0
- package/dist/db/tables/verifiedTokenRequests.js +120 -0
- package/dist/db/tables/verifiedTokenRequests.js.map +1 -0
- package/dist/db/tables/webhookSubscriptions.d.ts +14 -0
- package/dist/db/tables/webhookSubscriptions.d.ts.map +1 -1
- package/dist/db/tables/webhookSubscriptions.js +16 -0
- package/dist/db/tables/webhookSubscriptions.js.map +1 -1
- package/dist/handlers/internal/utils.d.ts +1 -16
- package/dist/handlers/internal/utils.d.ts.map +1 -1
- package/dist/handlers/internal/utils.js +17 -6
- package/dist/handlers/internal/utils.js.map +1 -1
- package/dist/handlers/relay.d.ts.map +1 -1
- package/dist/handlers/relay.js +37 -5
- package/dist/handlers/relay.js.map +1 -1
- package/dist/internal/Auth.d.ts +11 -2
- package/dist/internal/Auth.d.ts.map +1 -1
- package/dist/internal/Auth.js +14 -47
- package/dist/internal/Auth.js.map +1 -1
- package/dist/internal/FundingQuotes.d.ts +147 -47
- package/dist/internal/FundingQuotes.d.ts.map +1 -1
- package/dist/internal/FundingQuotes.js +119 -33
- package/dist/internal/FundingQuotes.js.map +1 -1
- package/dist/internal/Log.d.ts +37 -5
- package/dist/internal/Log.d.ts.map +1 -1
- package/dist/internal/Log.js +52 -3
- package/dist/internal/Log.js.map +1 -1
- package/dist/internal/MetricSink.d.ts.map +1 -1
- package/dist/internal/MetricSink.js +24 -0
- package/dist/internal/MetricSink.js.map +1 -1
- package/dist/internal/OpenApi.d.ts +2 -2
- package/dist/internal/OpenApi.d.ts.map +1 -1
- package/dist/internal/OpenApi.js +3 -0
- package/dist/internal/OpenApi.js.map +1 -1
- package/dist/internal/Response.d.ts +2 -2
- package/dist/internal/Response.d.ts.map +1 -1
- package/dist/internal/Response.js +12 -4
- package/dist/internal/Response.js.map +1 -1
- package/dist/internal/Schema.d.ts +14 -5
- package/dist/internal/Schema.d.ts.map +1 -1
- package/dist/internal/Schema.js +23 -5
- package/dist/internal/Schema.js.map +1 -1
- package/dist/internal/Value.d.ts +18 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js +11 -1
- package/dist/internal/Value.js.map +1 -1
- package/dist/internal/VerifiedTokens.d.ts.map +1 -1
- package/dist/internal/VerifiedTokens.js +10 -1
- package/dist/internal/VerifiedTokens.js.map +1 -1
- package/dist/internal/Webhooks.d.ts +24 -3
- package/dist/internal/Webhooks.d.ts.map +1 -1
- package/dist/internal/Webhooks.js +34 -8
- package/dist/internal/Webhooks.js.map +1 -1
- package/package.json +7 -2
- package/src/App.test.ts +9 -4
- package/src/App.ts +23 -3
- package/src/Client.test-d.ts +733 -20
- package/src/Scope.ts +5 -0
- package/src/admin/App.test.ts +4 -0
- package/src/admin/App.ts +4 -0
- package/src/admin/apps/early-access.test.ts +125 -0
- package/src/admin/apps/early-access.ts +176 -0
- package/src/admin/apps/organizations.test.ts +86 -2
- package/src/admin/apps/organizations.ts +155 -31
- package/src/admin/apps/scopes.test.ts +5 -0
- package/src/admin/apps/verified-tokens.test.ts +201 -0
- package/src/admin/apps/verified-tokens.ts +532 -286
- package/src/admin/ui/plugin.ts +2 -1
- package/src/admin/ui/src/lib/early-access.ts +63 -0
- package/src/admin/ui/src/lib/organizations.test.ts +81 -1
- package/src/admin/ui/src/lib/organizations.ts +92 -0
- package/src/admin/ui/src/lib/verified-tokens.ts +79 -0
- package/src/admin/ui/src/routeTree.gen.ts +33 -2
- package/src/admin/ui/src/routes/__root.tsx +2 -1
- package/src/admin/ui/src/routes/api-keys.tsx +1 -1
- package/src/admin/ui/src/routes/early-access.tsx +162 -0
- package/src/admin/ui/src/routes/organizations_.$orgId.tsx +103 -0
- package/src/admin/ui/src/routes/verified-tokens.tsx +230 -19
- package/src/admin/ui.generated.ts +95 -94
- package/src/analytics/Analytics.test.ts +83 -0
- package/src/analytics/Analytics.ts +20 -0
- package/src/analytics/tables/requestEvents.ts +60 -7
- package/src/apps/composition.test.ts +11 -2
- package/src/apps/data/App.test.ts +1 -1
- package/src/apps/data/App.ts +22 -14
- package/src/apps/data/FundingQuoteProviders.test.ts +297 -4
- package/src/apps/data/FundingQuoteProviders.ts +255 -29
- package/src/apps/data/FxOracle.test.ts +118 -0
- package/src/apps/data/FxOracle.ts +153 -0
- package/src/apps/data/index.ts +1 -0
- package/src/apps/data/routes/activities.test.ts +177 -3
- package/src/apps/data/routes/activities.ts +441 -132
- package/src/apps/data/routes/addresses.ts +19 -9
- package/src/apps/data/routes/balances.test.ts +148 -11
- package/src/apps/data/routes/balances.ts +140 -51
- package/src/apps/data/routes/exchanges.test.ts +544 -9
- package/src/apps/data/routes/exchanges.ts +690 -103
- package/src/apps/data/routes/fee-amm.test.ts +47 -23
- package/src/apps/data/routes/fee-amm.ts +98 -119
- package/src/apps/data/routes/funding.test.ts +113 -8
- package/src/apps/data/routes/funding.ts +77 -51
- package/src/apps/data/routes/receipts.test.ts +129 -23
- package/src/apps/data/routes/receipts.ts +205 -100
- package/src/apps/data/routes/tokens.test.ts +43 -0
- package/src/apps/data/routes/tokens.ts +28 -13
- package/src/apps/data/routes/transactions.test.ts +72 -19
- package/src/apps/data/routes/transactions.ts +162 -92
- package/src/apps/data/routes/transfers.test.ts +341 -31
- package/src/apps/data/routes/transfers.ts +358 -158
- package/src/apps/data/routes/valuation.test.ts +437 -0
- package/src/apps/data/routes/valuation.ts +423 -0
- package/src/apps/data/routes/verified-tokens.ts +14 -2
- package/src/apps/data/routes/webhooks.test.ts +56 -8
- package/src/apps/data/routes/webhooks.ts +144 -27
- package/src/apps/index.ts +2 -1
- package/src/apps/management/App.ts +13 -0
- package/src/apps/management/routes/api-keys.test.ts +14 -0
- package/src/apps/management/routes/api-keys.ts +27 -3
- package/src/apps/management/routes/billing.test.ts +152 -20
- package/src/apps/management/routes/billing.ts +34 -18
- package/src/apps/management/routes/faucet.test.ts +87 -0
- package/src/apps/management/routes/faucet.ts +201 -0
- package/src/apps/management/routes/invite-links.test.ts +117 -0
- package/src/apps/management/routes/invite-links.ts +43 -1
- package/src/apps/management/routes/me.test.ts +9 -99
- package/src/apps/management/routes/orgs.test.ts +45 -2
- package/src/apps/management/routes/orgs.ts +6 -0
- package/src/apps/management/routes/scopes.test.ts +1 -0
- package/src/apps/management/routes/usage.test.ts +6 -0
- package/src/apps/management/routes/usage.ts +7 -0
- package/src/apps/management/routes/verified-token-requests.test.ts +377 -0
- package/src/apps/management/routes/verified-token-requests.ts +397 -0
- package/src/apps/management/routes/webhooks.test.ts +426 -0
- package/src/apps/management/routes/webhooks.ts +672 -0
- package/src/apps/mpp/App.ts +86 -0
- package/src/apps/mpp/Mpp.test.ts +193 -0
- package/src/apps/mpp/Mpp.ts +353 -0
- package/src/apps/mpp/index.ts +2 -0
- package/src/apps/mpp/internal/Adapter.ts +11 -0
- package/src/apps/mpp/internal/Error.ts +9 -0
- package/src/apps/mpp/internal/Idempotency.ts +7 -0
- package/src/apps/mpp/internal/Screening.ts +10 -0
- package/src/apps/relay/App.test.ts +88 -6
- package/src/apps/relay/App.ts +61 -9
- package/src/db/Db.test.ts +19 -0
- package/src/db/Db.ts +125 -0
- package/src/db/Schema.ts +68 -0
- package/src/db/tables/earlyAccess.ts +86 -0
- package/src/db/tables/enabledBillingSources.test.ts +303 -0
- package/src/db/tables/enabledBillingSources.ts +118 -0
- package/src/db/tables/invitations.ts +3 -0
- package/src/db/tables/inviteLinks.ts +22 -3
- package/src/db/tables/organizations.test.ts +103 -0
- package/src/db/tables/organizations.ts +18 -2
- package/src/db/tables/sponsoredTransactions.ts +4 -0
- package/src/db/tables/verifiedTokenRequests.test.ts +200 -0
- package/src/db/tables/verifiedTokenRequests.ts +182 -0
- package/src/db/tables/webhookSubscriptions.ts +31 -0
- package/src/handlers/internal/utils.ts +22 -6
- package/src/handlers/relay.errors.test.ts +153 -0
- package/src/handlers/relay.ts +42 -7
- package/src/internal/Auth.test.ts +3 -3
- package/src/internal/Auth.ts +15 -47
- package/src/internal/FundingQuotes.test.ts +161 -6
- package/src/internal/FundingQuotes.ts +141 -39
- package/src/internal/Log.test-d.ts +21 -0
- package/src/internal/Log.test.ts +141 -0
- package/src/internal/Log.ts +93 -6
- package/src/internal/MetricSink.test.ts +215 -0
- package/src/internal/MetricSink.ts +24 -0
- package/src/internal/OpenApi.ts +3 -0
- package/src/internal/Response.test.ts +28 -0
- package/src/internal/Response.ts +12 -4
- package/src/internal/Schema.ts +50 -5
- package/src/internal/Value.test.ts +20 -0
- package/src/internal/Value.ts +24 -1
- package/src/internal/VerifiedTokens.ts +9 -1
- package/src/internal/Webhooks.test.ts +140 -0
- package/src/internal/Webhooks.ts +53 -9
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Switch } from '@base-ui/react/switch'
|
|
1
2
|
import {
|
|
2
3
|
type UseQueryResult,
|
|
3
4
|
useInfiniteQuery,
|
|
@@ -30,6 +31,8 @@ function PageComponent() {
|
|
|
30
31
|
const { period: period_search, query } = Route.useSearch()
|
|
31
32
|
const navigate = useNavigate({ from: Route.fullPath })
|
|
32
33
|
const period = period_search ?? '7d'
|
|
34
|
+
const disableBillingSource = Organizations.disableBillingSource.useMutation(orgId)
|
|
35
|
+
const enableBillingSource = Organizations.enableBillingSource.useMutation(orgId)
|
|
33
36
|
const organizationQuery = useSuspenseQuery(Organizations.get.options(orgId))
|
|
34
37
|
const organization = organizationQuery.data
|
|
35
38
|
const members = useInfiniteQuery(Organizations.members.options(orgId))
|
|
@@ -54,6 +57,8 @@ function PageComponent() {
|
|
|
54
57
|
const updateComplete = operationalQueries.every((result) => result.dataUpdatedAt > 0)
|
|
55
58
|
const updateError = operationalQueries.some((result) => result.error)
|
|
56
59
|
const refreshing = operationalQueries.some((result) => result.isFetching)
|
|
60
|
+
const billingSourceError = disableBillingSource.error ?? enableBillingSource.error
|
|
61
|
+
const billingSourcePending = disableBillingSource.isPending || enableBillingSource.isPending
|
|
57
62
|
|
|
58
63
|
function refresh() {
|
|
59
64
|
void Promise.all([
|
|
@@ -67,6 +72,16 @@ function PageComponent() {
|
|
|
67
72
|
])
|
|
68
73
|
}
|
|
69
74
|
|
|
75
|
+
function setBillingSource(options: BillingSourceChange) {
|
|
76
|
+
if (options.enabled) {
|
|
77
|
+
disableBillingSource.reset()
|
|
78
|
+
enableBillingSource.mutate(options.source)
|
|
79
|
+
} else {
|
|
80
|
+
enableBillingSource.reset()
|
|
81
|
+
disableBillingSource.mutate(options.source)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
70
85
|
return (
|
|
71
86
|
<Page
|
|
72
87
|
title={organization.name}
|
|
@@ -176,6 +191,12 @@ function PageComponent() {
|
|
|
176
191
|
|
|
177
192
|
<section className="flex flex-col gap-3">
|
|
178
193
|
<h2 className="text-heading-18 text-foreground">Billing</h2>
|
|
194
|
+
<BillingSourcesCard
|
|
195
|
+
enabledSources={organization.billing.enabledSources}
|
|
196
|
+
error={billingSourceError}
|
|
197
|
+
onChange={setBillingSource}
|
|
198
|
+
pending={billingSourcePending}
|
|
199
|
+
/>
|
|
179
200
|
<div className="grid gap-3 md:grid-cols-2">
|
|
180
201
|
<BillingCard
|
|
181
202
|
environment="Production"
|
|
@@ -550,6 +571,88 @@ declare namespace SectionError {
|
|
|
550
571
|
type Props = { error: Error; onRetry: () => unknown }
|
|
551
572
|
}
|
|
552
573
|
|
|
574
|
+
type BillingSourceChange = {
|
|
575
|
+
/** Whether the source should be enabled. */
|
|
576
|
+
enabled: boolean
|
|
577
|
+
/** Billing source being changed. */
|
|
578
|
+
source: Organizations.BillingSource
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
const billingSourceOptions = [
|
|
582
|
+
{
|
|
583
|
+
description: 'Allow the organization to set up Stripe as a billing method.',
|
|
584
|
+
label: 'Stripe',
|
|
585
|
+
source: 'stripe',
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
description: 'Allow the organization to set up a Tempo account as a billing method.',
|
|
589
|
+
label: 'Tempo',
|
|
590
|
+
source: 'tempo',
|
|
591
|
+
},
|
|
592
|
+
] as const
|
|
593
|
+
|
|
594
|
+
/** Organization-wide controls for billing-source setup. */
|
|
595
|
+
export function BillingSourcesCard(options: BillingSourcesCard.Props) {
|
|
596
|
+
return (
|
|
597
|
+
<Card>
|
|
598
|
+
<div className="p-4">
|
|
599
|
+
<h3 className="text-label-14 text-foreground">Enabled sources</h3>
|
|
600
|
+
<p className="mt-1 text-copy-13 text-foreground-secondary">
|
|
601
|
+
Disabling a source only blocks new setup. Existing billing connections continue to work.
|
|
602
|
+
</p>
|
|
603
|
+
</div>
|
|
604
|
+
<div className="divide-y divide-border border-t border-border">
|
|
605
|
+
{billingSourceOptions.map((source) => {
|
|
606
|
+
const enabled = options.enabledSources.includes(source.source)
|
|
607
|
+
return (
|
|
608
|
+
<div className="flex items-center justify-between gap-4 p-4" key={source.source}>
|
|
609
|
+
<div className="min-w-0">
|
|
610
|
+
<div className="flex items-center gap-2">
|
|
611
|
+
<span className="text-label-14 text-foreground">{source.label}</span>
|
|
612
|
+
<span className="text-label-12 text-foreground-secondary">
|
|
613
|
+
{enabled ? 'Enabled' : 'Disabled'}
|
|
614
|
+
</span>
|
|
615
|
+
</div>
|
|
616
|
+
<p className="mt-1 text-copy-13 text-foreground-secondary">{source.description}</p>
|
|
617
|
+
</div>
|
|
618
|
+
<Switch.Root
|
|
619
|
+
aria-label={`${source.label} billing source`}
|
|
620
|
+
checked={enabled}
|
|
621
|
+
className="flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-border bg-secondary p-0.5 outline-none transition-colors hover:bg-secondary-hover focus-visible:border-focus data-[checked]:bg-invert disabled:cursor-not-allowed disabled:opacity-50"
|
|
622
|
+
disabled={options.pending}
|
|
623
|
+
onCheckedChange={(checked) =>
|
|
624
|
+
options.onChange({ enabled: checked, source: source.source })
|
|
625
|
+
}
|
|
626
|
+
>
|
|
627
|
+
<Switch.Thumb className="block size-4 translate-x-0 rounded-full bg-foreground-secondary transition-transform data-[checked]:translate-x-4 data-[checked]:bg-on-invert" />
|
|
628
|
+
</Switch.Root>
|
|
629
|
+
</div>
|
|
630
|
+
)
|
|
631
|
+
})}
|
|
632
|
+
</div>
|
|
633
|
+
{options.error ? (
|
|
634
|
+
<p className="border-t border-border p-4 text-copy-13 text-negative" role="alert">
|
|
635
|
+
{options.error.message}
|
|
636
|
+
</p>
|
|
637
|
+
) : null}
|
|
638
|
+
</Card>
|
|
639
|
+
)
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
export declare namespace BillingSourcesCard {
|
|
643
|
+
/** Billing-source control properties. */
|
|
644
|
+
type Props = {
|
|
645
|
+
/** Currently enabled billing sources. */
|
|
646
|
+
enabledSources: readonly Organizations.BillingSource[]
|
|
647
|
+
/** Latest mutation error. */
|
|
648
|
+
error: Error | null
|
|
649
|
+
/** Handles a requested source change. */
|
|
650
|
+
onChange: (options: BillingSourceChange) => void
|
|
651
|
+
/** Whether a source change is pending. */
|
|
652
|
+
pending: boolean
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
553
656
|
function BillingCard(options: BillingCard.Props) {
|
|
554
657
|
const { settings, source } = options.record
|
|
555
658
|
const remaining =
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
1
|
+
import { createFileRoute, useNavigate } from '@tanstack/react-router'
|
|
2
2
|
import { useState } from 'react'
|
|
3
|
-
import { Button, Fields, Input, Select, useCopy } from 'regen-ui'
|
|
3
|
+
import { Button, Fields, Input, Select, Tabs, useCopy } from 'regen-ui'
|
|
4
4
|
import { Check, Copy as CopyIcon, ExternalLink, Plus, Trash2 } from 'lucide-react'
|
|
5
5
|
import { isAddress } from 'viem'
|
|
6
6
|
import { tempo as mainnet, tempoTestnet as testnet } from 'viem/tempo/chains'
|
|
7
7
|
import { Hooks } from 'wagmi/tempo'
|
|
8
8
|
|
|
9
9
|
import { Card, Notice, Page } from '../components/Page'
|
|
10
|
+
import { Checkbox } from '../components/Checkbox'
|
|
10
11
|
import { Dialog } from '../components/Dialog'
|
|
11
12
|
import * as VerifiedTokens from '../lib/verified-tokens'
|
|
12
13
|
|
|
@@ -17,8 +18,12 @@ type ChainId = typeof mainnet.id | typeof testnet.id
|
|
|
17
18
|
const defaultChain: ChainId = mainnet.id
|
|
18
19
|
|
|
19
20
|
export const Route = createFileRoute('/verified-tokens')({
|
|
21
|
+
validateSearch: VerifiedTokens.search,
|
|
20
22
|
loader: ({ context }) =>
|
|
21
|
-
|
|
23
|
+
Promise.all([
|
|
24
|
+
context.queryClient.prefetchQuery(VerifiedTokens.get.options({ chainId: defaultChain })),
|
|
25
|
+
context.queryClient.prefetchQuery(VerifiedTokens.requests.list.options()),
|
|
26
|
+
]),
|
|
22
27
|
component: RouteComponent,
|
|
23
28
|
})
|
|
24
29
|
|
|
@@ -35,10 +40,14 @@ const explorers: Record<number, string> = {
|
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
function RouteComponent() {
|
|
43
|
+
const { tab = 'verified' } = Route.useSearch()
|
|
44
|
+
const navigate = useNavigate({ from: Route.fullPath })
|
|
38
45
|
const [chain, setChain] = useState<ChainId>(defaultChain)
|
|
39
46
|
const [open, setOpen] = useState(false)
|
|
40
47
|
const tokens = VerifiedTokens.get.useQuery({ chainId: chain })
|
|
48
|
+
const requests = VerifiedTokens.requests.list.useQuery()
|
|
41
49
|
const create = VerifiedTokens.create.useMutation()
|
|
50
|
+
const pendingCount = requests.data?.data.length ?? 0
|
|
42
51
|
|
|
43
52
|
return (
|
|
44
53
|
<Dialog.Root onOpenChange={setOpen} open={open}>
|
|
@@ -46,25 +55,43 @@ function RouteComponent() {
|
|
|
46
55
|
title="Verified Tokens"
|
|
47
56
|
description="Manage the curated verified token list"
|
|
48
57
|
action={
|
|
49
|
-
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
tab === 'verified' ? (
|
|
59
|
+
<div className="flex items-center gap-2">
|
|
60
|
+
<ChainSelect onChange={setChain} value={chain} />
|
|
61
|
+
<Dialog.Trigger
|
|
62
|
+
render={
|
|
63
|
+
<Button variant="primary">
|
|
64
|
+
<Plus className="size-4" />
|
|
65
|
+
Add token
|
|
66
|
+
</Button>
|
|
67
|
+
}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
) : undefined
|
|
60
71
|
}
|
|
61
72
|
>
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
<Tabs
|
|
74
|
+
active={tab}
|
|
75
|
+
onChange={(id) => void navigate({ search: id === 'verified' ? {} : { tab: id } })}
|
|
76
|
+
tabs={[
|
|
77
|
+
{ id: 'verified', label: 'Verified' },
|
|
78
|
+
{ id: 'pending', label: pendingCount > 0 ? `Pending (${pendingCount})` : 'Pending' },
|
|
79
|
+
]}
|
|
67
80
|
/>
|
|
81
|
+
{tab === 'verified' ? (
|
|
82
|
+
<TokenList
|
|
83
|
+
chain={chain}
|
|
84
|
+
error={tokens.error}
|
|
85
|
+
loading={tokens.isPending}
|
|
86
|
+
tokens={tokens.data?.data ?? []}
|
|
87
|
+
/>
|
|
88
|
+
) : (
|
|
89
|
+
<RequestQueue
|
|
90
|
+
error={requests.error}
|
|
91
|
+
loading={requests.isPending}
|
|
92
|
+
requests={requests.data?.data ?? []}
|
|
93
|
+
/>
|
|
94
|
+
)}
|
|
68
95
|
<Dialog.Popup>
|
|
69
96
|
<AddTokenForm
|
|
70
97
|
defaultChain={chain}
|
|
@@ -82,6 +109,190 @@ function RouteComponent() {
|
|
|
82
109
|
)
|
|
83
110
|
}
|
|
84
111
|
|
|
112
|
+
/** Display label for a chain, falling back to the raw id. */
|
|
113
|
+
function chainLabel(chainId: number) {
|
|
114
|
+
return chains.find((chain) => chain.id === chainId)?.label ?? String(chainId)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Pending verification requests, oldest first, reviewed in bulk via selection. */
|
|
118
|
+
function RequestQueue(props: {
|
|
119
|
+
error: Error | null
|
|
120
|
+
loading: boolean
|
|
121
|
+
requests: readonly VerifiedTokens.requests.VerifiedTokenRequest[]
|
|
122
|
+
}) {
|
|
123
|
+
const approve = VerifiedTokens.requests.approve.useMutation()
|
|
124
|
+
const deny = VerifiedTokens.requests.deny.useMutation()
|
|
125
|
+
const [selected, setSelected] = useState<ReadonlySet<string>>(new Set())
|
|
126
|
+
const [busy, setBusy] = useState<'approve' | 'deny' | null>(null)
|
|
127
|
+
// Filtering against the live rows self-heals selections whose requests were
|
|
128
|
+
// reviewed elsewhere or removed by a refetch.
|
|
129
|
+
const chosen = props.requests.filter((request) => selected.has(request.id))
|
|
130
|
+
|
|
131
|
+
function toggle(id: string) {
|
|
132
|
+
setSelected((previous) => {
|
|
133
|
+
const next = new Set(previous)
|
|
134
|
+
if (next.has(id)) next.delete(id)
|
|
135
|
+
else next.add(id)
|
|
136
|
+
return next
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function review(action: 'approve' | 'deny') {
|
|
141
|
+
if (action === 'approve' && !confirm(`Verify ${describeSelection(chosen)}?`)) return
|
|
142
|
+
let reviewNote: string | undefined
|
|
143
|
+
if (action === 'deny') {
|
|
144
|
+
const input = prompt(`Reason for denying ${describeSelection(chosen)} (optional):`)
|
|
145
|
+
if (input === null) return
|
|
146
|
+
reviewNote = input.trim() || undefined
|
|
147
|
+
}
|
|
148
|
+
setBusy(action)
|
|
149
|
+
try {
|
|
150
|
+
for (const request of chosen) {
|
|
151
|
+
if (action === 'approve')
|
|
152
|
+
await approve.mutateAsync({ chainId: request.chainId, requestId: request.id })
|
|
153
|
+
else
|
|
154
|
+
await deny.mutateAsync({
|
|
155
|
+
requestId: request.id,
|
|
156
|
+
...(reviewNote ? { reviewNote } : {}),
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
setSelected(new Set())
|
|
160
|
+
} catch (error) {
|
|
161
|
+
alert(error instanceof Error ? error.message : String(error))
|
|
162
|
+
} finally {
|
|
163
|
+
setBusy(null)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<Card>
|
|
169
|
+
{props.requests.length > 0 ? (
|
|
170
|
+
<div className="flex items-center justify-between gap-4 border-b border-border px-5 py-3">
|
|
171
|
+
<span className="text-label-12 text-foreground-secondary">{chosen.length} selected</span>
|
|
172
|
+
<div className="flex items-center gap-2">
|
|
173
|
+
<Button
|
|
174
|
+
disabled={chosen.length === 0 || busy !== null}
|
|
175
|
+
loading={busy === 'deny'}
|
|
176
|
+
onClick={() => void review('deny')}
|
|
177
|
+
size="small"
|
|
178
|
+
>
|
|
179
|
+
Deny
|
|
180
|
+
</Button>
|
|
181
|
+
<Button
|
|
182
|
+
disabled={chosen.length === 0 || busy !== null}
|
|
183
|
+
loading={busy === 'approve'}
|
|
184
|
+
onClick={() => void review('approve')}
|
|
185
|
+
size="small"
|
|
186
|
+
variant="primary"
|
|
187
|
+
>
|
|
188
|
+
Approve
|
|
189
|
+
</Button>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
) : null}
|
|
193
|
+
{props.loading ? (
|
|
194
|
+
<Notice>Loading requests…</Notice>
|
|
195
|
+
) : props.error ? (
|
|
196
|
+
<Notice>{props.error.message}</Notice>
|
|
197
|
+
) : props.requests.length === 0 ? (
|
|
198
|
+
<Notice>No pending requests.</Notice>
|
|
199
|
+
) : (
|
|
200
|
+
<ul className="divide-y divide-border">
|
|
201
|
+
{props.requests.map((request) => (
|
|
202
|
+
<RequestRow
|
|
203
|
+
key={request.id}
|
|
204
|
+
onToggle={() => toggle(request.id)}
|
|
205
|
+
request={request}
|
|
206
|
+
selected={selected.has(request.id)}
|
|
207
|
+
/>
|
|
208
|
+
))}
|
|
209
|
+
</ul>
|
|
210
|
+
)}
|
|
211
|
+
</Card>
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Confirmation label: one token by name, several by count. */
|
|
216
|
+
function describeSelection(requests: readonly VerifiedTokens.requests.VerifiedTokenRequest[]) {
|
|
217
|
+
const [first] = requests
|
|
218
|
+
if (requests.length === 1 && first) return `${first.name} (${first.symbol})`
|
|
219
|
+
return `${requests.length} tokens`
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function RequestRow(props: {
|
|
223
|
+
onToggle: () => void
|
|
224
|
+
request: VerifiedTokens.requests.VerifiedTokenRequest
|
|
225
|
+
selected: boolean
|
|
226
|
+
}) {
|
|
227
|
+
const { request } = props
|
|
228
|
+
return (
|
|
229
|
+
// The row is a pointer affordance for the checkbox; clicks on interactive
|
|
230
|
+
// children (copy button, the checkbox itself) keep their own behavior.
|
|
231
|
+
<li
|
|
232
|
+
className="flex cursor-pointer items-center justify-between gap-4 px-5 py-3 transition-colors hover:bg-surface-hover data-[selected]:bg-surface-hover"
|
|
233
|
+
data-selected={props.selected || undefined}
|
|
234
|
+
onClick={(event) => {
|
|
235
|
+
if ((event.target as HTMLElement).closest('a, button, input')) return
|
|
236
|
+
props.onToggle()
|
|
237
|
+
}}
|
|
238
|
+
>
|
|
239
|
+
<div className="flex min-w-0 items-center gap-4">
|
|
240
|
+
<RequestLogo request={request} />
|
|
241
|
+
<div className="flex min-w-0 flex-col gap-1">
|
|
242
|
+
<span className="text-label-14 text-foreground">
|
|
243
|
+
{request.name} <span className="text-foreground-secondary">{request.symbol}</span>{' '}
|
|
244
|
+
<span className="text-foreground-secondary">· {chainLabel(request.chainId)}</span>
|
|
245
|
+
</span>
|
|
246
|
+
<div className="flex items-center gap-3">
|
|
247
|
+
<Address value={request.address} />
|
|
248
|
+
<span className="text-label-12 text-foreground-secondary">
|
|
249
|
+
{request.orgName ?? request.orgId} ·{' '}
|
|
250
|
+
{new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(
|
|
251
|
+
new Date(request.createdAt),
|
|
252
|
+
)}
|
|
253
|
+
</span>
|
|
254
|
+
</div>
|
|
255
|
+
{request.note ? (
|
|
256
|
+
<p className="truncate text-label-12 text-foreground-secondary" title={request.note}>
|
|
257
|
+
{request.note}
|
|
258
|
+
</p>
|
|
259
|
+
) : null}
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
<Checkbox
|
|
263
|
+
aria-label={`Select ${request.name}`}
|
|
264
|
+
checked={props.selected}
|
|
265
|
+
onCheckedChange={props.onToggle}
|
|
266
|
+
/>
|
|
267
|
+
</li>
|
|
268
|
+
)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Requested logo (uploaded SVG or URL), falling back to symbol initials. */
|
|
272
|
+
function RequestLogo(props: { request: VerifiedTokens.requests.VerifiedTokenRequest }) {
|
|
273
|
+
const { request } = props
|
|
274
|
+
const [failed, setFailed] = useState(false)
|
|
275
|
+
// Data-URI `img` rendering keeps requester-supplied SVG inert (no scripts).
|
|
276
|
+
const src = request.logo
|
|
277
|
+
? `data:image/svg+xml;utf8,${encodeURIComponent(request.logo)}`
|
|
278
|
+
: request.logoUri
|
|
279
|
+
if (src && !failed)
|
|
280
|
+
return (
|
|
281
|
+
<img
|
|
282
|
+
alt=""
|
|
283
|
+
className="size-8 shrink-0 rounded-full bg-secondary"
|
|
284
|
+
onError={() => setFailed(true)}
|
|
285
|
+
src={src}
|
|
286
|
+
title={request.logo ? 'Uploaded SVG' : request.logoUri}
|
|
287
|
+
/>
|
|
288
|
+
)
|
|
289
|
+
return (
|
|
290
|
+
<div className="flex size-8 shrink-0 items-center justify-center rounded-full bg-secondary text-label-12 text-foreground-secondary">
|
|
291
|
+
{request.symbol.slice(0, 2).toUpperCase()}
|
|
292
|
+
</div>
|
|
293
|
+
)
|
|
294
|
+
}
|
|
295
|
+
|
|
85
296
|
function ChainSelect(props: {
|
|
86
297
|
className?: string
|
|
87
298
|
onChange: (chain: ChainId) => void
|