From ac2c39a81e819d106544975ca3e2c9c06ec7d448 Mon Sep 17 00:00:00 2001 From: Steven Yi Date: Fri, 15 Mar 2024 15:20:21 -0400 Subject: [PATCH 1/4] feat: added Signers to work with signing of non-arweave wallets (e.g., ETH) --- .vscode/settings.json | 2 +- example/data_bundles.dart | 4 +- example/example.dart | 2 +- lib/arweave.dart | 2 + lib/src/models/data_item.dart | 113 ++++++++++-------- lib/src/models/models.dart | 2 +- lib/src/models/transaction.dart | 18 +-- ...action-base.dart => transaction_base.dart} | 7 +- lib/src/models/transaction_stream.dart | 18 +-- lib/src/models/wallet.dart | 3 + lib/src/signature_config.dart | 65 ++++++++++ lib/src/signer.dart | 22 ++++ lib/src/streams/data_item.dart | 23 ++-- test/data_bundle_test.dart | 16 ++- test/data_item_test.dart | 8 +- test/transactions_test.dart | 13 +- test/upload_transactions_test.dart | 4 +- 17 files changed, 225 insertions(+), 97 deletions(-) rename lib/src/models/{transaction-base.dart => transaction_base.dart} (74%) create mode 100644 lib/src/signature_config.dart create mode 100644 lib/src/signer.dart diff --git a/.vscode/settings.json b/.vscode/settings.json index 79ecc5a..0600eab 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,5 @@ { "editor.codeActionsOnSave": { - "source.organizeImports": true + "source.organizeImports": "explicit" } } diff --git a/example/data_bundles.dart b/example/data_bundles.dart index 1783bee..097b64f 100644 --- a/example/data_bundles.dart +++ b/example/data_bundles.dart @@ -21,7 +21,7 @@ void main() async { ..addTag('MyTag', '0') ..addTag('OtherTag', 'Foo'); - await dataItem.sign(wallet); + await dataItem.sign(ArweaveSigner(wallet)); // Prepare a data bundle transaction. final transaction = await client.transactions.prepare( @@ -31,7 +31,7 @@ void main() async { ); // Sign the bundle transaction. - await transaction.sign(wallet); + await transaction.sign(ArweaveSigner(wallet)); // Upload the transaction. await client.transactions.post(transaction); diff --git a/example/example.dart b/example/example.dart index 627126c..912bb58 100644 --- a/example/example.dart +++ b/example/example.dart @@ -22,7 +22,7 @@ void main() async { ..addTag('App-Version', '1.0.0'); // Sign the transaction. - await transaction.sign(wallet); + await transaction.sign(ArweaveSigner(wallet)); // Upload the transaction in a single call: await client.transactions.post(transaction); diff --git a/lib/arweave.dart b/lib/arweave.dart index 17cfcb1..c901f8b 100644 --- a/lib/arweave.dart +++ b/lib/arweave.dart @@ -1,3 +1,5 @@ export './src/arweave.dart'; export './src/models/models.dart'; +export './src/signature_config.dart'; +export './src/signer.dart'; export './src/streams/streams.dart'; diff --git a/lib/src/models/data_item.dart b/lib/src/models/data_item.dart index 10e2acb..ea32449 100644 --- a/lib/src/models/data_item.dart +++ b/lib/src/models/data_item.dart @@ -1,13 +1,11 @@ import 'dart:convert'; import 'dart:typed_data'; +import 'package:arweave/arweave.dart'; import 'package:arweave/src/utils/bundle_tag_parser.dart'; import '../crypto/crypto.dart'; import '../utils.dart'; -import 'models.dart'; - -final MIN_BINARY_SIZE = 1044; /// ANS-104 [DataItem] /// Spec: https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md @@ -39,6 +37,10 @@ class DataItem implements TransactionBase { late String _signature; late ByteBuffer binary; + @override + SignatureConfig? get signatureConfig => _signatureConfig; + late SignatureConfig _signatureConfig; + /// This constructor is reserved for JSON serialisation. /// /// [DataItem.withJsonData()] and [DataItem.withBlobData()] are the recommended ways to construct data items. @@ -103,24 +105,30 @@ class DataItem implements TransactionBase { } @override - Future getSignatureData() => deepHash( - [ - utf8.encode('dataitem'), - utf8.encode('1'), //Transaction format - utf8.encode('1'), //Signature type - decodeBase64ToBytes(owner), - decodeBase64ToBytes(target), - decodeBase64ToBytes(nonce), - serializeTags(tags: tags), - data, - ], - ); + Future getSignatureData() { + print( + 'DataItem signatureType ${signatureConfig!.signatureType.toString()}'); + return deepHash( + [ + utf8.encode('dataitem'), + utf8.encode('1'), //Transaction format + utf8.encode(signatureConfig!.signatureType.toString()), //Signature type + decodeBase64ToBytes(owner), + decodeBase64ToBytes(target), + decodeBase64ToBytes(nonce), + serializeTags(tags: tags), + data, + ], + ); + } /// Signs the [DataItem] using the specified wallet and sets the `id` and `signature` appropriately. @override - Future sign(Wallet wallet) async { + Future sign(Signer signer) async { + _signatureConfig = signer.signatureConfig; + final signatureData = await getSignatureData(); - final rawSignature = await wallet.sign(signatureData); + final rawSignature = await signer.sign(signatureData); _signature = encodeBytesToBase64(rawSignature); @@ -136,8 +144,8 @@ class DataItem implements TransactionBase { final serializedTags = serializeTags(tags: tags); final tagsLength = 16 + serializedTags.lengthInBytes; - const arweaveSignerLength = 512; - const ownerLength = 512; + final arweaveSignerLength = signatureConfig!.signatureLength; + final ownerLength = signatureConfig!.publicKeyLength; const signatureTypeLength = 2; @@ -158,23 +166,34 @@ class DataItem implements TransactionBase { Future verify() async { final buffer = (await asBinary()).toBytes().buffer; try { - if (buffer.lengthInBytes < MIN_BINARY_SIZE) { + // NOTE: This was previously hardcoded to 1044, using calculation here + // factoring in singnatureConfig, but this value should be checked + final minBinarySize = 20 + + signatureConfig!.signatureLength + + signatureConfig!.publicKeyLength; + + if (buffer.lengthInBytes < minBinarySize) { return false; } final sigType = byteArrayToLong(buffer.asUint8List().sublist(0, 2)); - assert(sigType == 1); - var tagsStart = 2 + 512 + 512 + 2; - final targetPresent = buffer.asUint8List()[1026] == 1; - tagsStart += targetPresent ? 32 : 0; - final anchorPresentByte = targetPresent ? 1059 : 1027; - final anchorPresent = buffer.asUint8List()[anchorPresentByte] == 1; - tagsStart += anchorPresent ? 32 : 0; + assert(sigType == signatureConfig!.signatureType); + + final targetStart = 2 + + signatureConfig!.signatureLength + + signatureConfig!.publicKeyLength; + final targetPresent = buffer.asUint8List()[targetStart] == 1; + final anchorStart = targetStart + (targetPresent ? 33 : 1); + final anchorPresent = buffer.asUint8List()[anchorStart] == 1; + + final tagsStart = anchorStart + (anchorPresent ? 33 : 1); final numberOfTags = byteArrayToLong( buffer.asUint8List().sublist(tagsStart, tagsStart + 8)); - final numberOfTagBytesArray = - buffer.asUint8List().sublist(tagsStart + 8, tagsStart + 16); - final numberOfTagBytes = byteArrayToLong(numberOfTagBytesArray); + + // FIXME: This is not being verified + // final numberOfTagBytesArray = + // buffer.asUint8List().sublist(tagsStart + 8, tagsStart + 16); + // final numberOfTagBytes = byteArrayToLong(numberOfTagBytesArray); if (numberOfTags > 0) { try { @@ -195,12 +214,8 @@ class DataItem implements TransactionBase { if (id != expectedId) return false; - return rsaPssVerify( - input: signatureData, - signature: claimedSignatureBytes, - modulus: decodeBase64ToBigInt(owner), - publicExponent: publicExponent, - ); + return signatureConfig! + .verify(signatureData, claimedSignatureBytes, owner); } catch (_) { return false; } @@ -217,12 +232,13 @@ class DataItem implements TransactionBase { } int getTagsStart() { - var tagsStart = 2 + 512 + 512 + 2; - var targetPresent = binary.asUint8List()[1026] == 1; - tagsStart += targetPresent ? 32 : 0; - var anchorPresentByte = targetPresent ? 1059 : 1027; - var anchorPresent = binary.asUint8List()[anchorPresentByte] == 1; - tagsStart += anchorPresent ? 32 : 0; + final targetStart = + 2 + signatureConfig!.signatureLength + signatureConfig!.publicKeyLength; + final targetPresent = binary.asUint8List()[targetStart] == 1; + final anchorStart = targetStart + (targetPresent ? 33 : 1); + final anchorPresent = binary.asUint8List()[anchorStart] == 1; + + final tagsStart = anchorStart + (anchorPresent ? 33 : 1); return tagsStart; } @@ -240,14 +256,16 @@ class DataItem implements TransactionBase { // Returns the start byte of the tags section (number of tags) int getTargetStart() { - return 1026; + return 2 + + signatureConfig!.signatureLength + + signatureConfig!.publicKeyLength; } // Returns the start byte of the tags section (number of tags) int getAnchorStart() { - var anchorStart = getTargetStart() + 1; + var anchorStart = getTargetStart(); final targetPresent = binary.asUint8List()[getTargetStart()] == 1; - anchorStart += targetPresent ? 32 : 0; + anchorStart += targetPresent ? 33 : 1; return anchorStart; } @@ -259,10 +277,11 @@ class DataItem implements TransactionBase { final tags = serializeTags(tags: this.tags); // See [https://github.com/joshbenaron/arweave-standards/blob/ans104/ans/ANS-104.md#13-dataitem-format] - assert(decodedOwner.buffer.lengthInBytes == 512); + assert( + decodedOwner.buffer.lengthInBytes == signatureConfig!.publicKeyLength); final bytesBuilder = BytesBuilder(); - bytesBuilder.add(shortTo2ByteArray(1)); + bytesBuilder.add(shortTo2ByteArray(signatureConfig!.signatureType)); bytesBuilder.add(decodeBase64ToBytes(signature)); bytesBuilder.add(decodedOwner); bytesBuilder.addByte(decodedTarget.isNotEmpty ? 1 : 0); diff --git a/lib/src/models/models.dart b/lib/src/models/models.dart index 93e5e31..9fdcdef 100644 --- a/lib/src/models/models.dart +++ b/lib/src/models/models.dart @@ -3,8 +3,8 @@ export 'data_item.dart'; export 'data_item_handle.dart'; export 'id.dart'; export 'tag.dart'; -export 'transaction-base.dart'; export 'transaction.dart'; +export 'transaction_base.dart'; export 'transaction_chunk.dart'; export 'transaction_stream.dart'; export 'transaction_uploader.dart'; diff --git a/lib/src/models/transaction.dart b/lib/src/models/transaction.dart index acbda28..3cf98a1 100644 --- a/lib/src/models/transaction.dart +++ b/lib/src/models/transaction.dart @@ -66,6 +66,10 @@ class Transaction implements TransactionBase { String get signature => _signature; late String _signature; + @override + SignatureConfig? get signatureConfig => _signatureConfig; + late SignatureConfig _signatureConfig; + @JsonKey(ignore: true) TransactionChunksWithProofs? get chunks => _chunks; TransactionChunksWithProofs? _chunks; @@ -287,11 +291,13 @@ class Transaction implements TransactionBase { } @override - Future sign(Wallet wallet) async { + Future sign(Signer signer) async { final signatureData = await getSignatureData(); - final rawSignature = await wallet.sign(signatureData); + + final rawSignature = await signer.sign(signatureData); _signature = encodeBytesToBase64(rawSignature); + _signatureConfig = signer.signatureConfig; final idHash = await sha256.hash(rawSignature); _id = encodeBytesToBase64(idHash.bytes); @@ -308,12 +314,8 @@ class Transaction implements TransactionBase { if (id != expectedId) return false; - return rsaPssVerify( - input: signatureData, - signature: claimedSignatureBytes, - modulus: decodeBase64ToBigInt(owner!), - publicExponent: publicExponent, - ); + return signatureConfig! + .verify(signatureData, claimedSignatureBytes, owner!); } catch (_) { return false; } diff --git a/lib/src/models/transaction-base.dart b/lib/src/models/transaction_base.dart similarity index 74% rename from lib/src/models/transaction-base.dart rename to lib/src/models/transaction_base.dart index e3646d2..22276ae 100644 --- a/lib/src/models/transaction-base.dart +++ b/lib/src/models/transaction_base.dart @@ -1,6 +1,6 @@ import 'dart:typed_data'; -import 'models.dart'; +import 'package:arweave/arweave.dart'; abstract class TransactionBase { String get id; @@ -17,6 +17,9 @@ abstract class TransactionBase { //Null signature means the transaction hasnt been signed String? get signature; + //Null signature config means the transaction hasnt been signed + SignatureConfig? get signatureConfig; + void setOwner(String owner); void addTag(String name, String value); @@ -24,7 +27,7 @@ abstract class TransactionBase { /// Returns the message that should be signed to produce a valid signature. Future getSignatureData(); - Future sign(Wallet wallet); + Future sign(Signer signer); Future verify(); } diff --git a/lib/src/models/transaction_stream.dart b/lib/src/models/transaction_stream.dart index 856ba99..32ba1b2 100644 --- a/lib/src/models/transaction_stream.dart +++ b/lib/src/models/transaction_stream.dart @@ -6,7 +6,6 @@ import 'package:async/async.dart'; import 'package:json_annotation/json_annotation.dart'; import '../crypto/crypto.dart'; -import '../streams/data_models.dart'; import '../utils.dart'; part 'transaction_stream.g.dart'; @@ -74,6 +73,10 @@ class TransactionStream implements Transaction { String get signature => _signature; late String _signature; + @override + SignatureConfig? get signatureConfig => _signatureConfig; + late SignatureConfig _signatureConfig; + @JsonKey(ignore: true) TransactionChunksWithProofs? get chunks => _chunks; TransactionChunksWithProofs? _chunks; @@ -298,11 +301,12 @@ class TransactionStream implements Transaction { } @override - Future sign(Wallet wallet) async { + Future sign(Signer signer) async { final signatureData = await getSignatureData(); - final rawSignature = await wallet.sign(signatureData); + final rawSignature = await signer.sign(signatureData); _signature = encodeBytesToBase64(rawSignature); + _signatureConfig = signer.signatureConfig; final idHash = await sha256.hash(rawSignature); _id = encodeBytesToBase64(idHash.bytes); @@ -319,12 +323,8 @@ class TransactionStream implements Transaction { if (id != expectedId) return false; - return rsaPssVerify( - input: signatureData, - signature: claimedSignatureBytes, - modulus: decodeBase64ToBigInt(owner!), - publicExponent: publicExponent, - ); + return signatureConfig! + .verify(signatureData, claimedSignatureBytes, owner!); } catch (_) { return false; } diff --git a/lib/src/models/wallet.dart b/lib/src/models/wallet.dart index 94280b6..475dfa6 100644 --- a/lib/src/models/wallet.dart +++ b/lib/src/models/wallet.dart @@ -3,6 +3,7 @@ import 'dart:core'; import 'dart:typed_data'; import 'package:arweave/src/crypto/hmac_drbg_secure_random.dart'; +import 'package:arweave/src/signature_config.dart'; import 'package:bip39/bip39.dart' as bip39; import 'package:cryptography/cryptography.dart' hide SecureRandom; import 'package:jwk/jwk.dart'; @@ -76,6 +77,8 @@ class Wallet { Future sign(Uint8List message) async => rsaPssSign(message: message, keyPair: _keyPair!); + SignatureConfig getSignatureConfig() => SignatureConfig.arweave; + factory Wallet.fromJwk(Map jwk) { // Normalize the JWK so that it can be decoded by 'cryptography'. jwk = jwk.map((key, value) { diff --git a/lib/src/signature_config.dart b/lib/src/signature_config.dart new file mode 100644 index 0000000..c6253b6 --- /dev/null +++ b/lib/src/signature_config.dart @@ -0,0 +1,65 @@ +import 'dart:typed_data'; + +import 'package:arweave/src/crypto/crypto.dart'; +import 'package:arweave/utils.dart'; + +typedef Verifier = Future Function( + Uint8List message, Uint8List signature, String owner); + +class SignatureConfig { + final String signatureName; + final int signatureType; + final int signatureLength; + final int publicKeyLength; // OWNER + final Verifier verify; + + const SignatureConfig(this.signatureName, this.signatureType, + this.signatureLength, this.publicKeyLength, this.verify); + + /// owner corresponds to base64 representation of public key + static final SignatureConfig arweave = SignatureConfig('arweave', 1, 512, 512, + (Uint8List message, Uint8List signature, String owner) { + final publicExponent = BigInt.from(65537); + return rsaPssVerify( + input: message, + signature: signature, + modulus: decodeBase64ToBigInt(owner), + publicExponent: publicExponent, + ); + }); + + static final SignatureConfig ed25519 = SignatureConfig('ed25519', 2, 64, 32, + (Uint8List message, Uint8List signature, String owner) { + throw UnimplementedError(); + }); + + static final SignatureConfig ethereum = SignatureConfig('ethereum', 3, 65, 65, + (Uint8List message, Uint8List signature, String owner) { + throw UnimplementedError(); + }); + + static final SignatureConfig solana = SignatureConfig('solana', 4, 64, 32, + (Uint8List message, Uint8List signature, String owner) { + throw UnimplementedError(); + }); + + static final SignatureConfig injectedAptos = + SignatureConfig('injectedAptos', 5, 64, 32, + (Uint8List message, Uint8List signature, String owner) { + throw UnimplementedError(); + }); + + /// signatureLength: max 32 64 byte signatures, +4 for 32-bit bitmap + /// publicKeyLength: max 64 32 byte keys, +1 for 8-bit threshold value + static final SignatureConfig multiAptos = + SignatureConfig('multiAptos', 6, 64 * 32 + 4, 32 * 32 + 1, + (Uint8List message, Uint8List signature, String owner) { + throw UnimplementedError(); + }); + + static final SignatureConfig typedEthereum = + SignatureConfig('typedEthereum', 7, 65, 42, + (Uint8List message, Uint8List signature, String owner) { + throw UnimplementedError(); + }); +} diff --git a/lib/src/signer.dart b/lib/src/signer.dart new file mode 100644 index 0000000..a880b8a --- /dev/null +++ b/lib/src/signer.dart @@ -0,0 +1,22 @@ +import 'dart:typed_data'; + +import 'package:arweave/arweave.dart'; + +abstract class Signer { + SignatureConfig get signatureConfig; + Future sign(Uint8List message); +} + +class ArweaveSigner implements Signer { + final Wallet wallet; + + ArweaveSigner(this.wallet); + + @override + SignatureConfig get signatureConfig => SignatureConfig.arweave; + + @override + Future sign(Uint8List message) { + return wallet.sign(message); + } +} diff --git a/lib/src/streams/data_item.dart b/lib/src/streams/data_item.dart index e47257c..88493ba 100644 --- a/lib/src/streams/data_item.dart +++ b/lib/src/streams/data_item.dart @@ -2,17 +2,15 @@ import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; +import 'package:arweave/arweave.dart'; +import 'package:arweave/src/utils.dart'; import 'package:arweave/src/utils/bundle_tag_parser.dart'; import 'package:arweave/utils.dart'; import 'package:async/async.dart'; import 'package:fpdart/fpdart.dart'; import '../crypto/crypto.dart'; -import '../models/models.dart'; -import 'data_models.dart'; import 'errors.dart'; -import 'utils.dart'; -import 'deep_hash_stream.dart'; DataItemTaskEither createDataItemTaskEither({ required final Wallet wallet, @@ -80,6 +78,7 @@ Future processDataItem({ required Stream Function() dataItemStreamGenerator, required String id, required int length, + required SignatureConfig signatureConfig, }) async { int byteIndex = 0; final reader = ChunkedStreamReader(dataItemStreamGenerator()); @@ -89,12 +88,12 @@ Future processDataItem({ byteIndex += 2; // get signature - final signature = await reader.readBytes(512); - byteIndex += 512; + final signature = await reader.readBytes(signatureConfig.signatureLength); + byteIndex += signatureConfig.signatureLength; // get owner - final owner = await reader.readChunk(512); - byteIndex += 512; + final owner = await reader.readChunk(signatureConfig.publicKeyLength); + byteIndex += signatureConfig.publicKeyLength; // get target final targetExists = (await reader.readChunk(1))[0] == 1; @@ -156,12 +155,8 @@ Future processDataItem({ throw Exception("ID doesn't match signature"); } - final signVerification = await rsaPssVerify( - input: signatureData, - signature: signature, - modulus: decodeBytesToBigInt(owner), - publicExponent: publicExponent, - ); + final signVerification = await signatureConfig.verify( + signatureData, signature, encodeBytesToBase64(owner)); if (!signVerification) { throw Exception("Invalid signature"); diff --git a/test/data_bundle_test.dart b/test/data_bundle_test.dart index 37aef11..7bcc7fe 100644 --- a/test/data_bundle_test.dart +++ b/test/data_bundle_test.dart @@ -16,6 +16,7 @@ void main() async { group('DataItem:', () { test('create, sign, and verify data item', () async { final wallet = getTestWallet(); + final signer = ArweaveSigner(wallet); final dataItem = DataItem.withBlobData( owner: await wallet.getOwner(), data: utf8.encode('HELLOWORLD_TEST_STRING') as Uint8List) @@ -23,13 +24,14 @@ void main() async { ..addTag('OtherTag', 'Foo') ..addTag('MyTag', '1'); - await dataItem.sign(wallet); + await dataItem.sign(signer); expect(await dataItem.verify(), isTrue); }); test('confirm data item with wrong signaure fails verify', () async { final wallet = getTestWallet(); + final signer = ArweaveSigner(wallet); final dataItem = DataItem.withBlobData( owner: await wallet.getOwner(), data: utf8.encode('HELLOWORLD_TEST_STRING') as Uint8List) @@ -37,7 +39,7 @@ void main() async { ..addTag('OtherTag', 'Foo') ..addTag('MyTag', '1'); - await dataItem.sign(wallet); + await dataItem.sign(signer); dataItem.addTag('MyTag', '2'); expect(await dataItem.verify(), isFalse); @@ -46,6 +48,7 @@ void main() async { test('create data bundle', () async { final wallet = getTestWallet(); + final signer = ArweaveSigner(wallet); final dataItemOne = DataItem.withBlobData( owner: await wallet.getOwner(), @@ -53,14 +56,14 @@ void main() async { ..addTag('MyTag', '0') ..addTag('OtherTag', 'Foo') ..addTag('MyTag', '1'); - await dataItemOne.sign(wallet); + await dataItemOne.sign(signer); final dataItemTwo = DataItem.withBlobData( owner: await wallet.getOwner(), data: utf8.encode('HELLOWORLD_TEST_STRING_2') as Uint8List) ..addTag('MyTag', '0') ..addTag('OtherTag', 'Foo') ..addTag('MyTag', '1'); - await dataItemTwo.sign(wallet); + await dataItemTwo.sign(signer); final items = [dataItemOne, dataItemTwo]; final bundle = await DataBundle.fromDataItems(items: items); expect(bundle.blob, isNotEmpty); @@ -71,6 +74,7 @@ void main() async { test('create data bundle with large files', () async { final wallet = getTestWallet(); + final signer = ArweaveSigner(wallet); final testData = generateByteList(5); expect(await deepHash([testData]), equals(testFileHash)); @@ -80,14 +84,14 @@ void main() async { ..addTag('MyTag', '0') ..addTag('OtherTag', 'Foo') ..addTag('MyTag', '1'); - await dataItemOne.sign(wallet); + await dataItemOne.sign(signer); final dataItemTwo = DataItem.withBlobData(owner: await wallet.getOwner(), data: testData) ..addTag('MyTag', '0') ..addTag('OtherTag', 'Foo') ..addTag('MyTag', '1'); - await dataItemTwo.sign(wallet); + await dataItemTwo.sign(signer); final items = [dataItemOne, dataItemTwo]; final bundle = await DataBundle.fromDataItems(items: items); diff --git a/test/data_item_test.dart b/test/data_item_test.dart index f0db89d..b6e36c8 100644 --- a/test/data_item_test.dart +++ b/test/data_item_test.dart @@ -1,14 +1,16 @@ import 'dart:convert'; import 'dart:typed_data'; +import 'package:arweave/src/signer.dart'; import 'package:arweave/src/streams/data_item.dart'; import 'package:arweave/src/streams/data_models.dart'; import 'package:arweave/src/streams/errors.dart'; import 'package:arweave/src/streams/utils.dart'; import 'package:fpdart/fpdart.dart'; import 'package:test/test.dart'; -import 'fixtures/test_wallet.dart'; + import 'deserialize_tags.dart' if (dart.library.io) 'deserialize_tags_io.dart'; +import 'fixtures/test_wallet.dart'; void main() async { final wallet = getTestWallet(); @@ -147,6 +149,7 @@ void main() async { dataStream: dataStreamGenerator, dataStreamSize: data.length, ); + final signer = ArweaveSigner(wallet); final dataItemTask = await dataItemTaskEither.run(); @@ -159,6 +162,7 @@ void main() async { dataItemStreamGenerator: dataItem.streamGenerator, id: dataItem.id, length: dataItem.dataItemSize, + signatureConfig: signer.signatureConfig, ); expect(processedDataItem.id, expectedDataItemId); @@ -185,6 +189,7 @@ void main() async { dataStream: dataStreamGenerator, dataStreamSize: data.length, ); + final signer = ArweaveSigner(wallet); final dataItemTask = await dataItemTaskEither.run(); @@ -197,6 +202,7 @@ void main() async { dataItemStreamGenerator: dataItem.streamGenerator, id: dataItem.id, length: dataItem.dataItemSize, + signatureConfig: signer.signatureConfig, ); final deserializedTags = deserializeTags(buffer: processedDataItem.tags); diff --git a/test/transactions_test.dart b/test/transactions_test.dart index 09dcad1..c150248 100644 --- a/test/transactions_test.dart +++ b/test/transactions_test.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:arweave/arweave.dart'; +import 'package:arweave/src/signer.dart'; import 'package:arweave/utils.dart' as utils; import 'package:test/test.dart'; @@ -20,6 +21,7 @@ void main() { test('create, sign, and verify data transaction', () async { final wallet = await getTestWallet(); + final signer = ArweaveSigner(wallet); final transaction = await client.transactions.prepare( Transaction.withBlobData(data: utf8.encode('test') as Uint8List), @@ -34,7 +36,7 @@ void main() { expect(transaction.lastTx, matches(transactionFieldPattern)); expect(transaction.reward.toInt(), greaterThan(0)); - await transaction.sign(wallet); + await transaction.sign(signer); expect(transaction.signature, matches(signaturePattern)); expect(transaction.id, matches(digestPattern)); @@ -49,6 +51,7 @@ void main() { test('create, sign, and verify AR transaction', () async { final wallet = await getTestWallet(); + final signer = ArweaveSigner(wallet); final transaction = await client.transactions.prepare( Transaction( @@ -61,7 +64,7 @@ void main() { expect(transaction.target, equals('GRQ7swQO1AMyFgnuAPI7AvGQlW3lzuQuwlJbIpWV7xk')); - await transaction.sign(wallet); + await transaction.sign(signer); expect(transaction.signature, matches(signaturePattern)); expect(transaction.id, matches(digestPattern)); @@ -75,6 +78,7 @@ void main() { test('sign v2 transaction', () async { final wallet = await getTestWallet(); + final signer = ArweaveSigner(wallet); final signedV2Tx = await getTestTransaction('test/fixtures/signed_v2_tx.json'); final unsignedV2Tx = @@ -90,7 +94,7 @@ void main() { tx.setLastTx(''); - await tx.sign(wallet); + await tx.sign(signer); expect(tx.dataRoot, signedV2Tx.dataRoot); expect(tx.signature, signedV2Tx.signature); @@ -159,6 +163,7 @@ void main() { group('stream', (() { test('create, sign, and verify data transaction', () async { final wallet = await getTestWallet(); + final signer = ArweaveSigner(wallet); const fileName = 'test/fixtures/lotsofdata.bin'; final fileStreamMeta = await getFileStreamMeta(fileName); @@ -179,7 +184,7 @@ void main() { expect(transaction.lastTx, matches(transactionFieldPattern)); expect(transaction.reward.toInt(), greaterThan(0)); - await transaction.sign(wallet); + await transaction.sign(signer); expect(transaction.signature, matches(signaturePattern)); expect(transaction.id, matches(digestPattern)); diff --git a/test/upload_transactions_test.dart b/test/upload_transactions_test.dart index 16901f1..9eca4da 100644 --- a/test/upload_transactions_test.dart +++ b/test/upload_transactions_test.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'package:arweave/arweave.dart'; +import 'package:arweave/src/signer.dart'; import 'package:arweave/utils.dart' as utils; import 'package:test/test.dart'; @@ -34,6 +35,7 @@ void main() { test('successfully upload AR only transaction', () async { final wallet = await getTestWallet(); + final signer = ArweaveSigner(wallet); final transaction = await client.transactions.prepare( Transaction( @@ -43,7 +45,7 @@ void main() { wallet, ); - await transaction.sign(wallet); + await transaction.sign(signer); expect( client.transactions.upload(transaction), From 0721b5c6dfe0867c7d795085981a8ffca088a38f Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Mon, 15 Apr 2024 18:16:18 -0300 Subject: [PATCH 2/4] fix --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 3e0d7d2..7344e53 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: json_annotation: ^4.0.1 jwk: ^0.1.0 meta: ^1.7.0 - pointycastle: ^3.1.1 + pointycastle: ^3.7.4 built_value: ^8.0.6 js: ^0.6.3 retry: ^3.1.0 From 82a86f85f6785dd7ea522c33bbbda6903de6d00c Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Mon, 15 Apr 2024 18:18:53 -0300 Subject: [PATCH 3/4] fix --- pubspec.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 7344e53..8d22a3c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: json_annotation: ^4.0.1 jwk: ^0.1.0 meta: ^1.7.0 - pointycastle: ^3.7.4 + pointycastle: 3.7.4 built_value: ^8.0.6 js: ^0.6.3 retry: ^3.1.0 @@ -30,6 +30,8 @@ dependencies: dependency_overrides: fetch_api: 1.0.1 + pointycastle: 3.7.4 + dev_dependencies: build_runner: ^2.0.4 From 52f7a8276099edb2ca402a85145e7ebb3b406f5f Mon Sep 17 00:00:00 2001 From: Thiago Carvalho Date: Mon, 15 Apr 2024 18:23:54 -0300 Subject: [PATCH 4/4] bump version --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 8d22a3c..af24421 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: arweave description: "" -version: 3.8.3 +version: 3.9.0 environment: sdk: ">=3.0.0 <4.0.0" publish_to: none