From e911028dc40dce353e355ee339818e16c1ae34e2 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 11 Mar 2022 10:56:15 +0530 Subject: [PATCH 01/18] refactor: add dataitem to json --- lib/src/models/data_item.dart | 9 +++++++++ lib/src/models/data_item.g.dart | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 lib/src/models/data_item.g.dart diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 10e2acb..f36f87a 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -2,15 +2,19 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:arweave/src/utils/bundle_tag_parser.dart'; +import 'package:json_annotation/json_annotation.dart'; import '../crypto/crypto.dart'; import '../utils.dart'; import 'models.dart'; +part 'data_item.g.dart'; + final MIN_BINARY_SIZE = 1044; /// ANS-104 [DataItem] /// Spec: https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md +@JsonSerializable() class DataItem implements TransactionBase { @override String get id => _id; @@ -37,6 +41,8 @@ class DataItem implements TransactionBase { @override String get signature => _signature; late String _signature; + + @JsonKey(ignore: true) late ByteBuffer binary; /// This constructor is reserved for JSON serialisation. @@ -287,4 +293,7 @@ class DataItem implements TransactionBase { bytesBuilder.add(data); return bytesBuilder; } + + /// Encodes the [DataItem] as JSON with the `data` as the original unencoded [Uint8List]. + Map toJson() => _$DataItemToJson(this); } diff --git a/lib/src/models/data_item.g.dart b/lib/src/models/data_item.g.dart new file mode 100644 index 0000000..b98dbf4 --- /dev/null +++ b/lib/src/models/data_item.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'data_item.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DataItem _$DataItemFromJson(Map json) => DataItem( + owner: json['owner'] as String?, + target: json['target'] as String?, + nonce: json['nonce'] as String?, + tags: (json['tags'] as List?) + ?.map((e) => Tag.fromJson(e as Map)) + .toList(), + data: json['data'] as String?, + ); + +Map _$DataItemToJson(DataItem instance) => { + 'owner': instance.owner, + 'target': instance.target, + 'nonce': instance.nonce, + 'tags': instance.tags, + 'data': instance.data, + }; From 218f6a8ee85832bcac13a0613305dba03db9f903 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Tue, 22 Mar 2022 15:05:08 -0400 Subject: [PATCH 02/18] refactor: update transaction sign PE-1136 --- lib/src/models/data_item.dart | 8 +++++--- lib/src/models/id.g.dart | 14 ++++++------- lib/src/models/transaction.dart | 3 +-- lib/src/models/transaction.g.dart | 34 +++++++++++++++---------------- lib/src/models/wallet.dart | 5 +++-- pubspec.yaml | 2 +- test/wallets_test.dart | 15 -------------- 7 files changed, 32 insertions(+), 49 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index f36f87a..f8f5e27 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -16,6 +16,9 @@ final MIN_BINARY_SIZE = 1044; /// Spec: https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md @JsonSerializable() class DataItem implements TransactionBase { + @JsonKey(defaultValue: 1) + final int format = 1; + @override String get id => _id; late String _id; @@ -112,7 +115,7 @@ class DataItem implements TransactionBase { Future getSignatureData() => deepHash( [ utf8.encode('dataitem'), - utf8.encode('1'), //Transaction format + utf8.encode(format.toString()), //Transaction format utf8.encode('1'), //Signature type decodeBase64ToBytes(owner), decodeBase64ToBytes(target), @@ -125,8 +128,7 @@ class DataItem implements TransactionBase { /// Signs the [DataItem] using the specified wallet and sets the `id` and `signature` appropriately. @override Future sign(Wallet wallet) async { - final signatureData = await getSignatureData(); - final rawSignature = await wallet.sign(signatureData); + final rawSignature = await wallet.sign(this); _signature = encodeBytesToBase64(rawSignature); diff --git a/lib/src/models/id.g.dart b/lib/src/models/id.g.dart index 9b8e9dc..2433538 100644 --- a/lib/src/models/id.g.dart +++ b/lib/src/models/id.g.dart @@ -6,14 +6,12 @@ part of 'id.dart'; // JsonSerializableGenerator // ************************************************************************** -ArweaveId _$ArweaveIdFromJson(Map json) { - return ArweaveId( - name: json['name'] as String, - url: json['url'] as String, - text: json['text'] as String, - avatarDataUri: json['avatarDataUri'] as String, - ); -} +ArweaveId _$ArweaveIdFromJson(Map json) => ArweaveId( + name: json['name'] as String, + url: json['url'] as String, + text: json['text'] as String, + avatarDataUri: json['avatarDataUri'] as String, + ); Map _$ArweaveIdToJson(ArweaveId instance) => { 'name': instance.name, diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 7317c38..def7a7d 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -277,8 +277,7 @@ class Transaction implements TransactionBase { @override Future sign(Wallet wallet) async { - final signatureData = await getSignatureData(); - final rawSignature = await wallet.sign(signatureData); + final rawSignature = await wallet.sign(this); _signature = encodeBytesToBase64(rawSignature); diff --git a/lib/src/models/transaction.g.dart b/lib/src/models/transaction.g.dart index 9d2d656..73a6de6 100644 --- a/lib/src/models/transaction.g.dart +++ b/lib/src/models/transaction.g.dart @@ -6,24 +6,22 @@ part of 'transaction.dart'; // JsonSerializableGenerator // ************************************************************************** -Transaction _$TransactionFromJson(Map json) { - return Transaction( - format: json['format'] as int? ?? 1, - id: json['id'] as String?, - lastTx: json['last_tx'] as String?, - owner: json['owner'] as String?, - tags: (json['tags'] as List?) - ?.map((e) => Tag.fromJson(e as Map)) - .toList(), - target: json['target'] as String?, - quantity: _stringToBigInt(json['quantity'] as String), - data: json['data'] as String?, - dataSize: json['data_size'] as String?, - dataRoot: json['data_root'] as String?, - reward: _stringToBigInt(json['reward'] as String), - signature: json['signature'] as String?, - ); -} +Transaction _$TransactionFromJson(Map json) => Transaction( + format: json['format'] as int? ?? 1, + id: json['id'] as String?, + lastTx: json['last_tx'] as String?, + owner: json['owner'] as String?, + tags: (json['tags'] as List?) + ?.map((e) => Tag.fromJson(e as Map)) + .toList(), + target: json['target'] as String?, + quantity: _stringToBigInt(json['quantity'] as String), + data: json['data'] as String?, + dataSize: json['data_size'] as String?, + dataRoot: json['data_root'] as String?, + reward: _stringToBigInt(json['reward'] as String), + signature: json['signature'] as String?, + ); Map _$TransactionToJson(Transaction instance) => { diff --git a/lib/src/models/wallet.dart b/lib/src/models/wallet.dart index 8c5ab87..461e9af 100644 --- a/lib/src/models/wallet.dart +++ b/lib/src/models/wallet.dart @@ -3,6 +3,7 @@ import 'dart:core'; import 'dart:math'; import 'dart:typed_data'; +import 'package:arweave/arweave.dart'; import 'package:cryptography/cryptography.dart'; import 'package:jwk/jwk.dart'; import 'package:pointycastle/export.dart'; @@ -54,8 +55,8 @@ class Wallet { await _keyPair!.extractPublicKey().then((res) => res.n)); Future getAddress() async => ownerToAddress(await getOwner()); - Future sign(Uint8List message) async => - rsaPssSign(message: message, keyPair: _keyPair!); + Future sign(TransactionBase transaction) async => rsaPssSign( + message: await transaction.getSignatureData(), keyPair: _keyPair!); factory Wallet.fromJwk(Map jwk) { // Normalize the JWK so that it can be decoded by 'cryptography'. diff --git a/pubspec.yaml b/pubspec.yaml index 0f2dc08..e0ea364 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ environment: dependencies: cryptography: ^2.0.1 http: ^0.13.3 - json_annotation: ^4.0.1 + json_annotation: 4.4.0 jwk: ^0.1.0 meta: ^1.7.0 pointycastle: ^3.1.1 diff --git a/test/wallets_test.dart b/test/wallets_test.dart index 9a40c65..7d6ccec 100644 --- a/test/wallets_test.dart +++ b/test/wallets_test.dart @@ -1,9 +1,7 @@ import 'dart:convert'; import 'dart:io'; -import 'dart:typed_data'; import 'package:arweave/arweave.dart'; -import 'package:arweave/utils.dart' as utils; import 'package:test/test.dart'; import 'utils.dart'; @@ -57,18 +55,5 @@ void main() { }, onPlatform: { 'browser': Skip('dart:io unavailable'), }); - - test('sign message with wallet', () async { - final wallet = await getTestWallet(); - final message = utf8.encode(''); - - final signature = await wallet.sign(message as Uint8List); - expect( - utils.encodeBytesToBase64(signature), - startsWith('II5LxGnPt4WTSz9P__wMAdjzXWlZE-wGbKU7wm4DbGuPXB5Vifs'), - ); - }, onPlatform: { - 'browser': Skip('dart:io unavailable'), - }); }); } From 6a70d70df3865fd9b0f9619f2f463fd9964fa807 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Tue, 22 Mar 2022 15:09:52 -0400 Subject: [PATCH 03/18] refactor: add toJson to transactionbase PE-1136 --- lib/src/models/data_item.dart | 1 + lib/src/models/transaction-base.dart | 2 ++ lib/src/models/transaction.dart | 1 + 3 files changed, 4 insertions(+) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index f8f5e27..ff86863 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -297,5 +297,6 @@ class DataItem implements TransactionBase { } /// Encodes the [DataItem] as JSON with the `data` as the original unencoded [Uint8List]. + @override Map toJson() => _$DataItemToJson(this); } diff --git a/lib/src/models/transaction-base.dart b/lib/src/models/transaction-base.dart index e3646d2..ee737f3 100644 --- a/lib/src/models/transaction-base.dart +++ b/lib/src/models/transaction-base.dart @@ -27,4 +27,6 @@ abstract class TransactionBase { Future sign(Wallet wallet); Future verify(); + + Map toJson(); } diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index def7a7d..f365402 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -311,5 +311,6 @@ class Transaction implements TransactionBase { _$TransactionFromJson(json); /// Encodes the [Transaction] as JSON with the `data` as the original unencoded [Uint8List]. + @override Map toJson() => _$TransactionToJson(this); } From 93f4e33d7157ec05e5278bc192ef532b21d82066 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Tue, 22 Mar 2022 15:21:44 -0400 Subject: [PATCH 04/18] refactor: add signMessage function PE-1136 --- lib/src/models/wallet.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/src/models/wallet.dart b/lib/src/models/wallet.dart index 461e9af..b5a9ea8 100644 --- a/lib/src/models/wallet.dart +++ b/lib/src/models/wallet.dart @@ -58,6 +58,9 @@ class Wallet { Future sign(TransactionBase transaction) async => rsaPssSign( message: await transaction.getSignatureData(), keyPair: _keyPair!); + Future signMessage(Uint8List message) async => + rsaPssSign(message: message, keyPair: _keyPair!); + factory Wallet.fromJwk(Map jwk) { // Normalize the JWK so that it can be decoded by 'cryptography'. jwk = jwk.map((key, value) { From 0a8366aac5333e402fd4a244744e15b018e26a39 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Tue, 22 Mar 2022 16:47:08 -0400 Subject: [PATCH 05/18] fix: fix nested json serialization PE-1136 --- lib/src/models/tag.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/models/tag.dart b/lib/src/models/tag.dart index 26f0828..f28de3f 100644 --- a/lib/src/models/tag.dart +++ b/lib/src/models/tag.dart @@ -2,7 +2,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'tag.g.dart'; -@JsonSerializable() +@JsonSerializable(explicitToJson: true) class Tag { /// The tag's name encoded as Base64. final String name; From ac76928d801306a0307902c1ef41021f7eed2984 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Tue, 22 Mar 2022 16:54:04 -0400 Subject: [PATCH 06/18] refactor: mark as explicitToJson PE-1136 --- lib/src/models/data_item.dart | 2 +- lib/src/models/data_item.g.dart | 2 +- lib/src/models/tag.g.dart | 10 ++++------ lib/src/models/transaction.dart | 2 +- lib/src/models/transaction.g.dart | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index ff86863..6111595 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -14,7 +14,7 @@ final MIN_BINARY_SIZE = 1044; /// ANS-104 [DataItem] /// Spec: https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md -@JsonSerializable() +@JsonSerializable(explicitToJson: true) class DataItem implements TransactionBase { @JsonKey(defaultValue: 1) final int format = 1; diff --git a/lib/src/models/data_item.g.dart b/lib/src/models/data_item.g.dart index b98dbf4..44e0c53 100644 --- a/lib/src/models/data_item.g.dart +++ b/lib/src/models/data_item.g.dart @@ -20,6 +20,6 @@ Map _$DataItemToJson(DataItem instance) => { 'owner': instance.owner, 'target': instance.target, 'nonce': instance.nonce, - 'tags': instance.tags, + 'tags': instance.tags.map((e) => e.toJson()).toList(), 'data': instance.data, }; diff --git a/lib/src/models/tag.g.dart b/lib/src/models/tag.g.dart index 80dfe7d..b445f30 100644 --- a/lib/src/models/tag.g.dart +++ b/lib/src/models/tag.g.dart @@ -6,12 +6,10 @@ part of 'tag.dart'; // JsonSerializableGenerator // ************************************************************************** -Tag _$TagFromJson(Map json) { - return Tag( - json['name'] as String, - json['value'] as String, - ); -} +Tag _$TagFromJson(Map json) => Tag( + json['name'] as String, + json['value'] as String, + ); Map _$TagToJson(Tag instance) => { 'name': instance.name, diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index f365402..2e13b90 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -12,7 +12,7 @@ part 'transaction.g.dart'; String _bigIntToString(BigInt v) => v.toString(); BigInt _stringToBigInt(String v) => BigInt.parse(v); -@JsonSerializable() +@JsonSerializable(explicitToJson: true) class Transaction implements TransactionBase { @JsonKey(defaultValue: 1) final int format; diff --git a/lib/src/models/transaction.g.dart b/lib/src/models/transaction.g.dart index 73a6de6..71f5fcc 100644 --- a/lib/src/models/transaction.g.dart +++ b/lib/src/models/transaction.g.dart @@ -29,7 +29,7 @@ Map _$TransactionToJson(Transaction instance) => 'id': instance.id, 'last_tx': instance.lastTx, 'owner': instance.owner, - 'tags': instance.tags, + 'tags': instance.tags.map((e) => e.toJson()).toList(), 'target': instance.target, 'quantity': _bigIntToString(instance.quantity), 'data': instance.data, From db8064223c8c880f1571403a35d5b31d6cf0fd0c Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Wed, 23 Mar 2022 12:42:03 -0400 Subject: [PATCH 07/18] refactor: remove late fields from json --- lib/src/models/transaction.dart | 2 ++ lib/src/models/transaction.g.dart | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 2e13b90..54b3fc4 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -17,6 +17,7 @@ class Transaction implements TransactionBase { @JsonKey(defaultValue: 1) final int format; + @JsonKey(ignore: true) @override String get id => _id; late String _id; @@ -60,6 +61,7 @@ class Transaction implements TransactionBase { BigInt get reward => _reward; late BigInt _reward; + @JsonKey(ignore: true) @override String get signature => _signature; late String _signature; diff --git a/lib/src/models/transaction.g.dart b/lib/src/models/transaction.g.dart index 71f5fcc..dae7db0 100644 --- a/lib/src/models/transaction.g.dart +++ b/lib/src/models/transaction.g.dart @@ -8,7 +8,6 @@ part of 'transaction.dart'; Transaction _$TransactionFromJson(Map json) => Transaction( format: json['format'] as int? ?? 1, - id: json['id'] as String?, lastTx: json['last_tx'] as String?, owner: json['owner'] as String?, tags: (json['tags'] as List?) @@ -20,13 +19,11 @@ Transaction _$TransactionFromJson(Map json) => Transaction( dataSize: json['data_size'] as String?, dataRoot: json['data_root'] as String?, reward: _stringToBigInt(json['reward'] as String), - signature: json['signature'] as String?, ); Map _$TransactionToJson(Transaction instance) => { 'format': instance.format, - 'id': instance.id, 'last_tx': instance.lastTx, 'owner': instance.owner, 'tags': instance.tags.map((e) => e.toJson()).toList(), @@ -36,5 +33,4 @@ Map _$TransactionToJson(Transaction instance) => 'data_size': instance.dataSize, 'data_root': instance.dataRoot, 'reward': _bigIntToString(instance.reward), - 'signature': instance.signature, }; From 3ced77d0c87fb54fcddeb1238a58dcb47eceb53e Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Thu, 24 Mar 2022 08:25:40 -0400 Subject: [PATCH 08/18] Revert "refactor: remove late fields from json" This reverts commit db8064223c8c880f1571403a35d5b31d6cf0fd0c. t --- lib/src/models/transaction.dart | 2 -- lib/src/models/transaction.g.dart | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 54b3fc4..2e13b90 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -17,7 +17,6 @@ class Transaction implements TransactionBase { @JsonKey(defaultValue: 1) final int format; - @JsonKey(ignore: true) @override String get id => _id; late String _id; @@ -61,7 +60,6 @@ class Transaction implements TransactionBase { BigInt get reward => _reward; late BigInt _reward; - @JsonKey(ignore: true) @override String get signature => _signature; late String _signature; diff --git a/lib/src/models/transaction.g.dart b/lib/src/models/transaction.g.dart index dae7db0..71f5fcc 100644 --- a/lib/src/models/transaction.g.dart +++ b/lib/src/models/transaction.g.dart @@ -8,6 +8,7 @@ part of 'transaction.dart'; Transaction _$TransactionFromJson(Map json) => Transaction( format: json['format'] as int? ?? 1, + id: json['id'] as String?, lastTx: json['last_tx'] as String?, owner: json['owner'] as String?, tags: (json['tags'] as List?) @@ -19,11 +20,13 @@ Transaction _$TransactionFromJson(Map json) => Transaction( dataSize: json['data_size'] as String?, dataRoot: json['data_root'] as String?, reward: _stringToBigInt(json['reward'] as String), + signature: json['signature'] as String?, ); Map _$TransactionToJson(Transaction instance) => { 'format': instance.format, + 'id': instance.id, 'last_tx': instance.lastTx, 'owner': instance.owner, 'tags': instance.tags.map((e) => e.toJson()).toList(), @@ -33,4 +36,5 @@ Map _$TransactionToJson(Transaction instance) => 'data_size': instance.dataSize, 'data_root': instance.dataRoot, 'reward': _bigIntToString(instance.reward), + 'signature': instance.signature, }; From b735c942c6ad2d99e99280c59c53a0abe6b8b794 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Thu, 24 Mar 2022 08:35:35 -0400 Subject: [PATCH 09/18] refactor: add json convertion utility function PE-1136 --- lib/src/models/transaction.dart | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 2e13b90..d2a1def 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -313,4 +313,17 @@ class Transaction implements TransactionBase { /// Encodes the [Transaction] as JSON with the `data` as the original unencoded [Uint8List]. @override Map toJson() => _$TransactionToJson(this); + + Map toUnsignedJSON() => { + 'format': format, + 'last_tx': lastTx, + 'owner': owner, + 'tags': tags.map((e) => e.toJson()).toList(), + 'target': target, + 'quantity': _bigIntToString(quantity), + 'data': data, + 'data_size': dataSize, + 'data_root': dataRoot, + 'reward': _bigIntToString(reward), + }; } From 3b4e7eefab15552363eb349fa0d768cb78f6783b Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Thu, 24 Mar 2022 10:10:16 -0400 Subject: [PATCH 10/18] refactor: update json function PE-1136 --- lib/src/models/data_item.dart | 3 +++ lib/src/models/transaction-base.dart | 1 + lib/src/models/transaction.dart | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 6111595..5c83f62 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -299,4 +299,7 @@ class DataItem implements TransactionBase { /// Encodes the [DataItem] as JSON with the `data` as the original unencoded [Uint8List]. @override Map toJson() => _$DataItemToJson(this); + + @override + Map toUnsignedJson() => _$DataItemToJson(this); } diff --git a/lib/src/models/transaction-base.dart b/lib/src/models/transaction-base.dart index ee737f3..4e62432 100644 --- a/lib/src/models/transaction-base.dart +++ b/lib/src/models/transaction-base.dart @@ -29,4 +29,5 @@ abstract class TransactionBase { Future verify(); Map toJson(); + Map toUnsignedJson(); } diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index d2a1def..7244ce2 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -314,7 +314,7 @@ class Transaction implements TransactionBase { @override Map toJson() => _$TransactionToJson(this); - Map toUnsignedJSON() => { + Map toUnsignedJson() => { 'format': format, 'last_tx': lastTx, 'owner': owner, From 3f3c72ec5e90df1076638eee7ac36310cbd371bf Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Thu, 24 Mar 2022 13:51:30 -0400 Subject: [PATCH 11/18] refactor: add data size to data item PE-1136 --- lib/src/models/data_item.dart | 21 +++++++++++++++++++-- lib/src/models/transaction.dart | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 5c83f62..bb796cd 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -41,6 +41,10 @@ class DataItem implements TransactionBase { @override late Uint8List data; + @JsonKey(name: 'data_size') + String get dataSize => _dataSize; + String _dataSize = '0'; + @override String get signature => _signature; late String _signature; @@ -58,13 +62,18 @@ class DataItem implements TransactionBase { List? tags, String? data, Uint8List? dataBytes, + String? dataSize, }) : target = target ?? '', nonce = nonce ?? '', _owner = owner ?? '', data = data != null ? decodeBase64ToBytes(data) : (dataBytes ?? Uint8List(0)), - _tags = tags ?? []; + _tags = tags ?? [] { + if (dataSize != null) { + _dataSize = dataSize; + } + } /// Constructs a [DataItem] with the specified JSON data and appropriate Content-Type tag. factory DataItem.withJsonData({ @@ -96,6 +105,7 @@ class DataItem implements TransactionBase { nonce: nonce, tags: tags, dataBytes: data, + dataSize: data.lengthInBytes.toString(), ); @override @@ -301,5 +311,12 @@ class DataItem implements TransactionBase { Map toJson() => _$DataItemToJson(this); @override - Map toUnsignedJson() => _$DataItemToJson(this); + Map toUnsignedJson() => { + 'format': format, + 'owner': owner, + 'tags': tags.map((e) => e.toJson()).toList(), + 'target': target, + 'data': data, + 'data_size': dataSize, + }; } diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 7244ce2..485edd6 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -314,6 +314,7 @@ class Transaction implements TransactionBase { @override Map toJson() => _$TransactionToJson(this); + @override Map toUnsignedJson() => { 'format': format, 'last_tx': lastTx, From a52b706c23a59a1965566b1b87e21053d701a7e8 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 25 Mar 2022 10:11:04 -0400 Subject: [PATCH 12/18] test: add sign message test PE-1136 --- test/wallets_test.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/wallets_test.dart b/test/wallets_test.dart index 7d6ccec..686837a 100644 --- a/test/wallets_test.dart +++ b/test/wallets_test.dart @@ -1,7 +1,9 @@ import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; import 'package:arweave/arweave.dart'; +import 'package:arweave/utils.dart'; import 'package:test/test.dart'; import 'utils.dart'; @@ -55,5 +57,18 @@ void main() { }, onPlatform: { 'browser': Skip('dart:io unavailable'), }); + + test('sign message with wallet', () async { + final wallet = await getTestWallet(); + final message = utf8.encode(''); + + final signature = await wallet.signMessage(message as Uint8List); + expect( + encodeBytesToBase64(signature), + startsWith('II5LxGnPt4WTSz9P__wMAdjzXWlZE-wGbKU7wm4DbGuPXB5Vifs'), + ); + }, onPlatform: { + 'browser': Skip('dart:io unavailable'), + }); }); } From 662eb4071e0378e3545cec35dde417404a82e76d Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 1 Apr 2022 09:29:07 -0400 Subject: [PATCH 13/18] refactor: update sign function PE-1136 --- lib/src/models/data_item.dart | 5 ++--- lib/src/models/transaction.dart | 5 ++--- lib/src/models/wallet.dart | 10 ++++++++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index bb796cd..9cc731c 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -138,9 +138,8 @@ class DataItem implements TransactionBase { /// Signs the [DataItem] using the specified wallet and sets the `id` and `signature` appropriately. @override Future sign(Wallet wallet) async { - final rawSignature = await wallet.sign(this); - - _signature = encodeBytesToBase64(rawSignature); + _signature = await wallet.sign(this); + final rawSignature = decodeBase64ToBytes(_signature); final idHash = await sha256.hash(rawSignature); _id = encodeBytesToBase64(idHash.bytes); diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 485edd6..8f86b9d 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -277,9 +277,8 @@ class Transaction implements TransactionBase { @override Future sign(Wallet wallet) async { - final rawSignature = await wallet.sign(this); - - _signature = encodeBytesToBase64(rawSignature); + _signature = await wallet.sign(this); + final rawSignature = decodeBase64ToBytes(_signature); final idHash = await sha256.hash(rawSignature); _id = encodeBytesToBase64(idHash.bytes); diff --git a/lib/src/models/wallet.dart b/lib/src/models/wallet.dart index b5a9ea8..a2ac548 100644 --- a/lib/src/models/wallet.dart +++ b/lib/src/models/wallet.dart @@ -55,8 +55,14 @@ class Wallet { await _keyPair!.extractPublicKey().then((res) => res.n)); Future getAddress() async => ownerToAddress(await getOwner()); - Future sign(TransactionBase transaction) async => rsaPssSign( - message: await transaction.getSignatureData(), keyPair: _keyPair!); + Future sign(TransactionBase transaction) async { + return encodeBytesToBase64( + await rsaPssSign( + message: await transaction.getSignatureData(), + keyPair: _keyPair!, + ), + ); + } Future signMessage(Uint8List message) async => rsaPssSign(message: message, keyPair: _keyPair!); From 5ea3bf1d4a3f9e8984b0f0d732b00b143a0a500f Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 1 Apr 2022 09:55:34 -0400 Subject: [PATCH 14/18] Revert "refactor: update sign function PE-1136" This reverts commit 662eb4071e0378e3545cec35dde417404a82e76d. --- lib/src/models/data_item.dart | 5 +++-- lib/src/models/transaction.dart | 5 +++-- lib/src/models/wallet.dart | 10 ++-------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 9cc731c..bb796cd 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -138,8 +138,9 @@ class DataItem implements TransactionBase { /// Signs the [DataItem] using the specified wallet and sets the `id` and `signature` appropriately. @override Future sign(Wallet wallet) async { - _signature = await wallet.sign(this); - final rawSignature = decodeBase64ToBytes(_signature); + final rawSignature = await wallet.sign(this); + + _signature = encodeBytesToBase64(rawSignature); final idHash = await sha256.hash(rawSignature); _id = encodeBytesToBase64(idHash.bytes); diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 8f86b9d..485edd6 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -277,8 +277,9 @@ class Transaction implements TransactionBase { @override Future sign(Wallet wallet) async { - _signature = await wallet.sign(this); - final rawSignature = decodeBase64ToBytes(_signature); + final rawSignature = await wallet.sign(this); + + _signature = encodeBytesToBase64(rawSignature); final idHash = await sha256.hash(rawSignature); _id = encodeBytesToBase64(idHash.bytes); diff --git a/lib/src/models/wallet.dart b/lib/src/models/wallet.dart index a2ac548..b5a9ea8 100644 --- a/lib/src/models/wallet.dart +++ b/lib/src/models/wallet.dart @@ -55,14 +55,8 @@ class Wallet { await _keyPair!.extractPublicKey().then((res) => res.n)); Future getAddress() async => ownerToAddress(await getOwner()); - Future sign(TransactionBase transaction) async { - return encodeBytesToBase64( - await rsaPssSign( - message: await transaction.getSignatureData(), - keyPair: _keyPair!, - ), - ); - } + Future sign(TransactionBase transaction) async => rsaPssSign( + message: await transaction.getSignatureData(), keyPair: _keyPair!); Future signMessage(Uint8List message) async => rsaPssSign(message: message, keyPair: _keyPair!); From b54c3ba11fe9d540d6a83313469f7c2712257046 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 1 Apr 2022 10:31:57 -0400 Subject: [PATCH 15/18] refactor: base64UrlEncode data PE-1136 --- lib/src/models/data_item.dart | 2 +- lib/src/models/transaction.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index bb796cd..34ed723 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -316,7 +316,7 @@ class DataItem implements TransactionBase { 'owner': owner, 'tags': tags.map((e) => e.toJson()).toList(), 'target': target, - 'data': data, + 'data': base64UrlEncode(data), 'data_size': dataSize, }; } diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 485edd6..257ab50 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -322,7 +322,7 @@ class Transaction implements TransactionBase { 'tags': tags.map((e) => e.toJson()).toList(), 'target': target, 'quantity': _bigIntToString(quantity), - 'data': data, + 'data': base64UrlEncode(data), 'data_size': dataSize, 'data_root': dataRoot, 'reward': _bigIntToString(reward), From 13da7d517418909c30d6961c440945cfeb812d24 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 1 Apr 2022 11:40:14 -0400 Subject: [PATCH 16/18] refactor: correct format and data PE-1136 --- lib/src/models/data_item.dart | 6 +++--- lib/src/models/transaction.dart | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 34ed723..284f90c 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -16,8 +16,8 @@ final MIN_BINARY_SIZE = 1044; /// Spec: https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md @JsonSerializable(explicitToJson: true) class DataItem implements TransactionBase { - @JsonKey(defaultValue: 1) - final int format = 1; + @JsonKey(defaultValue: 2) + final int format = 2; @override String get id => _id; @@ -316,7 +316,7 @@ class DataItem implements TransactionBase { 'owner': owner, 'tags': tags.map((e) => e.toJson()).toList(), 'target': target, - 'data': base64UrlEncode(data), + 'data': data, 'data_size': dataSize, }; } diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index 257ab50..ee2ac41 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -14,7 +14,7 @@ BigInt _stringToBigInt(String v) => BigInt.parse(v); @JsonSerializable(explicitToJson: true) class Transaction implements TransactionBase { - @JsonKey(defaultValue: 1) + @JsonKey(defaultValue: 2) final int format; @override @@ -322,7 +322,7 @@ class Transaction implements TransactionBase { 'tags': tags.map((e) => e.toJson()).toList(), 'target': target, 'quantity': _bigIntToString(quantity), - 'data': base64UrlEncode(data), + 'data': data, 'data_size': dataSize, 'data_root': dataRoot, 'reward': _bigIntToString(reward), From 1e47ec175a1da3acc5186503f312be677123844d Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 1 Apr 2022 14:16:31 -0400 Subject: [PATCH 17/18] refactor: update sign function PE-1136 --- lib/src/models/data_item.dart | 21 ++++++++++++++------- lib/src/models/transaction-base.dart | 6 ++++++ lib/src/models/transaction.dart | 18 +++++++++++++----- lib/src/models/wallet.dart | 13 +++++++++++-- 4 files changed, 44 insertions(+), 14 deletions(-) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 284f90c..25af8a4 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -111,6 +111,15 @@ class DataItem implements TransactionBase { @override void setOwner(String owner) => _owner = owner; + @override + void setId(String id) => _id = id; + + @override + void setSignature(String signature) => _signature = signature; + + @override + void setTags(List tags) => _tags = tags; + @override void addTag(String name, String value) { tags.add( @@ -137,14 +146,12 @@ class DataItem implements TransactionBase { /// Signs the [DataItem] using the specified wallet and sets the `id` and `signature` appropriately. @override - Future sign(Wallet wallet) async { - final rawSignature = await wallet.sign(this); - - _signature = encodeBytesToBase64(rawSignature); + Future sign(Wallet wallet) async { + final signedTransaction = await wallet.sign(this); - final idHash = await sha256.hash(rawSignature); - _id = encodeBytesToBase64(idHash.bytes); - return Uint8List.fromList(idHash.bytes); + setId(signedTransaction.id); + setSignature(signedTransaction.signature!); + setTags(signedTransaction.tags); } int getSize() { diff --git a/lib/src/models/transaction-base.dart b/lib/src/models/transaction-base.dart index 4e62432..ef05544 100644 --- a/lib/src/models/transaction-base.dart +++ b/lib/src/models/transaction-base.dart @@ -19,6 +19,12 @@ abstract class TransactionBase { void setOwner(String owner); + void setId(String id); + + void setSignature(String signature); + + void setTags(List tags); + void addTag(String name, String value); /// Returns the message that should be signed to produce a valid signature. diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index ee2ac41..d8c0655 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -174,6 +174,15 @@ class Transaction implements TransactionBase { @override void setOwner(String owner) => _owner = owner; + @override + void setId(String id) => _id = id; + + @override + void setSignature(String signature) => _signature = signature; + + @override + void setTags(List tags) => _tags = tags; + /// Sets the data and data size of this [Transaction]. /// /// Also chunks and validates the incoming data for format 2 transactions. @@ -277,12 +286,11 @@ class Transaction implements TransactionBase { @override Future sign(Wallet wallet) async { - final rawSignature = await wallet.sign(this); - - _signature = encodeBytesToBase64(rawSignature); + final signedTransaction = await wallet.sign(this); - final idHash = await sha256.hash(rawSignature); - _id = encodeBytesToBase64(idHash.bytes); + setId(signedTransaction.id); + setSignature(signedTransaction.signature!); + setTags(signedTransaction.tags); } @override diff --git a/lib/src/models/wallet.dart b/lib/src/models/wallet.dart index b5a9ea8..8ac30d2 100644 --- a/lib/src/models/wallet.dart +++ b/lib/src/models/wallet.dart @@ -55,8 +55,17 @@ class Wallet { await _keyPair!.extractPublicKey().then((res) => res.n)); Future getAddress() async => ownerToAddress(await getOwner()); - Future sign(TransactionBase transaction) async => rsaPssSign( - message: await transaction.getSignatureData(), keyPair: _keyPair!); + Future sign(TransactionBase transaction) async { + final rawSignature = await rsaPssSign( + message: await transaction.getSignatureData(), keyPair: _keyPair!); + final signature = encodeBytesToBase64(rawSignature); + + final idHash = await sha256.hash(rawSignature); + final id = encodeBytesToBase64(idHash.bytes); + return transaction + ..setId(id) + ..setSignature(signature); + } Future signMessage(Uint8List message) async => rsaPssSign(message: message, keyPair: _keyPair!); From ad6c18e7a40cc35b37e5ca666e71097f57876507 Mon Sep 17 00:00:00 2001 From: Javed Hussein Date: Fri, 1 Apr 2022 14:24:23 -0400 Subject: [PATCH 18/18] refactor: add dataitem to json PE-1136 --- lib/src/models/data_item.dart | 12 ++++++++++++ lib/src/models/data_item.g.dart | 2 ++ 2 files changed, 14 insertions(+) diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 25af8a4..08a1578 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -56,6 +56,8 @@ class DataItem implements TransactionBase { /// /// [DataItem.withJsonData()] and [DataItem.withBlobData()] are the recommended ways to construct data items. DataItem({ + String? id, + String? signature, String? owner, String? target, String? nonce, @@ -73,6 +75,13 @@ class DataItem implements TransactionBase { if (dataSize != null) { _dataSize = dataSize; } + if (signature != null) { + _signature = signature; + } + + if (id != null) { + _id = id; + } } /// Constructs a [DataItem] with the specified JSON data and appropriate Content-Type tag. @@ -317,6 +326,9 @@ class DataItem implements TransactionBase { @override Map toJson() => _$DataItemToJson(this); + factory DataItem.fromJson(Map json) => + _$DataItemFromJson(json); + @override Map toUnsignedJson() => { 'format': format, diff --git a/lib/src/models/data_item.g.dart b/lib/src/models/data_item.g.dart index 44e0c53..c06828e 100644 --- a/lib/src/models/data_item.g.dart +++ b/lib/src/models/data_item.g.dart @@ -8,12 +8,14 @@ part of 'data_item.dart'; DataItem _$DataItemFromJson(Map json) => DataItem( owner: json['owner'] as String?, + id: json['id'] as String?, target: json['target'] as String?, nonce: json['nonce'] as String?, tags: (json['tags'] as List?) ?.map((e) => Tag.fromJson(e as Map)) .toList(), data: json['data'] as String?, + signature: json['signature'] as String?, ); Map _$DataItemToJson(DataItem instance) => {