diff --git a/bskyweb/cmd/bskyweb/invitepass.go b/bskyweb/cmd/bskyweb/invitepass.go
index 51dd7943dd..7b17d2de66 100644
--- a/bskyweb/cmd/bskyweb/invitepass.go
+++ b/bskyweb/cmd/bskyweb/invitepass.go
@@ -220,12 +220,15 @@ func (srv *Server) WebInviteWalletHero(c echo.Context) error {
}
func (srv *Server) buildPassAssets(theme, handle string, avatarBytes []byte) ([]PassAsset, error) {
- icon1, err := readFS(srv.cfg.InvitePass.StripFS, "passes/"+theme+"/icon.png")
- if err != nil {
- return nil, fmt.Errorf("icon: %w", err)
+ _ = theme
+ // Icons are shared across themes (matches the Pass Designer layout - the
+ // pass.json hardcodes one backgroundColor + one background image).
+ icon1, _ := readFS(srv.cfg.InvitePass.StripFS, "passes/icon.png")
+ icon2, _ := readFS(srv.cfg.InvitePass.StripFS, "passes/icon@2x.png")
+ icon3, _ := readFS(srv.cfg.InvitePass.StripFS, "passes/icon@3x.png")
+ if len(icon1) == 0 && len(icon2) == 0 && len(icon3) == 0 {
+ return nil, fmt.Errorf("icon: no icon asset found at any density")
}
- icon2, _ := readFS(srv.cfg.InvitePass.StripFS, "passes/"+theme+"/icon@2x.png")
- icon3, _ := readFS(srv.cfg.InvitePass.StripFS, "passes/"+theme+"/icon@3x.png")
logo1, err := readFS(srv.cfg.InvitePass.StripFS, "passes/logo.png")
if err != nil {
return nil, fmt.Errorf("logo: %w", err)
@@ -247,9 +250,11 @@ func (srv *Server) buildPassAssets(theme, handle string, avatarBytes []byte) ([]
_ = avatarBytes
assets := []PassAsset{
- {Name: "icon.png", Data: icon1},
{Name: "logo.png", Data: logo1},
}
+ if len(icon1) > 0 {
+ assets = append(assets, PassAsset{Name: "icon.png", Data: icon1})
+ }
if len(icon2) > 0 {
assets = append(assets, PassAsset{Name: "icon@2x.png", Data: icon2})
}
diff --git a/src/features/inviteFriends/InviteFriendsDialogInner.tsx b/src/features/inviteFriends/InviteFriendsDialogInner.tsx
index a1c2f0c867..65348c4e0a 100644
--- a/src/features/inviteFriends/InviteFriendsDialogInner.tsx
+++ b/src/features/inviteFriends/InviteFriendsDialogInner.tsx
@@ -203,7 +203,7 @@ export function InviteFriendsDialogInner({
{isHandleValid && handle ? (
-
+
) : null}
diff --git a/src/features/inviteFriends/components/AddToWalletButton.test.tsx b/src/features/inviteFriends/components/AddToWalletButton.test.tsx
index 7aa2608c2f..02e0745e17 100644
--- a/src/features/inviteFriends/components/AddToWalletButton.test.tsx
+++ b/src/features/inviteFriends/components/AddToWalletButton.test.tsx
@@ -85,9 +85,7 @@ afterEach(async () => {
// Test 1: IS_WEB gate
test('renders null on web', async () => {
mockIsWeb = true
- const {toJSON} = render(
- ,
- )
+ const {toJSON} = render()
// Flush effects - with IS_WEB=true the canAddPasses effect exits early,
// so the flush is just a guard.
await act(async () => {})
@@ -97,9 +95,7 @@ test('renders null on web', async () => {
// Test 2: canAddPasses gate
test('renders null when canAddPasses() resolves false', async () => {
RNWallet.canAddPasses.mockResolvedValue(false)
- const {toJSON} = render(
- ,
- )
+ const {toJSON} = render()
await waitFor(() => expect(RNWallet.canAddPasses).toHaveBeenCalled())
// Flush promise resolution so setCanAdd(false) runs inside act
await act(async () => {})
@@ -108,9 +104,7 @@ test('renders null when canAddPasses() resolves false', async () => {
// Test 3: handle sentinel gate
test('renders null when handle is invalid', async () => {
- const {toJSON} = render(
- ,
- )
+ const {toJSON} = render()
// handle is invalid so canAddPasses is not called; flush anyway for safety
await act(async () => {})
expect(toJSON()).toBeNull()
@@ -118,7 +112,7 @@ test('renders null when handle is invalid', async () => {
// Test 4: empty handle gate
test('renders null when handle is empty', async () => {
- const {toJSON} = render()
+ const {toJSON} = render()
await act(async () => {})
expect(toJSON()).toBeNull()
})
@@ -133,7 +127,7 @@ test('iOS: mints token then calls addPass with the returned URL', async () => {
}),
})
const {UNSAFE_getByType} = render(
- ,
+ ,
)
await waitFor(() =>
UNSAFE_getByType('RNWalletView' as unknown as ComponentType),
@@ -159,9 +153,7 @@ test('iOS: mints token then calls addPass with the returned URL', async () => {
// Test 6: Android is gated out for iOS-only launch (Google Wallet backend not provisioned)
test('Android: renders null until Google Wallet backend is wired', () => {
;(Platform as {OS: string}).OS = 'android'
- const {toJSON} = render(
- ,
- )
+ const {toJSON} = render()
expect(toJSON()).toBeNull()
})
@@ -178,7 +170,7 @@ test('addPass throws – error toast and logger.error are called', async () => {
const {logger} = require('#/logger')
const loggerSpy = jest.spyOn(logger, 'error')
const {UNSAFE_getByType} = render(
- ,
+ ,
)
await waitFor(() =>
UNSAFE_getByType('RNWalletView' as unknown as ComponentType),
diff --git a/src/features/inviteFriends/components/AddToWalletButton.tsx b/src/features/inviteFriends/components/AddToWalletButton.tsx
index f1eca8a186..480d0f0890 100644
--- a/src/features/inviteFriends/components/AddToWalletButton.tsx
+++ b/src/features/inviteFriends/components/AddToWalletButton.tsx
@@ -8,17 +8,10 @@ import {useAgent} from '#/state/session'
import * as Toast from '#/components/Toast'
import {useAnalytics} from '#/analytics'
import {IS_WEB} from '#/env'
-import {type InviteThemeKey} from '../themes'
const BSKY_WEB = 'https://bsky.app'
-export function AddToWalletButton({
- themeKey,
- handle,
-}: {
- themeKey: InviteThemeKey
- handle: string
-}) {
+export function AddToWalletButton({handle}: {handle: string}) {
const {t: l} = useLingui()
const ax = useAnalytics()
const agent = useAgent()
@@ -64,16 +57,15 @@ export function AddToWalletButton({
Authorization: `Bearer ${accessJwt}`,
'Content-Type': 'application/json',
},
- body: JSON.stringify({theme: themeKey}),
+ body: JSON.stringify({}),
})
if (!res.ok) throw new Error(`pass.url ${res.status}`)
const {url} = (await res.json()) as {url: string}
added = await RNWallet.addPass(url)
} else {
- const res = await fetch(
- `${BSKY_WEB}/invite/wallet/jwt?theme=${themeKey}`,
- {headers: {Authorization: `Bearer ${accessJwt}`}},
- )
+ const res = await fetch(`${BSKY_WEB}/invite/wallet/jwt`, {
+ headers: {Authorization: `Bearer ${accessJwt}`},
+ })
if (!res.ok) throw new Error(`wallet/jwt ${res.status}`)
const {jwt} = (await res.json()) as {jwt: string}
added = await RNWallet.addPassWithSignedJwt(jwt)