From fc0486187354bb19a331bb53a6dffd54b90b3186 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 6 May 2024 15:19:05 -0700 Subject: [PATCH 1/4] add script to generate test vectors folder --- generate_vectors.dart | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 generate_vectors.dart diff --git a/generate_vectors.dart b/generate_vectors.dart new file mode 100644 index 0000000..683c7a8 --- /dev/null +++ b/generate_vectors.dart @@ -0,0 +1,55 @@ +import 'dart:io'; +import 'package:path/path.dart' as p; + +void main() { + final vectorsPath = + p.join('tbdex', 'hosted', 'test-vectors', 'protocol', 'vectors'); + final outputDir = Directory('test/protocol/test_vectors') + ..createSync(recursive: true); + + Directory(vectorsPath) + .listSync() + .whereType() + .where((file) => file.path.endsWith('.json')) + .forEach((file) { + final json = file.readAsStringSync(); + final dartCode = _generateCode(file.path, json); + + File(p.join(outputDir.path, '${_getFileName(file.path)}.dart')) + .writeAsStringSync(dartCode); + }); +} + +String _generateCode(String filePath, String jsonString) => ''' +class ${_getClassName(filePath)} { + static const String vector = r\'\'\' + $jsonString\'\'\'; +}'''; + +String _getFileName(String filePath) { + var segments = p.split(filePath); + final index = segments.indexOf('vectors'); + print(segments); + final baseName = segments[index + 1].split('.').first; + + return _toSnakeCase(baseName); +} + +String _getClassName(String filePath) { + var segments = p.split(filePath); + final index = segments.indexOf('vectors'); + final baseName = segments[index + 1].split('.').first; + + return _toCamelCase(baseName); +} + +String _toSnakeCase(String input) => input.replaceAll('-', '_').toLowerCase(); + +String _toCamelCase(String input) => input + .split(RegExp('[_-]')) + .map( + (str) => str.isEmpty + ? '' + : str[0].toUpperCase() + str.substring(1).toLowerCase(), + ) + .join(); From 9aae0809289665bca53383940f4f0cb9cebba11a Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 6 May 2024 15:19:16 -0700 Subject: [PATCH 2/4] add just command to generate vectors --- Justfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Justfile b/Justfile index 211005c..9a26dca 100644 --- a/Justfile +++ b/Justfile @@ -2,6 +2,10 @@ schemas: #!/bin/bash dart run generate_schemas.dart +vectors: + #!/bin/bash + dart run generate_vectors.dart + get: @dart pub get From 803c31c15a6a438e9a0810d1130f55bd5d197660 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 6 May 2024 15:19:30 -0700 Subject: [PATCH 3/4] add test vectors --- test/protocol/test_vectors/parse_balance.dart | 22 ++++ test/protocol/test_vectors/parse_close.dart | 24 ++++ .../protocol/test_vectors/parse_offering.dart | 111 ++++++++++++++++++ test/protocol/test_vectors/parse_order.dart | 22 ++++ .../test_vectors/parse_orderstatus.dart | 23 ++++ test/protocol/test_vectors/parse_quote.dart | 40 +++++++ test/protocol/test_vectors/parse_rfq.dart | 52 ++++++++ .../parse_rfq_omit_private_data.dart | 33 ++++++ 8 files changed, 327 insertions(+) create mode 100644 test/protocol/test_vectors/parse_balance.dart create mode 100644 test/protocol/test_vectors/parse_close.dart create mode 100644 test/protocol/test_vectors/parse_offering.dart create mode 100644 test/protocol/test_vectors/parse_order.dart create mode 100644 test/protocol/test_vectors/parse_orderstatus.dart create mode 100644 test/protocol/test_vectors/parse_quote.dart create mode 100644 test/protocol/test_vectors/parse_rfq.dart create mode 100644 test/protocol/test_vectors/parse_rfq_omit_private_data.dart diff --git a/test/protocol/test_vectors/parse_balance.dart b/test/protocol/test_vectors/parse_balance.dart new file mode 100644 index 0000000..4faa6ef --- /dev/null +++ b/test/protocol/test_vectors/parse_balance.dart @@ -0,0 +1,22 @@ +class ParseBalance { + static const String vector = r''' + { + "description": "Balance parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"kind\":\"balance\",\"id\":\"balance_01hw25hn2pej6rdnd5qnh96wxj\",\"createdAt\":\"2024-04-22T05:48:01.494Z\",\"protocol\":\"1.0\"},\"data\":{\"currencyCode\":\"USD\",\"available\":\"400.00\"},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..v6cJEJuEOjCes3-7UJvkyMgPRUk9dD3h_COfjSEQJiNMpQ7DOMTnFAVd-g_gsO4Y5FBqnKT8B9N86pFPoebNCQ\"}", + "output": { + "metadata": { + "from": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "kind": "balance", + "id": "balance_01hw25hn2pej6rdnd5qnh96wxj", + "createdAt": "2024-04-22T05:48:01.494Z", + "protocol": "1.0" + }, + "data": { + "currencyCode": "USD", + "available": "400.00" + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..v6cJEJuEOjCes3-7UJvkyMgPRUk9dD3h_COfjSEQJiNMpQ7DOMTnFAVd-g_gsO4Y5FBqnKT8B9N86pFPoebNCQ" + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_close.dart b/test/protocol/test_vectors/parse_close.dart new file mode 100644 index 0000000..ac8cb75 --- /dev/null +++ b/test/protocol/test_vectors/parse_close.dart @@ -0,0 +1,24 @@ +class ParseClose { + static const String vector = r''' + { + "description": "Close parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"to\":\"did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y\",\"exchangeId\":\"rfq_01hw25hn2xffnv99m4rb9r8rth\",\"protocol\":\"1.0\",\"kind\":\"close\",\"id\":\"close_01hw25hn2xffnv99m4rehcmj53\",\"createdAt\":\"2024-04-22T05:48:01.501Z\"},\"data\":{\"reason\":\"The reason for closing the exchange\",\"success\":true},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..ZvoVDuSrqqdXsSXgqB-U26tAU1WqUqqU_KpD1KvdYocIcmTsshjUASEwM_lUz1UnGglqkWeCIrHqrm9NNGDqBw\"}", + "output": { + "metadata": { + "from": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "to": "did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y", + "exchangeId": "rfq_01hw25hn2xffnv99m4rb9r8rth", + "protocol": "1.0", + "kind": "close", + "id": "close_01hw25hn2xffnv99m4rehcmj53", + "createdAt": "2024-04-22T05:48:01.501Z" + }, + "data": { + "reason": "The reason for closing the exchange", + "success": true + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..ZvoVDuSrqqdXsSXgqB-U26tAU1WqUqqU_KpD1KvdYocIcmTsshjUASEwM_lUz1UnGglqkWeCIrHqrm9NNGDqBw" + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_offering.dart b/test/protocol/test_vectors/parse_offering.dart new file mode 100644 index 0000000..97e24d7 --- /dev/null +++ b/test/protocol/test_vectors/parse_offering.dart @@ -0,0 +1,111 @@ +class ParseOffering { + static const String vector = r''' + { + "description": "Offering parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:c765ni81pupn5zc646xskdsufgokstbsgfwhae8hudsrjushhruy\",\"kind\":\"offering\",\"id\":\"offering_01hwcg100gf8btevp8x3pea75b\",\"createdAt\":\"2024-04-26T06:03:34.289Z\",\"protocol\":\"1.0\"},\"data\":{\"description\":\"Selling BTC for USD\",\"payin\":{\"currencyCode\":\"USD\",\"min\":\"0.0\",\"max\":\"999999.99\",\"methods\":[{\"kind\":\"DEBIT_CARD\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"properties\":{\"cardNumber\":{\"type\":\"string\",\"description\":\"The 16-digit debit card number\",\"minLength\":16,\"maxLength\":16},\"expiryDate\":{\"type\":\"string\",\"description\":\"The expiry date of the card in MM/YY format\",\"pattern\":\"^(0[1-9]|1[0-2])\\\\/([0-9]{2})$\"},\"cardHolderName\":{\"type\":\"string\",\"description\":\"Name of the cardholder as it appears on the card\"},\"cvv\":{\"type\":\"string\",\"description\":\"The 3-digit CVV code\",\"minLength\":3,\"maxLength\":3}},\"required\":[\"cardNumber\",\"expiryDate\",\"cardHolderName\",\"cvv\"],\"additionalProperties\":false}}]},\"payout\":{\"currencyCode\":\"BTC\",\"max\":\"999526.11\",\"methods\":[{\"kind\":\"BTC_ADDRESS\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema#\",\"type\":\"object\",\"properties\":{\"btcAddress\":{\"type\":\"string\",\"description\":\"your Bitcoin wallet address\"}},\"required\":[\"btcAddress\"],\"additionalProperties\":false},\"estimatedSettlementTime\":10}]},\"payoutUnitsPerPayinUnit\":\"0.00003826\",\"requiredClaims\":{\"id\":\"7ce4004c-3c38-4853-968b-e411bafcd945\",\"input_descriptors\":[{\"id\":\"bbdb9b7c-5754-4f46-b63b-590bada959e0\",\"constraints\":{\"fields\":[{\"path\":[\"$.type[*]\"],\"filter\":{\"type\":\"string\",\"pattern\":\"^YoloCredential$\"}}]}}]}},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6Yzc2NW5pODFwdXBuNXpjNjQ2eHNrZHN1Zmdva3N0YnNnZndoYWU4aHVkc3JqdXNoaHJ1eSMwIn0..ciWPR5RGHxfQZJUKw3Z2np6EtVJ0wQMZBsNoFjJ-W11x1NmmZCfSkbRAES0eoGlu0Wlyf4waHKvN0UdunakgCw\"}", + "output": { + "metadata": { + "from": "did:dht:c765ni81pupn5zc646xskdsufgokstbsgfwhae8hudsrjushhruy", + "kind": "offering", + "id": "offering_01hwcg100gf8btevp8x3pea75b", + "createdAt": "2024-04-26T06:03:34.289Z", + "protocol": "1.0" + }, + "data": { + "description": "Selling BTC for USD", + "payin": { + "currencyCode": "USD", + "min": "0.0", + "max": "999999.99", + "methods": [ + { + "kind": "DEBIT_CARD", + "requiredPaymentDetails": { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "cardNumber": { + "type": "string", + "description": "The 16-digit debit card number", + "minLength": 16, + "maxLength": 16 + }, + "expiryDate": { + "type": "string", + "description": "The expiry date of the card in MM/YY format", + "pattern": "^(0[1-9]|1[0-2])\\/([0-9]{2})$" + }, + "cardHolderName": { + "type": "string", + "description": "Name of the cardholder as it appears on the card" + }, + "cvv": { + "type": "string", + "description": "The 3-digit CVV code", + "minLength": 3, + "maxLength": 3 + } + }, + "required": [ + "cardNumber", + "expiryDate", + "cardHolderName", + "cvv" + ], + "additionalProperties": false + } + } + ] + }, + "payout": { + "currencyCode": "BTC", + "max": "999526.11", + "methods": [ + { + "kind": "BTC_ADDRESS", + "requiredPaymentDetails": { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "btcAddress": { + "type": "string", + "description": "your Bitcoin wallet address" + } + }, + "required": [ + "btcAddress" + ], + "additionalProperties": false + }, + "estimatedSettlementTime": 10 + } + ] + }, + "payoutUnitsPerPayinUnit": "0.00003826", + "requiredClaims": { + "id": "7ce4004c-3c38-4853-968b-e411bafcd945", + "input_descriptors": [ + { + "id": "bbdb9b7c-5754-4f46-b63b-590bada959e0", + "constraints": { + "fields": [ + { + "path": [ + "$.type[*]" + ], + "filter": { + "type": "string", + "pattern": "^YoloCredential$" + } + } + ] + } + } + ] + } + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6Yzc2NW5pODFwdXBuNXpjNjQ2eHNrZHN1Zmdva3N0YnNnZndoYWU4aHVkc3JqdXNoaHJ1eSMwIn0..ciWPR5RGHxfQZJUKw3Z2np6EtVJ0wQMZBsNoFjJ-W11x1NmmZCfSkbRAES0eoGlu0Wlyf4waHKvN0UdunakgCw" + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_order.dart b/test/protocol/test_vectors/parse_order.dart new file mode 100644 index 0000000..b29e9a2 --- /dev/null +++ b/test/protocol/test_vectors/parse_order.dart @@ -0,0 +1,22 @@ +class ParseOrder { + static const String vector = r''' + { + "description": "Order parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y\",\"to\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"exchangeId\":\"rfq_01hw25hn38fg8sz07yn8dknvjy\",\"externalId\":\"ext_1234\",\"protocol\":\"1.0\",\"kind\":\"order\",\"id\":\"order_01hw25hn38fg8sz07ynfn8vwmb\",\"createdAt\":\"2024-04-22T05:48:01.512Z\"},\"data\":{},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0..dwoJjm0Ixh6GnwSOhx1AOo9dSHOWNMC_mqM4s-dDhJR0HQI47vD1uemqFSgSZaB9qNUqZawoCcqbhv4fSlO5Ag\"}", + "output": { + "metadata": { + "from": "did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y", + "to": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "exchangeId": "rfq_01hw25hn38fg8sz07yn8dknvjy", + "externalId": "ext_1234", + "protocol": "1.0", + "kind": "order", + "id": "order_01hw25hn38fg8sz07ynfn8vwmb", + "createdAt": "2024-04-22T05:48:01.512Z" + }, + "data": {}, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0..dwoJjm0Ixh6GnwSOhx1AOo9dSHOWNMC_mqM4s-dDhJR0HQI47vD1uemqFSgSZaB9qNUqZawoCcqbhv4fSlO5Ag" + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_orderstatus.dart b/test/protocol/test_vectors/parse_orderstatus.dart new file mode 100644 index 0000000..83f9c72 --- /dev/null +++ b/test/protocol/test_vectors/parse_orderstatus.dart @@ -0,0 +1,23 @@ +class ParseOrderstatus { + static const String vector = r''' + { + "description": "Order Status parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"to\":\"did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y\",\"exchangeId\":\"rfq_01hw25hn39ermsmftw3a3rb1ph\",\"protocol\":\"1.0\",\"kind\":\"orderstatus\",\"id\":\"orderstatus_01hw25hn39ermsmftw3d1efc2f\",\"createdAt\":\"2024-04-22T05:48:01.513Z\"},\"data\":{\"orderStatus\":\"wee\"},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..alR9hfgjKSbSEmuXi1fpA7Puh5JNp22uDqk2b5zGcbvbgUsDCkChBQ47SWjAV5BchmfZ0yaDLPQPTxiH918jBQ\"}", + "output": { + "metadata": { + "from": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "to": "did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y", + "exchangeId": "rfq_01hw25hn39ermsmftw3a3rb1ph", + "protocol": "1.0", + "kind": "orderstatus", + "id": "orderstatus_01hw25hn39ermsmftw3d1efc2f", + "createdAt": "2024-04-22T05:48:01.513Z" + }, + "data": { + "orderStatus": "wee" + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..alR9hfgjKSbSEmuXi1fpA7Puh5JNp22uDqk2b5zGcbvbgUsDCkChBQ47SWjAV5BchmfZ0yaDLPQPTxiH918jBQ" + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_quote.dart b/test/protocol/test_vectors/parse_quote.dart new file mode 100644 index 0000000..c0c38e6 --- /dev/null +++ b/test/protocol/test_vectors/parse_quote.dart @@ -0,0 +1,40 @@ +class ParseQuote { + static const String vector = r''' + { + "description": "Quote parses from string", + "input": "{\"metadata\":{\"exchangeId\":\"rfq_01hw25hn2te5rt4c6fnkb877xg\",\"from\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"to\":\"did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y\",\"protocol\":\"1.0\",\"kind\":\"quote\",\"id\":\"quote_01hw25hn2vfd0944t9xp7jbx0t\",\"createdAt\":\"2024-04-22T05:48:01.499Z\"},\"data\":{\"expiresAt\":\"2024-04-22T05:48:01.499Z\",\"payin\":{\"currencyCode\":\"BTC\",\"amount\":\"0.01\",\"fee\":\"0.0001\",\"paymentInstruction\":{\"link\":\"tbdex.io/example\",\"instruction\":\"Fake instruction\"}},\"payout\":{\"currencyCode\":\"USD\",\"amount\":\"1000.00\",\"paymentInstruction\":{\"link\":\"tbdex.io/example\",\"instruction\":\"Fake instruction\"}}},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..sHQBr_s8EEx81hf4I8-qaY_ya4wWtE_wN93YY5-y22bG9RyiX4PAnwJUQJewa8STrK-M38yVNQDaBnqs1O9WAQ\"}", + "output": { + "metadata": { + "exchangeId": "rfq_01hw25hn2te5rt4c6fnkb877xg", + "from": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "to": "did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y", + "protocol": "1.0", + "kind": "quote", + "id": "quote_01hw25hn2vfd0944t9xp7jbx0t", + "createdAt": "2024-04-22T05:48:01.499Z" + }, + "data": { + "expiresAt": "2024-04-22T05:48:01.499Z", + "payin": { + "currencyCode": "BTC", + "amount": "0.01", + "fee": "0.0001", + "paymentInstruction": { + "link": "tbdex.io/example", + "instruction": "Fake instruction" + } + }, + "payout": { + "currencyCode": "USD", + "amount": "1000.00", + "paymentInstruction": { + "link": "tbdex.io/example", + "instruction": "Fake instruction" + } + } + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6M3doZnRncGJkamloeDl6ZTl0ZG41NzV6cXptNHF3Y2NldG5mMXliaWlidXphZDdycm15eSMwIn0..sHQBr_s8EEx81hf4I8-qaY_ya4wWtE_wN93YY5-y22bG9RyiX4PAnwJUQJewa8STrK-M38yVNQDaBnqs1O9WAQ" + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_rfq.dart b/test/protocol/test_vectors/parse_rfq.dart new file mode 100644 index 0000000..17bcd6c --- /dev/null +++ b/test/protocol/test_vectors/parse_rfq.dart @@ -0,0 +1,52 @@ +class ParseRfq { + static const String vector = r''' + { + "description": "RFQ parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y\",\"to\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"protocol\":\"1.0\",\"kind\":\"rfq\",\"id\":\"rfq_01hw25hn32f2rrbxxrscfce76a\",\"exchangeId\":\"rfq_01hw25hn32f2rrbxxrscfce76a\",\"createdAt\":\"2024-04-22T05:48:01.506Z\"},\"data\":{\"offeringId\":\"offering_01hw25hn32f2rrbxxrs91eh3dz\",\"payin\":{\"kind\":\"DEBIT_CARD\",\"amount\":\"20000.00\",\"paymentDetailsHash\":\"-qyAULSCWs_NvbKpN7-uPvKzRl5aWWlUgqSuitKKQQw\"},\"payout\":{\"kind\":\"BTC_ADDRESS\",\"paymentDetailsHash\":\"tDJ0QRBRkfOM_i0Yq96Ble4aFRn6SgJa07lhPusQxRw\"},\"claimsHash\":\"3e2RPtam5xuFmmq_MbO3QLFj86ylFSe-nxA-mhlFSH8\"},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0..1ujzgRCxChND0mdKlwwSw9w23LubZ1H8yBvspDUz-RCdKa3XaOHdlwWvSeZCwW4DJxJoN5rY0UlwqIBKB4R6AA\",\"privateData\":{\"salt\":\"w9LebtsDQhEMMOBXzfs2JA\",\"payin\":{\"paymentDetails\":{\"cardNumber\":\"1234567890123456\",\"expiryDate\":\"12/22\",\"cardHolderName\":\"Ephraim Bartholomew Winthrop\",\"cvv\":\"123\"}},\"payout\":{\"paymentDetails\":{\"btcAddress\":\"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa\"}},\"claims\":[\"eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiUHV1cHV1Q3JlZGVudGlhbCJdLCJpZCI6InVybjp1dWlkOjU4ZDZlYjFjLTE3M2ItNDc4OS1iZmVhLTZmYzAwMTRjNzI5NyIsImlzc3VlciI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDQtMjJUMDU6NDg6MDFaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnF5YWM0cHJ1OXlrY3hicnV0cGFheGttdXN1c3hoNHd0YzRjdHQxOTgxM3pyaWU4dXl5NXkiLCJiZWVwIjoiYm9vcCJ9fSwibmJmIjoxNzEzNzY0ODgxLCJqdGkiOiJ1cm46dXVpZDo1OGQ2ZWIxYy0xNzNiLTQ3ODktYmZlYS02ZmMwMDE0YzcyOTciLCJpc3MiOiJkaWQ6ZGh0OnF5YWM0cHJ1OXlrY3hicnV0cGFheGttdXN1c3hoNHd0YzRjdHQxOTgxM3pyaWU4dXl5NXkiLCJzdWIiOiJkaWQ6ZGh0OnF5YWM0cHJ1OXlrY3hicnV0cGFheGttdXN1c3hoNHd0YzRjdHQxOTgxM3pyaWU4dXl5NXkiLCJpYXQiOjE3MTM3NjQ4ODF9.j90ud9-fl_UrhA5fMfApBOxu3IwLnn_Wq7cugLEaoENdzv14W-jWOuL7mCFy1bCF95PWK6RliZQEqdJZnOw6Dg\"]}}", + "output": { + "metadata": { + "from": "did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y", + "to": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "protocol": "1.0", + "kind": "rfq", + "id": "rfq_01hw25hn32f2rrbxxrscfce76a", + "exchangeId": "rfq_01hw25hn32f2rrbxxrscfce76a", + "createdAt": "2024-04-22T05:48:01.506Z" + }, + "data": { + "offeringId": "offering_01hw25hn32f2rrbxxrs91eh3dz", + "payin": { + "kind": "DEBIT_CARD", + "amount": "20000.00", + "paymentDetailsHash": "-qyAULSCWs_NvbKpN7-uPvKzRl5aWWlUgqSuitKKQQw" + }, + "payout": { + "kind": "BTC_ADDRESS", + "paymentDetailsHash": "tDJ0QRBRkfOM_i0Yq96Ble4aFRn6SgJa07lhPusQxRw" + }, + "claimsHash": "3e2RPtam5xuFmmq_MbO3QLFj86ylFSe-nxA-mhlFSH8" + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0..1ujzgRCxChND0mdKlwwSw9w23LubZ1H8yBvspDUz-RCdKa3XaOHdlwWvSeZCwW4DJxJoN5rY0UlwqIBKB4R6AA", + "privateData": { + "salt": "w9LebtsDQhEMMOBXzfs2JA", + "payin": { + "paymentDetails": { + "cardNumber": "1234567890123456", + "expiryDate": "12/22", + "cardHolderName": "Ephraim Bartholomew Winthrop", + "cvv": "123" + } + }, + "payout": { + "paymentDetails": { + "btcAddress": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa" + } + }, + "claims": [ + "eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiUHV1cHV1Q3JlZGVudGlhbCJdLCJpZCI6InVybjp1dWlkOjU4ZDZlYjFjLTE3M2ItNDc4OS1iZmVhLTZmYzAwMTRjNzI5NyIsImlzc3VlciI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSIsImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDQtMjJUMDU6NDg6MDFaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZGh0OnF5YWM0cHJ1OXlrY3hicnV0cGFheGttdXN1c3hoNHd0YzRjdHQxOTgxM3pyaWU4dXl5NXkiLCJiZWVwIjoiYm9vcCJ9fSwibmJmIjoxNzEzNzY0ODgxLCJqdGkiOiJ1cm46dXVpZDo1OGQ2ZWIxYy0xNzNiLTQ3ODktYmZlYS02ZmMwMDE0YzcyOTciLCJpc3MiOiJkaWQ6ZGh0OnF5YWM0cHJ1OXlrY3hicnV0cGFheGttdXN1c3hoNHd0YzRjdHQxOTgxM3pyaWU4dXl5NXkiLCJzdWIiOiJkaWQ6ZGh0OnF5YWM0cHJ1OXlrY3hicnV0cGFheGttdXN1c3hoNHd0YzRjdHQxOTgxM3pyaWU4dXl5NXkiLCJpYXQiOjE3MTM3NjQ4ODF9.j90ud9-fl_UrhA5fMfApBOxu3IwLnn_Wq7cugLEaoENdzv14W-jWOuL7mCFy1bCF95PWK6RliZQEqdJZnOw6Dg" + ] + } + }, + "error": false +}'''; +} \ No newline at end of file diff --git a/test/protocol/test_vectors/parse_rfq_omit_private_data.dart b/test/protocol/test_vectors/parse_rfq_omit_private_data.dart new file mode 100644 index 0000000..ed07e85 --- /dev/null +++ b/test/protocol/test_vectors/parse_rfq_omit_private_data.dart @@ -0,0 +1,33 @@ +class ParseRfqOmitPrivateData { + static const String vector = r''' + { + "description": "RFQ with privateData omitted parses from string", + "input": "{\"metadata\":{\"from\":\"did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y\",\"to\":\"did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy\",\"protocol\":\"1.0\",\"kind\":\"rfq\",\"id\":\"rfq_01hw25hn37fdcs0m21z3z1fr09\",\"exchangeId\":\"rfq_01hw25hn37fdcs0m21z3z1fr09\",\"createdAt\":\"2024-04-22T05:48:01.511Z\"},\"data\":{\"offeringId\":\"offering_01hw25hn36f0kstngeye3bytfh\",\"payin\":{\"kind\":\"DEBIT_CARD\",\"amount\":\"20000.00\",\"paymentDetailsHash\":\"E6z4pXvZKD3H7h66sMRNq3CDeEqqrsZDqK6E-PpIsrM\"},\"payout\":{\"kind\":\"BTC_ADDRESS\",\"paymentDetailsHash\":\"oynR-RqIJct-GlVyVc7Qqw3A9RQjT4wX44-tZmfrud4\"},\"claimsHash\":\"yqSdLDlRiRJkhTYJF7yqfliaX064uxb4am5r3MD1cWw\"},\"signature\":\"eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0..ePt0IG_SHKM8Dp-WIIUwVDSs-dIi7yoCboatmMRIW1orPCThK5YN-eQEC5oZFoByoYSiXskyUIHnkCkU_nh1BQ\"}", + "output": { + "metadata": { + "from": "did:dht:qyac4pru9ykcxbrutpaaxkmususxh4wtc4ctt19813zrie8uyy5y", + "to": "did:dht:3whftgpbdjihx9ze9tdn575zqzm4qwccetnf1ybiibuzad7rrmyy", + "protocol": "1.0", + "kind": "rfq", + "id": "rfq_01hw25hn37fdcs0m21z3z1fr09", + "exchangeId": "rfq_01hw25hn37fdcs0m21z3z1fr09", + "createdAt": "2024-04-22T05:48:01.511Z" + }, + "data": { + "offeringId": "offering_01hw25hn36f0kstngeye3bytfh", + "payin": { + "kind": "DEBIT_CARD", + "amount": "20000.00", + "paymentDetailsHash": "E6z4pXvZKD3H7h66sMRNq3CDeEqqrsZDqK6E-PpIsrM" + }, + "payout": { + "kind": "BTC_ADDRESS", + "paymentDetailsHash": "oynR-RqIJct-GlVyVc7Qqw3A9RQjT4wX44-tZmfrud4" + }, + "claimsHash": "yqSdLDlRiRJkhTYJF7yqfliaX064uxb4am5r3MD1cWw" + }, + "signature": "eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDpkaHQ6cXlhYzRwcnU5eWtjeGJydXRwYWF4a211c3VzeGg0d3RjNGN0dDE5ODEzenJpZTh1eXk1eSMwIn0..ePt0IG_SHKM8Dp-WIIUwVDSs-dIi7yoCboatmMRIW1orPCThK5YN-eQEC5oZFoByoYSiXskyUIHnkCkU_nh1BQ" + }, + "error": false +}'''; +} \ No newline at end of file From 51e0267bcdaae945ff61b2893da3738e855a48ff Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Mon, 6 May 2024 15:19:51 -0700 Subject: [PATCH 4/4] add vectors test with failing offering vector --- test/protocol/vectors_test.dart | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 test/protocol/vectors_test.dart diff --git a/test/protocol/vectors_test.dart b/test/protocol/vectors_test.dart new file mode 100644 index 0000000..ca3dced --- /dev/null +++ b/test/protocol/vectors_test.dart @@ -0,0 +1,63 @@ +import 'dart:convert'; + +import 'package:tbdex/tbdex.dart'; +import 'package:test/test.dart'; + +import 'test_vectors/parse_close.dart'; +import 'test_vectors/parse_offering.dart'; +import 'test_vectors/parse_order.dart'; +import 'test_vectors/parse_orderstatus.dart'; +import 'test_vectors/parse_quote.dart'; +import 'test_vectors/parse_rfq.dart'; + +void main() { + group('Vectors', () { + test('can parse offering test vector', () async { + final json = jsonDecode(ParseOffering.vector) as Map; + final parsed = await Offering.parse(json['input']); + + expect(parsed, isA()); + expect(parsed.toJson(), equals(json['output'])); + }); + + test('can parse rfq test vector', () async { + final json = jsonDecode(ParseRfq.vector) as Map; + final parsed = await Rfq.parse(json['input']); + + expect(parsed, isA()); + expect(parsed.toJson(), equals(json['output'])); + }); + + test('can parse order test vector', () async { + final json = jsonDecode(ParseOrder.vector) as Map; + final parsed = await Order.parse(json['input']); + + expect(parsed, isA()); + expect(parsed.toJson(), equals(json['output'])); + }); + + test('can parse orderstatus test vector', () async { + final json = jsonDecode(ParseOrderstatus.vector) as Map; + final parsed = await OrderStatus.parse(json['input']); + + expect(parsed, isA()); + expect(parsed.toJson(), equals(json['output'])); + }); + + test('can parse quote test vector', () async { + final json = jsonDecode(ParseQuote.vector) as Map; + final parsed = await Quote.parse(json['input']); + + expect(parsed, isA()); + expect(parsed.toJson(), equals(json['output'])); + }); + + test('can parse close test vector', () async { + final json = jsonDecode(ParseClose.vector) as Map; + final parsed = await Close.parse(json['input']); + + expect(parsed, isA()); + expect(parsed.toJson(), equals(json['output'])); + }); + }); +}