Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 39 additions & 18 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,21 @@ jobs:
platform_name: Windows (ARM)
build: 'pnpm tauri build --target aarch64-pc-windows-msvc'
- platform: 'macos-26'
platform_name: iOS
build: 'pnpm tauri ios build --export-method app-store-connect'
build_dev: 'pnpm tauri ios build --export-method debugging'
platform_name: iOS (TestFlight)
platform_type: iOS
build: 'pnpm tauri ios build --export-method app-store-connect --build-number 1'
disable_offers: 'false'
disable_options: 'false'
disable_swap: 'false'
ipa_name: Sage_TestFlight
- platform: 'macos-26'
platform_name: iOS (App Store)
platform_type: iOS
build: 'pnpm tauri ios build --export-method app-store-connect --build-number 2'
Comment thread
Rigidity marked this conversation as resolved.
disable_offers: 'true'
disable_options: 'true'
disable_swap: 'true'
ipa_name: Sage_AppStore
- platform: 'macos-15'
platform_name: Android
build: 'pnpm tauri android build'
Expand All @@ -90,7 +102,7 @@ jobs:
run: rustup target add x86_64-apple-darwin

- name: Add aarch64-apple-ios
if: matrix.platform_name == 'iOS'
if: matrix.platform_type == 'iOS'
run: rustup target add aarch64-apple-ios

- name: Add aarch64-pc-windows-msvc
Expand Down Expand Up @@ -150,19 +162,19 @@ jobs:
run: pnpm install

- name: Save API key to file
if: matrix.platform_name == 'MacOS' || matrix.platform_name == 'iOS'
if: matrix.platform_name == 'MacOS' || matrix.platform_type == 'iOS'
run: |
mkdir -p ~/private_keys
echo -n '${{ secrets.APPLE_API_SECRET_KEY }}' > ~/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8

- name: Setup Xcode
if: matrix.platform_name == 'iOS'
if: matrix.platform_type == 'iOS'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '26.5'

- name: Verify Xcode SDK
if: matrix.platform_name == 'iOS'
if: matrix.platform_type == 'iOS'
run: |
xcodebuild -version
xcrun --sdk iphoneos --show-sdk-version
Expand All @@ -173,16 +185,25 @@ jobs:
# On MacOS we only notarize on tagged releases
# On iOS we need these secrets as well to do code signing
- name: Build with secrets
if: ${{ (matrix.platform_name == 'MacOS' && startsWith(github.event.ref, 'refs/tags/v')) || matrix.platform_name == 'iOS' }}
run: ${{ startsWith(github.event.ref, 'refs/tags/v') && matrix.build || matrix.build_dev || matrix.build }}
if: ${{ (matrix.platform_name == 'MacOS' && startsWith(github.event.ref, 'refs/tags/v')) || matrix.platform_type == 'iOS' }}
run: ${{ matrix.build }}
Comment thread
Rigidity marked this conversation as resolved.
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_KEY_PATH: ~/private_keys/AuthKey_${{ secrets.APPLE_API_KEY_ID }}.p8
VITE_DISABLE_OFFERS: ${{ matrix.disable_offers }}
VITE_DISABLE_OPTIONS: ${{ matrix.disable_options }}
VITE_DISABLE_SWAP: ${{ matrix.disable_swap }}
CI: true

- name: Preserve iOS IPA
if: matrix.platform_type == 'iOS'
run: |
mkdir -p artifacts/ios
cp src-tauri/gen/apple/build/arm64/Sage.ipa "artifacts/ios/${{ matrix.ipa_name }}.ipa"

# On Android we need to use the NDK environment variables.
- name: Build with NDK
if: matrix.platform_name == 'Android'
Expand All @@ -195,7 +216,7 @@ jobs:

# We don't currently do signing on other platforms
- name: Build without secrets
if: ${{ !((matrix.platform_name == 'MacOS' && startsWith(github.event.ref, 'refs/tags/v')) || matrix.platform_name == 'iOS' || matrix.platform_name == 'Android') }}
if: ${{ !((matrix.platform_name == 'MacOS' && startsWith(github.event.ref, 'refs/tags/v')) || matrix.platform_type == 'iOS' || matrix.platform_name == 'Android') }}
run: ${{ matrix.build }}
env:
CI: true
Expand Down Expand Up @@ -334,21 +355,21 @@ jobs:
# iOS
- name: Upload IPA (iOS)
uses: actions/upload-artifact@v4
if: matrix.platform_name == 'iOS'
if: matrix.platform_type == 'iOS'
with:
name: Sage_iOS.ipa
path: src-tauri/gen/apple/build/arm64/*.ipa
name: ${{ matrix.ipa_name }}.ipa
path: artifacts/ios/${{ matrix.ipa_name }}.ipa

- name: Release (iOS)
uses: softprops/action-gh-release@v2
if: matrix.platform_name == 'iOS' && startsWith(github.event.ref, 'refs/tags/v')
if: matrix.platform_type == 'iOS' && startsWith(github.event.ref, 'refs/tags/v')
with:
files: |
src-tauri/gen/apple/build/arm64/*.ipa
artifacts/ios/${{ matrix.ipa_name }}.ipa

- name: Upload to App Store (or TestFlight)
if: matrix.platform_name == 'iOS' && startsWith(github.event.ref, 'refs/tags/v')
run: xcrun altool --upload-app --type ios --file "src-tauri/gen/apple/build/arm64/Sage.ipa" --apiKey $APPLE_API_KEY_ID --apiIssuer $APPLE_API_ISSUER
- name: Upload iOS build to App Store Connect
if: matrix.platform_type == 'iOS' && startsWith(github.event.ref, 'refs/tags/v')
run: xcrun altool --upload-app --type ios --file "artifacts/ios/${{ matrix.ipa_name }}.ipa" --apiKey $APPLE_API_KEY_ID --apiIssuer $APPLE_API_ISSUER
env:
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
Expand Down
9 changes: 2 additions & 7 deletions crates/sage-wallet/src/wallet/offer/take_offer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,8 @@ impl Wallet {
.iter()
.map(|coin_spend| coin_spend.coin.coin_id())
.collect_vec();
self.select_spends_excluding(
&mut ctx,
&mut spends,
&actions,
&offer_input_coin_ids,
)
.await?;
self.select_spends_excluding(&mut ctx, &mut spends, &actions, &offer_input_coin_ids)
.await?;

// Reset DIDs and reveal trade prices
let mut royalty_nft_count = 0;
Expand Down
5 changes: 4 additions & 1 deletion src/components/CoinList.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { offersEnabled } from '@/lib/features';
import { spacescanCoinUrl } from '@/lib/urls';
import { formatTimestamp, fromMojos } from '@/lib/utils';
import { t } from '@lingui/core/macro';
Expand Down Expand Up @@ -334,7 +335,9 @@ const SpentCell = ({ row }: { row: Row<CoinRecord> }) =>
: row.original.transaction_id
? t`Pending...`
: row.original.offer_id
? t`Locked in offer`
? offersEnabled
? t`Locked in offer`
: t`Locked`
: '';

// Wrapper components to eliminate remaining inline arrow functions
Expand Down
79 changes: 42 additions & 37 deletions src/components/MultiSelectActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { commands, NftRecord, TransactionResponse } from '@/bindings';
import { CustomError } from '@/contexts/ErrorContext';
import { useErrors } from '@/hooks/useErrors';
import useOfferStateWithDefault from '@/hooks/useOfferStateWithDefault';
import { offersEnabled } from '@/lib/features';
import { toMojos } from '@/lib/utils';
import { useWalletState } from '@/state';
import { t } from '@lingui/core/macro';
Expand Down Expand Up @@ -242,50 +243,54 @@ export function MultiSelectActions({
</span>
</DropdownMenuItem>

<DropdownMenuSeparator />
{offersEnabled && (
<>
<DropdownMenuSeparator />

<DropdownMenuItem
className='cursor-pointer'
onClick={(e) => {
e.stopPropagation();
<DropdownMenuItem
className='cursor-pointer'
onClick={(e) => {
e.stopPropagation();

const newNfts = [...offerState.offered.nfts];
let addedCount = 0;
const newNfts = [...offerState.offered.nfts];
let addedCount = 0;

for (const item of selected) {
if (newNfts.includes(item)) {
continue;
}
for (const item of selected) {
if (newNfts.includes(item)) {
continue;
}

newNfts.push(item);
addedCount++;
}
newNfts.push(item);
addedCount++;
}

setOfferState({
offered: {
...offerState.offered,
nfts: newNfts,
},
});
setOfferState({
offered: {
...offerState.offered,
nfts: newNfts,
},
});

const nfts = addedCount === 1 ? t`NFT` : t`NFTs`;
const message =
addedCount > 0
? t`Added ${addedCount} ${nfts} to offer`
: t`Selected NFTs are already in the offer`;
toast.success(message, {
onClick: () => navigate('/offers/make'),
});
const nfts = addedCount === 1 ? t`NFT` : t`NFTs`;
const message =
addedCount > 0
? t`Added ${addedCount} ${nfts} to offer`
: t`Selected NFTs are already in the offer`;
toast.success(message, {
onClick: () => navigate('/offers/make'),
});

onConfirm();
}}
aria-label={t`Add ${selectedCount} selected NFTs to offer`}
>
<HandCoins className='mr-2 h-4 w-4' aria-hidden='true' />
<span>
<Trans>Add to Offer</Trans>
</span>
</DropdownMenuItem>
onConfirm();
}}
aria-label={t`Add ${selectedCount} selected NFTs to offer`}
>
<HandCoins className='mr-2 h-4 w-4' aria-hidden='true' />
<span>
<Trans>Add to Offer</Trans>
</span>
</DropdownMenuItem>
</>
)}
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
Expand Down
24 changes: 12 additions & 12 deletions src/components/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import {
TooltipTrigger,
} from '@/components/ui/tooltip';
import { usePeers } from '@/hooks/usePeers';
import { offersEnabled, optionsEnabled, swapEnabled } from '@/lib/features';
import { logoutAndUpdateState, useWalletState } from '@/state';
import { t } from '@lingui/core/macro';
import { Trans } from '@lingui/react/macro';
import { platform } from '@tauri-apps/plugin-os';
import {
ArrowDownUp,
ArrowLeftRight,
Expand All @@ -33,8 +33,6 @@ interface NavProps {
export function TopNav({ isCollapsed }: NavProps) {
const className = isCollapsed ? 'h-5 w-5' : 'h-4 w-4';

const isIos = platform() === 'ios';

return (
<nav
className={`grid font-medium font-body ${isCollapsed ? 'gap-1' : ''}`}
Expand Down Expand Up @@ -68,7 +66,7 @@ export function TopNav({ isCollapsed }: NavProps) {
<SquareUserRound className={className} aria-hidden='true' />
</NavLink>

{!isIos && (
Comment thread
cursor[bot] marked this conversation as resolved.
{optionsEnabled && (
<NavLink
url={'/options'}
isCollapsed={isCollapsed}
Expand All @@ -78,15 +76,17 @@ export function TopNav({ isCollapsed }: NavProps) {
</NavLink>
)}

<NavLink
url={'/offers'}
isCollapsed={isCollapsed}
message={<Trans>Offers</Trans>}
>
<Handshake className={className} aria-hidden='true' />
</NavLink>
{offersEnabled && (
<NavLink
url={'/offers'}
isCollapsed={isCollapsed}
message={<Trans>Offers</Trans>}
>
<Handshake className={className} aria-hidden='true' />
</NavLink>
)}
Comment thread
cursor[bot] marked this conversation as resolved.

{!isIos && (
{swapEnabled && (
<NavLink
url={'/swap'}
isCollapsed={isCollapsed}
Expand Down
Loading
Loading