Skip to content

Commit 682e7f1

Browse files
Merge pull request #22 from codescalers/main_tfchain
Get the result after applying extrinsic
2 parents 65ba465 + cec9065 commit 682e7f1

File tree

6 files changed

+113
-88
lines changed

6 files changed

+113
-88
lines changed

packages/tfchain_client/bin/tfchain_client.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ void main() async {
1919
await client.connect();
2020
// final extrinsic = await client.clientBalances.transfer(
2121
// address: "5CJrCjZvsudNoJApTGG5PKcZfhAzAyGqgSK8bysoCV2oRBMC", amount: 10);
22-
final extrinsic = await client.clientTwins.create(relay: [], pk: []);
22+
final twinId = await client.clientTwins.create(relay: [], pk: []);
2323

24-
await client.apply(extrinsic);
24+
print(twinId);
2525
// await client.kvStrore.list();
2626

2727
// await client.disconnect();

packages/tfchain_client/lib/src/balances.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ class QueryBalances {
1717
}
1818

1919
class Balances extends QueryBalances {
20-
Balances(Client client) : super(client) {
21-
this.client = client;
22-
}
20+
Balances(Client this.client) : super(client);
21+
22+
final Client client;
2323

2424
Future<RuntimeCall> transfer(
2525
{required String address, required int amount}) async {
@@ -30,12 +30,12 @@ class Balances extends QueryBalances {
3030
final publicKey = keyring.decodeAddress(address);
3131
MultiAddress multiAddress = Address32(publicKey);
3232

33-
final extrinsic =
34-
client.api.tx.balances.transfer(dest: multiAddress, value: BigInt.from(amount));
33+
final extrinsic = client.api.tx.balances
34+
.transfer(dest: multiAddress, value: BigInt.from(amount));
3535
return extrinsic;
3636
}
3737

38-
// Future<AccountInfo?> getMyBalance() async {
39-
// return await this
40-
// }
38+
Future<AccountInfo?> getMyBalance() async {
39+
return await this.get(address: client.address);
40+
}
4141
}

packages/tfchain_client/lib/src/client.dart

Lines changed: 84 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,30 @@ class Client extends QueryClient {
129129
}
130130
}
131131

132+
List<int> _getMyEventsPhaseId(List<dynamic> events) {
133+
final Set<int> phaseIds = Set();
134+
for (final event in events) {
135+
if (event["event"] != null &&
136+
event["event"].key == "TransactionPayment" &&
137+
ListEquality().equals(
138+
event["event"].value.value[0], keypair!.publicKey.bytes)) {
139+
phaseIds.add(event['phase'].value);
140+
}
141+
}
142+
return phaseIds.toList();
143+
}
144+
145+
List<dynamic> _filterMyEvents(List<dynamic> events) {
146+
final List<dynamic> myEvents = [];
147+
final phaseIds = _getMyEventsPhaseId(events);
148+
for (final event in events) {
149+
if (phaseIds.contains(event["phase"].value)) {
150+
myEvents.add(event["event"]);
151+
}
152+
}
153+
return myEvents;
154+
}
155+
132156
Future<void> apply(RuntimeCall runtimeCall) async {
133157
if (provider == null) {
134158
throw Exception("Provider is not initialized");
@@ -153,10 +177,8 @@ class Client extends QueryClient {
153177
.result
154178
.replaceAll('0x', '');
155179

156-
final keyring = await KeyPair.sr25519.fromMnemonic(mnemonic);
157-
158180
final encodedCall = runtimeCall.encode();
159-
final nonce = await api.rpc.system.accountNextIndex(keyring.address);
181+
final nonce = await api.rpc.system.accountNextIndex(address);
160182
final metadata = await api.rpc.state.getMetadata();
161183

162184
// await api.rpc.state.queryStorageAt(keys)
@@ -176,93 +198,86 @@ class Client extends QueryClient {
176198

177199
final payload = payloadToSign.encode(api.registry);
178200

179-
final signature = keyring.sign(payload);
201+
final signature = keypair!.sign(payload);
180202

181203
// final hexSignature = hex.encode(signature);
182204

183205
// final publicKey = hex.encode(keyring.publicKey.bytes);
184-
206+
final signatureType = keypairType == "sr25519"
207+
? SignatureType.sr25519
208+
: SignatureType.ed25519;
185209
final extrinsic = ExtrinsicPayload(
186-
signer: Uint8List.fromList(keyring.bytes()),
210+
signer: Uint8List.fromList(keypair!.bytes()),
187211
method: encodedCall,
188212
signature: signature,
189213
eraPeriod: 64,
190214
blockNumber: blockNumber,
191215
nonce: nonce,
192216
tip: 0)
193-
.encode(api.registry, SignatureType.sr25519);
194-
195-
final hexExtrinsic = hex.encode(extrinsic);
196-
final input = Input.fromHex(hexExtrinsic);
197-
final dynamic extrinsicDecoded =
198-
ExtrinsicsCodec(chainInfo: metadata.chainInfo).decode(input);
199-
print(extrinsicDecoded);
200-
201-
final submit = await AuthorApi(provider!).submitAndWatchExtrinsic(
217+
.encode(api.registry, signatureType);
218+
219+
// final hexExtrinsic = hex.encode(extrinsic);
220+
// final input = Input.fromHex(hexExtrinsic);
221+
// final dynamic extrinsicDecoded =
222+
// ExtrinsicsCodec(chainInfo: metadata.chainInfo).decode(input);
223+
// print(extrinsicDecoded);
224+
Completer<void> _complete = Completer();
225+
final StreamSubscription subscription =
226+
await AuthorApi(provider!).submitAndWatchExtrinsic(
202227
extrinsic,
203228
(p0) async {
204229
print("Extrinsic result: ${p0.type} - ${p0.value}");
205230
if (p0.type == 'inBlock') {
206-
try {
207-
final finalizedBlockHash = p0.value;
208-
print(finalizedBlockHash.runtimeType);
209-
final moduleHash =
210-
Hasher.twoxx128.hash(Uint8List.fromList('System'.codeUnits));
211-
final storageHash =
212-
Hasher.twoxx128.hash(Uint8List.fromList('Events'.codeUnits));
213-
Uint8List storageKey = Uint8List.fromList([
214-
...moduleHash,
215-
...storageHash,
216-
]);
217-
final finalizedBlockHashBytes = hexToBytes(finalizedBlockHash);
218-
final changes = await stateApi
219-
.queryStorageAt([storageKey], at: finalizedBlockHashBytes);
220-
if (changes != Null && changes.isNotEmpty) {
221-
for (var changeSet in changes) {
222-
print("Change Set:");
223-
for (var change in changeSet.changes) {
224-
Uint8List key = change.key;
225-
Uint8List value = change.value!;
226-
227-
final input = Input.fromBytes(value);
228-
final List<dynamic> decodedEvents =
229-
metadata.chainInfo.scaleCodec.decode('EventCodec', input);
230-
// try {
231-
// List<Map<String, dynamic>> jsonEvents =
232-
// decodedEvents.map((dynamic entry) {
233-
// Map<String, dynamic> convertedEntry = {};
234-
235-
// entry.forEach((key, value) {
236-
// if (value is MapEntry) {
237-
// // Replace MapEntry with {}
238-
// convertedEntry[key] = value.value;
239-
// } else {
240-
// convertedEntry[key] = value;
241-
// }
242-
// });
243-
244-
// return convertedEntry;
245-
// }).toList();
246-
247-
// String jsonOutput = jsonEncode(jsonEvents);
248-
249-
// print("Converted JSON:");
250-
// print(jsonOutput);
251-
// } catch (e) {
252-
// print("Error converting events: $e");
253-
// }
231+
final finalizedBlockHash = p0.value;
232+
final moduleHash =
233+
Hasher.twoxx128.hash(Uint8List.fromList('System'.codeUnits));
234+
final storageHash =
235+
Hasher.twoxx128.hash(Uint8List.fromList('Events'.codeUnits));
236+
Uint8List storageKey = Uint8List.fromList([
237+
...moduleHash,
238+
...storageHash,
239+
]);
240+
final finalizedBlockHashBytes = hexToBytes(finalizedBlockHash);
241+
final changes = await stateApi
242+
.queryStorageAt([storageKey], at: finalizedBlockHashBytes);
243+
if (changes != Null && changes.isNotEmpty) {
244+
for (var changeSet in changes) {
245+
for (var change in changeSet.changes) {
246+
Uint8List key = change.key;
247+
Uint8List value = change.value!;
248+
249+
final input = Input.fromBytes(value);
250+
final List<dynamic> decodedEvents =
251+
metadata.chainInfo.scaleCodec.decode('EventCodec', input);
252+
final myEvents = _filterMyEvents(decodedEvents);
253+
bool targetModuleEventOccur = false;
254+
for (final event in myEvents) {
255+
if (event.key == "System" &&
256+
event.value.key == "ExtrinsicFailed") {
257+
// TODO: get the error name and type
258+
final error = event.value.value["DispatchError"].value;
259+
final errorType = event.value.value["DispatchError"].key;
260+
_complete.completeError(
261+
"Failed to apply extrinsic: ${errorType}${error}");
262+
} else if (event.key == runtimeCall.runtimeType.toString()) {
263+
targetModuleEventOccur = true;
264+
} else if (targetModuleEventOccur &&
265+
event.key == "System" &&
266+
event.value.key == "ExtrinsicSuccess") {
267+
print("Extrinsic is applied successfully");
268+
_complete.complete();
269+
return;
270+
}
254271
}
255272
}
256-
} else {
257-
print("No events found in the block");
258273
}
259-
} catch (e) {
260-
print('Error decoding events: $e');
274+
} else {
275+
_complete.completeError("No events found in the block");
261276
}
262277
}
263278
},
264279
);
265-
266-
// print(submit);
280+
await _complete.future;
281+
subscription.cancel();
267282
}
268283
}

packages/tfchain_client/lib/src/contracts.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ class Contracts extends QueryContracts {
111111
}
112112

113113
Future<RuntimeCall> createName({required String name}) async {
114-
final extrinsic =
115-
client.api.tx.smartContractModule.createNameContract(name: name);
114+
final extrinsic = client.api.tx.smartContractModule
115+
.createNameContract(name: name.codeUnits);
116116
return extrinsic;
117117
}
118118

packages/tfchain_client/lib/src/twins.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@ class QueryTwins {
2222
}
2323

2424
class Twins extends QueryTwins {
25-
Twins(Client client) : super(client);
25+
Twins(Client this.client) : super(client);
2626

27-
Future<RuntimeCall> create(
28-
{required List<int> relay, required List<int> pk}) async {
27+
final Client client;
28+
29+
Future<int?> create({required List<int> relay, required List<int> pk}) async {
2930
final extrinsic =
3031
client.api.tx.tfgridModule.createTwin(relay: relay, pk: pk);
31-
return extrinsic;
32+
33+
await client.apply(extrinsic);
34+
return await getTwinIdByAccountId(address: client.address);
3235
}
3336

3437
Future<RuntimeCall> update(

packages/tfchain_client/lib/tfchain_client.dart

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
library client;
22

3+
import 'dart:async';
34
import 'dart:typed_data';
45

5-
66
import 'package:polkadart/polkadart.dart'
7-
show AuthorApi, ExtrinsicPayload, Hasher, Provider, SignatureType, SigningPayload, StateApi;
7+
show
8+
AuthorApi,
9+
ExtrinsicPayload,
10+
Hasher,
11+
Provider,
12+
SignatureType,
13+
SigningPayload,
14+
StateApi;
815
import 'package:polkadart/scale_codec.dart';
916
import 'package:polkadart_keyring/polkadart_keyring.dart';
10-
import 'package:substrate_metadata/types/metadata_types.dart';
1117
import 'package:tfchain_client/generated/dev/types/tfchain_runtime/runtime_call.dart';
1218
import 'package:tfchain_client/src/balances.dart' as balance;
1319
import 'package:tfchain_client/src/contracts.dart';
@@ -23,5 +29,6 @@ import 'package:tfchain_client/src/twins.dart';
2329
import 'package:bip39/bip39.dart';
2430
import 'package:convert/convert.dart';
2531
import 'package:signer/signer.dart' as Signer;
32+
import 'package:collection/collection.dart';
2633

2734
part 'src/client.dart';

0 commit comments

Comments
 (0)