tangem_sdk 0.7.0 copy "tangem_sdk: ^0.7.0" to clipboard
tangem_sdk: ^0.7.0 copied to clipboard

PlatformAndroidiOS
outdated

A new flutter plugin project.

example/lib/main.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:tangem_sdk/tangem_sdk.dart';
import 'package:tangem_sdk_example/app_widgets.dart';
import 'package:tangem_sdk_example/utils.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Tangem SDK plugin example')),
        body: CommandListWidget(),
      ),
    );
  }
}

class CommandListWidget extends StatefulWidget {
  @override
  _CommandListWidgetState createState() => _CommandListWidgetState();
}

class _CommandListWidgetState extends State<CommandListWidget> {
  final Utils _utils = Utils();
  final _jsonEncoder = JsonEncoder.withIndent('  ');

  String? _cardId;
  String? _walletPublicKey;
  String _response = "";
  final _controller = TextEditingController();

  @override
  void initState() {
    super.initState();

    _controller.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          SizedBox(height: 25),
          RowActions(
            [
              ActionButton("Scan card", _handleScanCard),
              ActionButton("Sign hash", _handleSign),
            ],
          ),
          ActionType("Wallet"),
          RowActions(
            [
              ActionButton("Create", _handleCreateWallet),
              ActionButton("Purge", _handlePurgeWallet),
            ],
          ),
          ActionType("Pins"),
          RowActions(
            [
              ActionButton("Set access code", _handleSetAccessCode),
              ActionButton("Set passcode", _handleSetPasscode),
            ],
          ),
          SizedBox(height: 5),
          Divider(),
          ActionType("JSONRRPC"),
          Container(
            padding: EdgeInsets.symmetric(horizontal: 16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                SizedBox(height: 5),
                TextField(
                  decoration: InputDecoration(
                    contentPadding: EdgeInsets.fromLTRB(0, 0, 0, 5),
                    labelText: "Paste the configuration",
                    isDense: true,
                  ),
                  minLines: 1,
                  maxLines: 25,
                  controller: _controller,
                ),
                SizedBox(height: 15),
                Row(
                  children: [
                    OutlinedButton(
                        onPressed: () async {
                          final data = await Clipboard.getData(Clipboard.kTextPlain);
                          final textData = data?.text ?? "";
                          if (textData.isEmpty) return;

                          _controller.value = TextEditingValue(text: textData);
                        },
                        child: Icon(Icons.paste)),
                    SizedBox(width: 8),
                    Expanded(
                      child: OutlinedButton(
                        child: Text("Launch"),
                        onPressed: _controller.text.isEmpty ? null : () => _handleJsonRpc(_controller.text),
                      ),
                    )
                  ],
                ),
              ],
            ),
          ),
          Divider(),
          ActionType("RESULT"),
          Text(_response),
        ],
      ),
    );
  }

  void _handleScanCard() {
    final json = {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "scan",
      "params": <String, dynamic>{},
    };
    _launchJSONRPCRequest(json);
  }

  void _handleSign() {
    if (_cardId == null || _walletPublicKey == null) {
      _showToast("Scan the card or create a wallet");
      return;
    }

    final json = {
      "method": "sign_hash",
      "jsonrpc": "2.0",
      "params": <String, dynamic>{
        "walletPublicKey": _walletPublicKey,
        "hash": "f1642bb080e1f320924dde7238c1c5f8",
      },
    };
    _launchJSONRPCRequest(json, _cardId);
  }

  void _handleCreateWallet() {
    if (_cardId == null) {
      _showToast("Scan the card");
      return;
    }

    _showToast("Only for: Secp256k1");
    final json = {
      "id": 3,
      "jsonrpc": "2.0",
      "method": "create_wallet",
      "params": <String, dynamic>{
        "curve": "Secp256k1",
      },
    };
    _launchJSONRPCRequest(json, _cardId);
  }

  void _handlePurgeWallet() {
    if (_cardId == null || _walletPublicKey == null) {
      _showToast("Scan the card or create a wallet");
      return;
    }

    final json = {
      "id": 4,
      "jsonrpc": "2.0",
      "method": "purge_wallet",
      "params": <String, dynamic>{
        "walletPublicKey": _walletPublicKey,
      },
    };
    _launchJSONRPCRequest(json, _cardId);
  }

  void _handleSetAccessCode() {
    if (_cardId == null) {
      _showToast("Scan the card");
      return;
    }

    final json = {
      "jsonrpc": "2.0",
      "method": "set_accesscode",
      "params": <String, dynamic>{"accessCode": "ABCDEFGH"},
    };
    _launchJSONRPCRequest(json, _cardId);
  }

  void _handleSetPasscode() {
    if (_cardId == null) {
      _showToast("Scan the card");
      return;
    }

    final json = {
      "jsonrpc": "2.0",
      "method": "set_passcode",
      "params": <String, dynamic>{"passcode": "ABCDEFGH"},
    };
    _launchJSONRPCRequest(json, _cardId);
  }

  void _handleJsonRpc(String text) {
    _launchJSONRPCRequest(text.trim(), null, null);
  }

  void _launchJSONRPCRequest(dynamic requestStructure, [String? cardId, Message? message]) {
    String? request;
    if (requestStructure is String) {
      request = requestStructure;
    } else if (requestStructure is Map<String, dynamic>) {
      request = jsonEncode(JSONRPCRequest.fromJson(requestStructure));
    } else if (requestStructure is List) {
      final requests = requestStructure.map((e) => JSONRPCRequest.fromJson(e)).toList();
      request = jsonEncode(requests);
    }

    if (request == null) {
      _showToast("Can't recognize the request structure");
      return;
    }

    final callback = Callback((success) {
      final decodedResponse = jsonDecode(success);
      _printResponse(decodedResponse);
      _parseResponse(decodedResponse);
    }, (error) {
      // it is not expected
    });

    TangemSdk.runJSONRPCRequest(callback, request, cardId, message);
  }

  void _printResponse(Object decodedResponse) {
    final prettyJson = _jsonEncoder.convert(decodedResponse);
    prettyJson.split("\n").forEach((element) => print(element));

    setState(() {
      _response = prettyJson;
    });
  }

  void _parseResponse(Object decodedResponse) {
    if (decodedResponse is List || decodedResponse is! Map<String, dynamic>) return;

    JSONRPCResponse jsonRpcResponse;
    try {
      jsonRpcResponse = JSONRPCResponse.fromJson(decodedResponse);
    } catch (ex) {
      print(ex.toString());
      return;
    }

    if (jsonRpcResponse.result != null) {
      switch (jsonRpcResponse.id) {
        case 1:
          {
            _cardId = jsonRpcResponse.result["cardId"];
            final wallets = jsonRpcResponse.result["wallets"];
            if (wallets is List && wallets.isNotEmpty) {
              _walletPublicKey = wallets[0]["publicKey"];
            }
            break;
          }
        case 3:
          {
            _walletPublicKey = jsonRpcResponse.result["wallet"]["publicKey"];
            break;
          }
        case 4:
          {
            _walletPublicKey = null;
            break;
          }
      }
    }
  }

  _showToast(String message) {
    Fluttertoast.showToast(
      msg: message,
      gravity: ToastGravity.BOTTOM,
      backgroundColor: Colors.black.withOpacity(0.8),
      toastLength: Toast.LENGTH_LONG,
    );
  }
}
0
likes
100
pub points
10%
popularity

Publisher

unverified uploader

A new flutter plugin project.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

convert, flutter, json_annotation

More

Packages that depend on tangem_sdk