Skip to content
Merged
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
7 changes: 6 additions & 1 deletion .github/workflows/api-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,14 @@ jobs:
- name: Wait for DEV deployment
timeout-minutes: 15
run: |
EXPECTED=$(curl -s https://api.github.com/repos/${{ github.repository }}/commits/develop | jq -r '.sha')
EXPECTED=${{ github.event.pull_request.head.sha }}
echo "Expected commit: $EXPECTED"

if [ -z "$EXPECTED" ] || [ "$EXPECTED" == "null" ]; then
echo "::error::Could not determine expected commit SHA"
exit 1
fi

for i in {1..30}; do
if RESPONSE=$(curl -sf ${{ env.DEV_API_URL }}/version 2>&1); then
ACTUAL=$(echo "$RESPONSE" | jq -r '.commit')
Expand Down
24 changes: 18 additions & 6 deletions src/integration/blockchain/spark/spark-client.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { SparkWallet } from '@buildonspark/spark-sdk';
import { Injectable } from '@nestjs/common';
import { Currency } from '@uniswap/sdk-core';
import { GetConfig } from 'src/config/config';
import { DfxLogger } from 'src/shared/services/dfx-logger';
import { AsyncField } from 'src/shared/utils/async-field';
import { BlockchainTokenBalance } from '../shared/dto/blockchain-token-balance.dto';
import { BlockchainClient } from '../shared/util/blockchain-client';
Expand Down Expand Up @@ -43,10 +41,7 @@ export interface SparkFeeEstimate {
blocks: number;
}

@Injectable()
export class SparkClient extends BlockchainClient {
private readonly logger = new DfxLogger(SparkClient);

private readonly wallet: AsyncField<SparkWallet>;
private readonly cachedAddress: AsyncField<string>;

Expand All @@ -58,7 +53,7 @@ export class SparkClient extends BlockchainClient {
mnemonicOrSeed: GetConfig().blockchain.spark.sparkWalletSeed,
accountNumber: 0,
options: { network: 'MAINNET' },
}).then((r) => r.wallet),
}).then(({ wallet }) => this.syncLeaves(wallet)),
);
this.cachedAddress = new AsyncField(() => this.wallet.then((w) => w.getSparkAddress()), true);
}
Expand All @@ -72,6 +67,8 @@ export class SparkClient extends BlockchainClient {
async sendTransaction(to: string, amount: number): Promise<{ txid: string; fee: number }> {
const wallet = await this.wallet;

await this.syncLeaves(wallet);

const amountSats = Math.round(amount * 1e8);

const result = await wallet.transfer({
Expand Down Expand Up @@ -128,6 +125,19 @@ export class SparkClient extends BlockchainClient {
);
}

// --- SYNC METHODS --- //

private async syncLeaves(wallet: SparkWallet): Promise<SparkWallet> {
// SDK bug: internal this.leaves cache is not synced on initialization or after deposits
// optimizeLeaves() fetches fresh leaves from network and updates the cache at the start,
// even when no optimization swaps are needed - consume generator to trigger sync
for await (const _ of wallet.optimizeLeaves()) {
/* Consume generator - sync happens at generator start */
}

return wallet;
}

// --- FEE METHODS (always 0 for Spark L2) --- //

async getNativeFee(): Promise<number> {
Expand All @@ -154,6 +164,8 @@ export class SparkClient extends BlockchainClient {
async getNativeCoinBalance(): Promise<number> {
const wallet = await this.wallet;

await this.syncLeaves(wallet);

const { balance } = await wallet.getBalance();

return Number(balance) / 1e8;
Expand Down
Loading