dynamic_sdk_fireblocks_flow 1.17.0 copy "dynamic_sdk_fireblocks_flow: ^1.17.0" to clipboard
dynamic_sdk_fireblocks_flow: ^1.17.0 copied to clipboard

Dynamic SDK Fireblocks Flow API client (attach source, quote, prepare signing, broadcast, flow status).

Dynamic SDK Fireblocks Flow #

Client-side implementation of the Dynamic Fireblocks Flow API — drives a payment/deposit/withdraw flow through its client-side steps: attachSource, getQuote, prepareSigning, broadcast, and getFlow.

The Flow session token (dft_...) returned by attachSource is persisted automatically to secure storage (flutter_secure_storage), keyed by flow ID, and reused for every subsequent call on that flow — including after the app is killed and restarted.

Deliberately out of scope:

  • Create Flow (POST /server/{environmentId}/flow/{mode}) requires an Authorization: Bearer dyn_... API token with flow.write scope. That's a backend-only credential — create the flow from your server, then hand the resulting flowId to the client.
  • Sign and Broadcast (step 5) isn't an API call. Sign the signingPayload returned by prepareSigning with the source wallet's own signer (see the dynamic_sdk/dynamic_sdk_web3dart/dynamic_sdk_solana packages), submit it to the chain yourself, then report the resulting hash via broadcast.

Full Example #

1. Initialize the SDK #

// main.dart
import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  DynamicSDK.init(
    props: ClientProps(
      environmentId: 'YOUR_ENVIRONMENT_ID',
      appName: 'Your App Name',
      redirectUrl: 'yourapp://',
    ),
  );
  runApp(const MyApp());
}

2. Drive a flow created by your backend #

Your backend creates the flow (POST /server/{environmentId}/flow/{mode}) and gives the client a flowId. From there:

import 'package:dynamic_sdk/dynamic_sdk.dart';
import 'package:dynamic_sdk_fireblocks_flow/dynamic_sdk_fireblocks_flow.dart';

Future<void> runFlow(String flowId, BaseWallet wallet) async {
  final flow = DynamicSDK.instance.fireblocksFlow;

  // Step 2 -- attach the paying wallet. The session token this returns is
  // persisted to secure storage automatically; you never handle it directly.
  final attached = await flow.attachSource(
    flowId: flowId,
    request: AttachSourceRequest(
      sourceType: FlowSourceType.wallet,
      fromAddress: wallet.address,
      fromChainId: '1',
      fromChainName: ChainEnum.evm,
    ),
  );

  // Step 3 -- get a quote. Quotes expire 60 seconds after issuance.
  final quoted = await flow.getQuote(
    flowId: flowId,
    request: const GetQuoteRequest(fromTokenAddress: '0x...'),
  );

  // Step 4 -- prepare the unsigned payload for the source chain.
  final prepared = await flow.prepareSigning(flowId: flowId);

  // Step 5 -- sign `prepared.signingPayload` with the source wallet's own
  // signer and broadcast it to the chain yourself (this package does not do
  // this step). For an EVM source, for example, map the fields of
  // `prepared.signingPayload.evmTransaction` onto a web3dart `Transaction`
  // and send it with `DynamicSDK.instance.web3dart.sendTransaction(...)`;
  // for SOL/SUI, sign+send `serializedTransaction` with `dynamic_sdk_solana`
  // (or the SUI signer); for BTC, sign the `psbt`.
  // `signAndBroadcast` is your own app code -- not part of this package.
  final txHash = await signAndBroadcast(prepared.signingPayload, wallet);

  // Step 6 -- report the resulting transaction hash.
  await flow.broadcast(
    flowId: flowId,
    request: BroadcastRequest(txHash: txHash),
  );

  // Step 7 -- poll until settled. This call needs no session token, so it
  // also works after an app restart to resume tracking an in-flight flow.
  var status = await flow.getFlow(flowId: flowId);
  while (status.settlementState != FlowSettlementState.completed &&
      status.settlementState != FlowSettlementState.failed) {
    await Future.delayed(const Duration(seconds: 3));
    status = await flow.getFlow(flowId: flowId);
  }
}

3. Resuming after an app restart #

Because the session token is persisted per flowId, tracking an in-flight flow after the app was killed just means calling getFlow() again — no re-attach needed unless the token has actually expired:

final status = await DynamicSDK.instance.fireblocksFlow.getFlow(flowId: flowId);

If a later call (getQuote, prepareSigning, broadcast) throws a FireblocksFlowException with sessionTokenInvalid == true, the stored token has already been removed — call attachSource() again to obtain a new one.

0
likes
140
points
229
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Dynamic SDK Fireblocks Flow API client (attach source, quote, prepare signing, broadcast, flow status).

Homepage

License

MIT (license)

Dependencies

dynamic_sdk, flutter, flutter_secure_storage, freezed_annotation, http, json_annotation

More

Packages that depend on dynamic_sdk_fireblocks_flow