Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate extrinsic classes #315

Merged
merged 51 commits into from
Oct 31, 2023
Merged

Generate extrinsic classes #315

merged 51 commits into from
Oct 31, 2023

Conversation

leonardocustodio
Copy link
Owner

@leonardocustodio leonardocustodio commented Jul 11, 2023

Milestone

  • Implement Substrate's standard derivation format that applies to seeds and mnemonics.
  • Use Substrate's Bip39 password to encrypt/decrypt seeds and mnemonics.
  • Support Ed25519 signatures and key derivation
  • Sign and verify messages using ed25519 keypairs
  • Support substrate's signed extensions
  • Support transaction subscription
  • Support runtime event subscription
  • Create a package that manage a set of keys in a consistent environment
  • Utilities needed for signing, hash and encode/decode messages
  • Examples
  • Docs

Example:

  final Polkadot polkadot = Polkadot.url(Uri.parse('wss://rpc.polkadot.io'));
  final call = polkadot.tx.balances.transferAll(dest: 'dest', keepAlive: true)

Copy link
Collaborator

@Lohann Lohann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! remember to increment the package version and update the CHANGELOG.md with a description of the new features.

@kemalinnowise
Copy link

kemalinnowise commented Jul 26, 2023

If I'm allowed to ask guys just wondering if you about accept this PR when it might be merged ? I was seeking for a weeks for this sort of solution:)

@leonardocustodio
Copy link
Owner Author

leonardocustodio commented Jul 26, 2023

Hello @kemalinnowise , Right now it only generates an encoded call and the payload to sign. Is that enough for you? If so we can merge it already.
I'm still making the part where it signs the payload and constructs the whole extrinsic. I think it might be done by the weekend.

@kemalinnowise
Copy link

kemalinnowise commented Jul 26, 2023

Hello @kemalinnowise , Right now it only generates an encoded call and the payload to sign. Is that enough for you? If so we can merge it already.
I'm still making the part where it signs the payload and constructs the whole extrinsic. I think it might be done by the weekend.

Hi @leonardocustodio !
First of all let me express my gratitude. I really appreciate your impact!
This lib is awesome. No rush so far however looking forward to update cli with all those incredible new features!

@kemalinnowise
Copy link

@leonardocustodio Hi! Hope U doing well!
May I ask for update with one generates an encoded call and the payload to sign ?:) This week we start working on Extrinsics

@leonardocustodio
Copy link
Owner Author

leonardocustodio commented Aug 19, 2023

Hello @kemalinnowise, unfortunately I was not able to finish this yet. But you can use this branch directly and here is an example on how you can accomplish what you want (create signed extrinsics):

import 'package:convert/convert.dart';
import 'package:demo/generated/polkadot/polkadot.dart';
import 'package:polkadart/polkadart.dart';
import 'package:polkadart_keyring/polkadart_keyring.dart';

Future<void> main(List<String> arguments) async {
  final provider = Provider.fromUri(Uri.parse('wss://rpc.efinity.io'));
  final api = Polkadot(provider);

  final keyring = await Keyring.fromMnemonic(
      "toward disagree come neither clay priority bamboo chat tiny fabric damp aisle//0");
  final publicKey = hex.encode(keyring.publicKey.bytes);
  print('Public Key: $publicKey');
  // 4ea987928399dfe5b94bf7d37995850a21067bfa4549fa83b40250ee635fc064

  final call =
      '0a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f';
  final specVersion = 'c60b0000';
  final transactionVersion = '08000000';
  final genesisHash =
      '99ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a0';
  final blockHash =
      '99ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a0';
  final era = '00';
  final nonce = '28';
  final tip = '00';

  final payloadToSign = SigningPayload(
    method: call,
    specVersion: specVersion,
    transactionVersion: transactionVersion,
    genesisHash: genesisHash,
    blockHash: blockHash,
    era: era,
    nonce: nonce,
    tip: tip,
  );

  final payload = payloadToSign.encode(api.registry);
  print('Payload: ${hex.encode(payload)}');
  // 0x0a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f002800c60b00000800000099ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a099ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a0
  final anotherHexPayload = hex
      .encode(SigningPayload.createSigningPayload(payloadToSign, api.registry));
  print('Payload: $anotherHexPayload');

  final signature = keyring.sign(payload);
  final hexSignature = hex.encode(signature);
  print('Signature: $hexSignature');
  // d19e04fc1a4ec115ec55d29e53676ddaeae0467134f9513b29ed3cd6fd6cd551a96c35b92b867dfd08ba37417e5733620acc4ad17c1d7c65909d6edaaffd4d0e

  final extrinsic = Extrinsic(
          signer: publicKey,
          method: call,
          signature: hexSignature,
          era: era,
          nonce: nonce,
          tip: tip)
      .encode(api.registry);

  final hexExtrinsic = hex.encode(extrinsic);
  print('Extrinsic: $hexExtrinsic');
  // 2d0284006802f945419791d3138b4086aa0b2700abb679f950e2721fd7d65b5d1fdf8f0201d19e04fc1a4ec115ec55d29e53676ddaeae0467134f9513b29ed3cd6fd6cd551a96c35b92b867dfd08ba37417e5733620acc4ad17c1d7c65909d6edaaffd4d0e0028000a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f
}

Please note a few of those stuff were added to a helper method in this branch.
Also the call value is what you can get from final call = polkadot.tx.balances.transferAll(dest: 'dest', keepAlive: true)
Any doubts, let me know.

@kemalinnowise
Copy link

Hello @kemalinnowise, unfortunately I was not able to finish this yet. But you can use this branch directly and here is an example on how you can accomplish what you want (create signed extrinsics):

import 'package:convert/convert.dart';
import 'package:demo/generated/polkadot/polkadot.dart';
import 'package:polkadart/polkadart.dart';
import 'package:polkadart_keyring/polkadart_keyring.dart';

Future<void> main(List<String> arguments) async {
  final provider = Provider.fromUri(Uri.parse('wss://rpc.efinity.io'));
  final api = Polkadot(provider);

  final keyring = await Keyring.fromMnemonic(
      "toward disagree come neither clay priority bamboo chat tiny fabric damp aisle//0");
  final publicKey = hex.encode(keyring.publicKey.bytes);
  print('Public Key: $publicKey');
  // 4ea987928399dfe5b94bf7d37995850a21067bfa4549fa83b40250ee635fc064

  final call =
      '0a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f';
  final specVersion = 'c60b0000';
  final transactionVersion = '08000000';
  final genesisHash =
      '99ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a0';
  final blockHash =
      '99ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a0';
  final era = '00';
  final nonce = '28';
  final tip = '00';

  final payloadToSign = SigningPayload(
    method: call,
    specVersion: specVersion,
    transactionVersion: transactionVersion,
    genesisHash: genesisHash,
    blockHash: blockHash,
    era: era,
    nonce: nonce,
    tip: tip,
  );

  final payload = payloadToSign.encode(api.registry);
  print('Payload: ${hex.encode(payload)}');
  // 0x0a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f002800c60b00000800000099ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a099ded175d436bee7d751fa3f2f8c7a257ddc063a541f8daa5e6152604f66b2a0
  final anotherHexPayload = hex
      .encode(SigningPayload.createSigningPayload(payloadToSign, api.registry));
  print('Payload: $anotherHexPayload');

  final signature = keyring.sign(payload);
  final hexSignature = hex.encode(signature);
  print('Signature: $hexSignature');
  // d19e04fc1a4ec115ec55d29e53676ddaeae0467134f9513b29ed3cd6fd6cd551a96c35b92b867dfd08ba37417e5733620acc4ad17c1d7c65909d6edaaffd4d0e

  final extrinsic = Extrinsic(
          signer: publicKey,
          method: call,
          signature: hexSignature,
          era: era,
          nonce: nonce,
          tip: tip)
      .encode(api.registry);

  final hexExtrinsic = hex.encode(extrinsic);
  print('Extrinsic: $hexExtrinsic');
  // 2d0284006802f945419791d3138b4086aa0b2700abb679f950e2721fd7d65b5d1fdf8f0201d19e04fc1a4ec115ec55d29e53676ddaeae0467134f9513b29ed3cd6fd6cd551a96c35b92b867dfd08ba37417e5733620acc4ad17c1d7c65909d6edaaffd4d0e0028000a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f
}

Please note a few of those stuff were added to a helper method in this branch. Also the call value is what you can get from final call = polkadot.tx.balances.transferAll(dest: 'dest', keepAlive: true) Any doubts, let me know.

I appreciate your response!

@kemalinnowise
Copy link

Actually, I talked with my manager and he allowed me to help you. I just not good at substrate and blockchain. But this feature is critical in our project, so if you accept my help and ready to outsource some work to me, I'm ready.

@leonardocustodio
Copy link
Owner Author

Sure, that would be great. Can you check if you can make a fully working extrinsic first using the method above?

@kemalinnowise
Copy link

Screenshot 2023-08-23 at 14 39 45

I would love to check but for some reason neither case from picture above or others I've tried won't pull specific branch. Like pub get proceed fine but I can't see any package in

External Libraries -> Dart Packages

In case if need here is my -flutter doctor :

Details

[✓] Flutter (Channel stable, 3.13.0, on macOS 13.4 22F66 darwin-arm64, locale en-PL)
    • Flutter version 3.13.0 on channel stable at /Users/kemal/Documents/development/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision efbf63d9c6 (7 days ago), 2023-08-15 21:05:06 -0500
    • Engine revision 1ac611c64e
    • Dart version 3.1.0
    • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
    • Android SDK at /Users/kemal/Library/Android/sdk
    • Platform android-33, build-tools 33.0.2
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.12.0

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] VS Code (version 1.78.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.66.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.4 22F66 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 116.0.5845.96

[✓] Network resources
    • All expected network resources are available.

• No issues found!

@leonardocustodio
Copy link
Owner Author

My suggestion to import polkadart in your project at this moment would be clone the whole repository inside your project folder in a polkadart folder for example and import it this way

  substrate_metadata:
    path: polkadart/packages/substrate_metadata
  polkadart_scale_codec:
    path: polkadart/packages/polkadart_scale_codec

@kemalinnowise
Copy link

My suggestion to import polkadart in your project at this moment would be clone the whole repository inside your project folder in a polkadart folder for example and import it this way

  substrate_metadata:
    path: polkadart/packages/substrate_metadata
  polkadart_scale_codec:
    path: polkadart/packages/polkadart_scale_codec

I've tried specified approach however given errors won't allow me to proceed:

Because every version of substrate_metadata from path depends on polkadart_scale_codec from hosted and sandbox depends on polkadart_scale_codec from path, substrate_metadata from path is forbidden.
So, because sandbox depends on substrate_metadata from path, version solving failed.

Also I've tried to use various options depending on some of packages separately won't work as well

P.S. Is there any option to communicate with you via Discord or whatever for more convenience ?

@leonardocustodio
Copy link
Owner Author

Here is a demo project which you can use to learn how to setup. Please note you need melos installed. Also you might need to fix the directories in pubspec_overrides.yaml.

demo.zip

@kemalinnowise
Copy link

Hello!

I downloaded the demo project and configured the dependencies from the repository, everything run and works for me except for the generation in my projects pubcpec.yaml I use the following to generate Mychain instead Poladot:

image

So I've tried replace this lines in demo project with one from my project and run:

dart pub run polkadart_cli:generate -v

The command line throws given error:

➜  sandbox dart pub run polkadart_cli:generate -v
FINE: Pub 3.1.0
MSG : Deprecated. Use `dart run` instead.
FINE: Package Config up to date.
FINE: Package Config up to date.
MSG : Building package executable...
IO  : Created temp directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov
IO  : Copying "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill" to "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp".
IO  : Renaming "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp" to "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill".
IO  : Deleting directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov.
ERR : Failed to build polkadart_cli:generate:
    | ../../../.pub-cache/hosted/pub.dev/watcher-1.0.2/lib/src/constructable_file_system_event.dart:7:57: Error: The class 'FileSystemEvent' can't be extended, implemented, or mixed in outside of its library because it's a sealed class.
    | abstract class _ConstructableFileSystemEvent implements FileSystemEvent {
    |                                                         ^
FINE: Exception type: ApplicationException
FINE: package:pub/src/dart.dart 170:7                        precompile
    | ===== asynchronous gap ===========================
    | dart:async                                             Future.catchError
    | package:pub/src/utils.dart 155:21                      waitAndPrintErrors.<fn>
    | dart:async                                             Future.wait
    | package:pub/src/utils.dart 153:17                      waitAndPrintErrors
    | package:pub/src/entrypoint.dart 515:14                 Entrypoint.precompileExecutable.<fn>
    | package:pub/src/log.dart 437:18                        progress
    | package:pub/src/entrypoint.dart 513:15                 Entrypoint.precompileExecutable
    | package:pub/src/command/run.dart 107:26                RunCommand.runProtected.<fn>.<fn>
    | package:pub/src/log.dart 420:32                        errorsOnlyUnlessTerminal
    | package:pub/src/command/run.dart 106:38                RunCommand.runProtected.<fn>
    | package:pub/src/executable.dart 97:22                  runExecutable
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/executable.dart 79:24                  runExecutable
    | package:pub/src/command/run.dart 100:26                RunCommand.runProtected
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/command/run.dart 61:7                  RunCommand.runProtected
    | package:pub/src/command.dart 199:21                    PubCommand.run.<fn>
    | dart:async                                             new Future.sync
    | package:pub/src/utils.dart 114:12                      captureErrors.wrappedCallback
    | package:stack_trace                                    Chain.capture
    | package:pub/src/utils.dart 131:11                      captureErrors
    | package:pub/src/command.dart 198:13                    PubCommand.run
    | package:args/command_runner.dart 212:27                CommandRunner.runCommand
    | package:dartdev/dartdev.dart 240:30                    DartdevRunner.runCommand
    | package:args/command_runner.dart 122:25                CommandRunner.run.<fn>
    | dart:async                                             new Future.sync
    | package:args/command_runner.dart 122:14                CommandRunner.run
    | package:dartdev/dartdev.dart 59:29                     runDartdev
    | /opt/s/w/ir/x/w/sdk/pkg/dartdev/bin/dartdev.dart 11:9  main
FINE: Building package executable finished (0.644s).
---- Log transcript ----
FINE: Pub 3.1.0
MSG : Deprecated. Use `dart run` instead.
FINE: Package Config up to date.
FINE: Package Config up to date.
MSG : Building package executable...
IO  : Created temp directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov
IO  : Copying "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill" to "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp".
IO  : Renaming "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp" to "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill".
IO  : Deleting directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov.
ERR : Failed to build polkadart_cli:generate:
    | ../../../.pub-cache/hosted/pub.dev/watcher-1.0.2/lib/src/constructable_file_system_event.dart:7:57: Error: The class 'FileSystemEvent' can't be extended, implemented, or mixed in outside of its library because it's a sealed class.
    | abstract class _ConstructableFileSystemEvent implements FileSystemEvent {
    |                                                         ^
FINE: Exception type: ApplicationException
FINE: package:pub/src/dart.dart 170:7                        precompile
    | ===== asynchronous gap ===========================
    | dart:async                                             Future.catchError
    | package:pub/src/utils.dart 155:21                      waitAndPrintErrors.<fn>
    | dart:async                                             Future.wait
    | package:pub/src/utils.dart 153:17                      waitAndPrintErrors
    | package:pub/src/entrypoint.dart 515:14                 Entrypoint.precompileExecutable.<fn>
    | package:pub/src/log.dart 437:18                        progress
    | package:pub/src/entrypoint.dart 513:15                 Entrypoint.precompileExecutable
    | package:pub/src/command/run.dart 107:26                RunCommand.runProtected.<fn>.<fn>
    | package:pub/src/log.dart 420:32                        errorsOnlyUnlessTerminal
    | package:pub/src/command/run.dart 106:38                RunCommand.runProtected.<fn>
    | package:pub/src/executable.dart 97:22                  runExecutable
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/executable.dart 79:24                  runExecutable
    | package:pub/src/command/run.dart 100:26                RunCommand.runProtected
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/command/run.dart 61:7                  RunCommand.runProtected
    | package:pub/src/command.dart 199:21                    PubCommand.run.<fn>
    | dart:async                                             new Future.sync
    | package:pub/src/utils.dart 114:12                      captureErrors.wrappedCallback
    | package:stack_trace                                    Chain.capture
    | package:pub/src/utils.dart 131:11                      captureErrors
    | package:pub/src/command.dart 198:13                    PubCommand.run
    | package:args/command_runner.dart 212:27                CommandRunner.runCommand
    | package:dartdev/dartdev.dart 240:30                    DartdevRunner.runCommand
    | package:args/command_runner.dart 122:25                CommandRunner.run.<fn>
    | dart:async                                             new Future.sync
    | package:args/command_runner.dart 122:14                CommandRunner.run
    | package:dartdev/dartdev.dart 59:29                     runDartdev
    | /opt/s/w/ir/x/w/sdk/pkg/dartdev/bin/dartdev.dart 11:9  main
FINE: Building package executable finished (0.644s).
---- End log transcript ----
IO  : Writing 10340 characters to text file /Users/kemal/.pub-cache/log/pub_log.txt.
MSG : Logs written to /Users/kemal/.pub-cache/log/pub_log.txt.

@kemalinnowise
Copy link

Hello!

I downloaded the demo project and configured the dependencies from the repository, everything run and works for me except for the generation in my projects pubcpec.yaml I use the following to generate Mychain instead Poladot:

image

So I've tried replace this lines in demo project with one from my project and run:

dart pub run polkadart_cli:generate -v

The command line throws given error:

➜  sandbox dart pub run polkadart_cli:generate -v
FINE: Pub 3.1.0
MSG : Deprecated. Use `dart run` instead.
FINE: Package Config up to date.
FINE: Package Config up to date.
MSG : Building package executable...
IO  : Created temp directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov
IO  : Copying "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill" to "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp".
IO  : Renaming "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp" to "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill".
IO  : Deleting directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov.
ERR : Failed to build polkadart_cli:generate:
    | ../../../.pub-cache/hosted/pub.dev/watcher-1.0.2/lib/src/constructable_file_system_event.dart:7:57: Error: The class 'FileSystemEvent' can't be extended, implemented, or mixed in outside of its library because it's a sealed class.
    | abstract class _ConstructableFileSystemEvent implements FileSystemEvent {
    |                                                         ^
FINE: Exception type: ApplicationException
FINE: package:pub/src/dart.dart 170:7                        precompile
    | ===== asynchronous gap ===========================
    | dart:async                                             Future.catchError
    | package:pub/src/utils.dart 155:21                      waitAndPrintErrors.<fn>
    | dart:async                                             Future.wait
    | package:pub/src/utils.dart 153:17                      waitAndPrintErrors
    | package:pub/src/entrypoint.dart 515:14                 Entrypoint.precompileExecutable.<fn>
    | package:pub/src/log.dart 437:18                        progress
    | package:pub/src/entrypoint.dart 513:15                 Entrypoint.precompileExecutable
    | package:pub/src/command/run.dart 107:26                RunCommand.runProtected.<fn>.<fn>
    | package:pub/src/log.dart 420:32                        errorsOnlyUnlessTerminal
    | package:pub/src/command/run.dart 106:38                RunCommand.runProtected.<fn>
    | package:pub/src/executable.dart 97:22                  runExecutable
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/executable.dart 79:24                  runExecutable
    | package:pub/src/command/run.dart 100:26                RunCommand.runProtected
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/command/run.dart 61:7                  RunCommand.runProtected
    | package:pub/src/command.dart 199:21                    PubCommand.run.<fn>
    | dart:async                                             new Future.sync
    | package:pub/src/utils.dart 114:12                      captureErrors.wrappedCallback
    | package:stack_trace                                    Chain.capture
    | package:pub/src/utils.dart 131:11                      captureErrors
    | package:pub/src/command.dart 198:13                    PubCommand.run
    | package:args/command_runner.dart 212:27                CommandRunner.runCommand
    | package:dartdev/dartdev.dart 240:30                    DartdevRunner.runCommand
    | package:args/command_runner.dart 122:25                CommandRunner.run.<fn>
    | dart:async                                             new Future.sync
    | package:args/command_runner.dart 122:14                CommandRunner.run
    | package:dartdev/dartdev.dart 59:29                     runDartdev
    | /opt/s/w/ir/x/w/sdk/pkg/dartdev/bin/dartdev.dart 11:9  main
FINE: Building package executable finished (0.644s).
---- Log transcript ----
FINE: Pub 3.1.0
MSG : Deprecated. Use `dart run` instead.
FINE: Package Config up to date.
FINE: Package Config up to date.
MSG : Building package executable...
IO  : Created temp directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov
IO  : Copying "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill" to "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp".
IO  : Renaming "./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov/generate.dart.incremental.dill.temp" to "./.dart_tool/pub/incremental/polkadart_cli/generate.dart.incremental.dill".
IO  : Deleting directory ./.dart_tool/pub/incremental/polkadart_cli/tmpDHhEov.
ERR : Failed to build polkadart_cli:generate:
    | ../../../.pub-cache/hosted/pub.dev/watcher-1.0.2/lib/src/constructable_file_system_event.dart:7:57: Error: The class 'FileSystemEvent' can't be extended, implemented, or mixed in outside of its library because it's a sealed class.
    | abstract class _ConstructableFileSystemEvent implements FileSystemEvent {
    |                                                         ^
FINE: Exception type: ApplicationException
FINE: package:pub/src/dart.dart 170:7                        precompile
    | ===== asynchronous gap ===========================
    | dart:async                                             Future.catchError
    | package:pub/src/utils.dart 155:21                      waitAndPrintErrors.<fn>
    | dart:async                                             Future.wait
    | package:pub/src/utils.dart 153:17                      waitAndPrintErrors
    | package:pub/src/entrypoint.dart 515:14                 Entrypoint.precompileExecutable.<fn>
    | package:pub/src/log.dart 437:18                        progress
    | package:pub/src/entrypoint.dart 513:15                 Entrypoint.precompileExecutable
    | package:pub/src/command/run.dart 107:26                RunCommand.runProtected.<fn>.<fn>
    | package:pub/src/log.dart 420:32                        errorsOnlyUnlessTerminal
    | package:pub/src/command/run.dart 106:38                RunCommand.runProtected.<fn>
    | package:pub/src/executable.dart 97:22                  runExecutable
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/executable.dart 79:24                  runExecutable
    | package:pub/src/command/run.dart 100:26                RunCommand.runProtected
    | ===== asynchronous gap ===========================
    | dart:async                                             _CustomZone.registerUnaryCallback
    | package:pub/src/command/run.dart 61:7                  RunCommand.runProtected
    | package:pub/src/command.dart 199:21                    PubCommand.run.<fn>
    | dart:async                                             new Future.sync
    | package:pub/src/utils.dart 114:12                      captureErrors.wrappedCallback
    | package:stack_trace                                    Chain.capture
    | package:pub/src/utils.dart 131:11                      captureErrors
    | package:pub/src/command.dart 198:13                    PubCommand.run
    | package:args/command_runner.dart 212:27                CommandRunner.runCommand
    | package:dartdev/dartdev.dart 240:30                    DartdevRunner.runCommand
    | package:args/command_runner.dart 122:25                CommandRunner.run.<fn>
    | dart:async                                             new Future.sync
    | package:args/command_runner.dart 122:14                CommandRunner.run
    | package:dartdev/dartdev.dart 59:29                     runDartdev
    | /opt/s/w/ir/x/w/sdk/pkg/dartdev/bin/dartdev.dart 11:9  main
FINE: Building package executable finished (0.644s).
---- End log transcript ----
IO  : Writing 10340 characters to text file /Users/kemal/.pub-cache/log/pub_log.txt.
MSG : Logs written to /Users/kemal/.pub-cache/log/pub_log.txt.

Sorry that was my bad. For some reason watcher won't work properly, I fixed bug and now things work fine on my side. Seems to me Existing changes is enough for my project) What is the next steps, how can I be helpful ?

@kemalinnowise
Copy link

Also I try replace your example with my and got given error while generate classes:

lib/generated/mychain/pallets/evm.dart:128:35: Error: The method 'call' isn't defined for the class '$Call'.
 - '$Call' is from 'package:sandbox/generated/mychain/types/pallet_evm/pallet/call.dart' ('lib/generated/mychain/types/pallet_evm/pallet/call.dart').
Try correcting the name to the name of an existing method, or defining a method named 'call'.
    final _call = _i8.Call.values.call(
                                  ^^^^

And one more thing:

final extrinsic = Extrinsic(
          signer: publicKey,
          method: call,
          signature: hexSignature,
          era: era,
          nonce: nonce,
          tip: tip)
      .encode(api.registry);

  final hexExtrinsic = hex.encode(extrinsic);
  print('Extrinsic: $hexExtrinsic');
  // 2d0284006802f945419791d3138b4086aa0b2700abb679f950e2721fd7d65b5d1fdf8f0201d19e04fc1a4ec115ec55d29e53676ddaeae0467134f9513b29ed3cd6fd6cd551a96c35b92b867dfd08ba37417e5733620acc4ad17c1d7c65909d6edaaffd4d0e0028000a03008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48a10f

Where to send this serialised extrinsic ?

@leonardocustodio
Copy link
Owner Author

leonardocustodio commented Aug 25, 2023

This would give you an encoded call:

  final dest = $MultiAddress().raw(hex.decode(
      "06d0f1711a6d0408135ff35043137210d0563f3d02f17e6cdacec1f6e23a5a17"));
  final runtimeCall = api.tx.balances.transferAll(dest: dest, keepAlive: true);
  final call = hex.encode(runtimeCall.encode());
  print(call);

Where api is:

  final provider = Provider.fromUri(Uri.parse('wss://rpc.efinity.io'));
  final api = Polkadot(provider);

And this Polkadot is actually the name that you put on the chains, and should come from /lib/generated/<name>.dart

@leonardocustodio
Copy link
Owner Author

leonardocustodio commented Aug 25, 2023

Where to send this serialised extrinsic ?

That's actually one thing that you can help out if you wish. Basically, you need to make a RPC call to author.submitExtrinsic passing the signed extrinsic. There is already the RPC interface, the system calls are done through it. But we have not made the other interfaces.

@clangenb
Copy link
Contributor

clangenb commented Oct 6, 2023

Hi there, maintainer of https://github.com/encointer/encointer-wallet-flutter here. We want to get rid of our unstable webView that runs a @polkadot-js/api, and want to have a pure dart<>substrate interface. The work you have done here is wonderful.

Once this PR is merged, we would love to try out your lib! Is there any estimate, is this still being worked on?

@leonardocustodio
Copy link
Owner Author

Hello @clangenb , yes we have resumed the development and our ETA for our next milestone is in about two months, here is the list of things that will be released in this next milestone:

 3a.  | Substrate Uri    | Implement Substrate's standard derivation format that applies to seeds and mnemonics. |
| 3b.  | Encrypt/Decrypt  | Use Substrate's Bip39 password to encrypt/decrypt seeds and mnemonics. |
| 3c.  | Ed25519          | Support Ed25519 signatures and key derivation |
| 3e.  | Sign & Verify    | Sign and verify messages using ed25519 keypairs |
| 3f.  | Substrate Signed Extensions | Support substrate's signed extensions |
| 3g.  | AssetHub Signed Extensions | Support AssetHub's signed extensions |
| 3h.  | Transaction Subscriptions   | Support transaction subscription |
| 3i.  | Event Subscriptions         | Support runtime event subscription |
| 3j.  | Keyring          | Create a package that manage a set of keys in a consistent environment |
| 3k.  | Crypto           | Utilities needed for signing, hash and encode/decode messages |

@clangenb
Copy link
Contributor

clangenb commented Oct 6, 2023

Awesome thanks for the swift reply - cool features are in the pipeline! What I can't see in this milestone list is extrinsic creation and calling the author RPC to submit the extrinsic and listen for tx status updates (so essentially work that builds upon this PR), do you also have some info regarding this?

@leonardocustodio
Copy link
Owner Author

leonardocustodio commented Oct 6, 2023 via email

@clangenb
Copy link
Contributor

clangenb commented Oct 8, 2023

Awesome, thank you so much for all these updates. I was curious about your library and started integrating the current state into our codebase and generated some types just to get a feeling about it - works flawlessly so far.

My current endeavour is to send an already signed and scale-encoded extrinsic to our chain and listen for the extrinsic status updates. As I have found your library meanwhile, I might use your state/system apis as an inspiration and implement parts of the author api analogously to them. If your interested, I could maybe upstream it.

@leonardocustodio
Copy link
Owner Author

prs are always welcome, feel free to send any if you want to 😄

@leonardocustodio
Copy link
Owner Author

@clangenb, you can now submitAndWatchExtrinsic using this PR, though the PR is not done yet.

@clangenb
Copy link
Contributor

Hi there, thanks a lot! I have also made my own implementation meanwhile, as I needed quite some boilerplate around sending the extrinsic and moreover finding out whether the extrinsic was a success or not. Some of the code is a bit opinionated, so I am not sure if it fits in a library like polkadart, but you can have a look at it if you like: encointer/encointer-wallet-flutter#1529.

This file might be of interest to you in particular: https://github.com/encointer/encointer-wallet-flutter/blob/831bd4638b002c567707dadc6e7eaad022d4be12/app/lib/service/tx/lib/src/send_tx_dart.dart

justkawal and others added 9 commits October 29, 2023 23:59
* add lock and unlock

* update _locked

* fix stuck CI build failing

* dummy test

* add test cases for pairs_test

* add equality check for keypair

* improvements and functionality addition

* fix tests

* keypair tests

* tests for keyring class

* changes in test
@leonardocustodio leonardocustodio marked this pull request as ready for review October 31, 2023 17:09
@leonardocustodio leonardocustodio merged commit c364455 into main Oct 31, 2023
@leonardocustodio leonardocustodio deleted the create-tx branch October 31, 2023 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants