diff --git a/hosted/test-vectors/message/marshal.json b/hosted/test-vectors/message/marshal.json deleted file mode 100644 index 5dd5ddf3..00000000 --- a/hosted/test-vectors/message/marshal.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "description": "Tbdex Message Marshalling Tests", - "vectors": [ - { - "description": "RFQ parses from string", - "input": "{\"metadata\":{\"kind\":\"rfq\",\"to\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"from\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"id\":\"rfq_7zzzzzzyzte028007g0g001xdc\",\"exchangeId\":\"rfq_7zzzzzzyzte028007g0g001xdc\",\"createdAt\":\"2023-10-24T16:15:04.010Z\"},\"data\":{\"offeringId\":\"offering_01hdh7fyzzek48003ms0001bv2\",\"payinSubunits\":\"1000\",\"payinMethod\":{\"kind\":\"BTC_ADDRESS\",\"paymentDetails\":{\"address\":\"123456\"}},\"payoutMethod\":{\"kind\":\"MOMO\",\"paymentDetails\":{\"phoneNumber\":\"+254712345678\",\"accountHolderName\":\"Alfred Holder\"}},\"claims\":[\"presentation submission\"]},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..Y9gKs87CGalvHxlChHsL2fx2wtlPbY2-tBDciz7rSKRJkWmeIdyu-7NxwUdVMlQfJ58PTLoYPknXUKL8Hc0v4w\"}", - "output": { - "metadata": { - "kind": "rfq", - "to": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", - "from": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", - "id": "rfq_7zzzzzzyzte028007g0g001xdc", - "exchangeId": "rfq_7zzzzzzyzte028007g0g001xdc", - "createdAt": "2023-10-24T16:15:04.010Z" - }, - "data": { - "offeringId": "offering_01hdh7fyzzek48003ms0001bv2", - "payinSubunits": "1000", - "payinMethod": { - "kind": "BTC_ADDRESS", - "paymentDetails": { - "address": "123456" - } - }, - "payoutMethod": { - "kind": "MOMO", - "paymentDetails": { - "phoneNumber": "+254712345678", - "accountHolderName": "Alfred Holder" - } - }, - "claims": [ - "presentation submission" - ] - }, - "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..Y9gKs87CGalvHxlChHsL2fx2wtlPbY2-tBDciz7rSKRJkWmeIdyu-7NxwUdVMlQfJ58PTLoYPknXUKL8Hc0v4w" - }, - "errors": false - }, - { - "description": "Quote parses from string", - "input": "{\"metadata\":{\"kind\":\"quote\",\"to\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"quote_7zzzzzzpyrfy2r004fgm0013c7\",\"exchangeId\":\"rfq_7zzzzzzzztfxx8001ff8000ex2\",\"createdAt\":\"2023-10-24T16:15:04.024Z\"},\"data\":{\"expiresAt\":\"2023-10-25T16:15:04.024Z\",\"payin\":{\"currencyCode\":\"AUD\",\"amountSubunits\":\"1000\",\"feeSubunits\":\"1\"},\"payout\":{\"currencyCode\":\"BTC\",\"amountSubunits\":\"12\",\"feeSubunits\":\"2\"},\"paymentInstructions\":{\"payin\":{\"link\":\"https://block.xyz\",\"instruction\":\"payin instruction\"},\"payout\":{\"link\":\"https://block.xyz\",\"instruction\":\"payout instruction\"}}},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..B2n8TL3Tk_Bq0uf8l-1IIj_p44fuLghihElbrF493N1b1TqexdHqkhUuevdh5DKsTi3DgiQyHd8Vijwnz6Ap_A\"}", - "output": { - "metadata": { - "kind": "quote", - "to": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", - "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", - "id": "quote_7zzzzzzpyrfy2r004fgm0013c7", - "exchangeId": "rfq_7zzzzzzzztfxx8001ff8000ex2", - "createdAt": "2023-10-24T16:15:04.024Z" - }, - "data": { - "expiresAt": "2023-10-25T16:15:04.024Z", - "payin": { - "currencyCode": "AUD", - "amountSubunits": "1000", - "feeSubunits": "1" - }, - "payout": { - "currencyCode": "BTC", - "amountSubunits": "12", - "feeSubunits": "2" - }, - "paymentInstructions": { - "payin": { - "link": "https://block.xyz", - "instruction": "payin instruction" - }, - "payout": { - "link": "https://block.xyz", - "instruction": "payout instruction" - } - } - }, - "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..B2n8TL3Tk_Bq0uf8l-1IIj_p44fuLghihElbrF493N1b1TqexdHqkhUuevdh5DKsTi3DgiQyHd8Vijwnz6Ap_A" - }, - "errors": false - }, - { - "description": "Order parses from string", - "input": "{\"metadata\":{\"kind\":\"order\",\"to\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"from\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"id\":\"order_01hdh7fpzjeh980014a8000t9d\",\"exchangeId\":\"rfq_7zzzzzzqvhffw8002vz0000mwp\",\"createdAt\":\"2023-10-24T16:15:04.032Z\"},\"data\":{},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..FLzrqCirBzDFix3AuIpv-1FtGSUNq7v6ckUQjzrGc5JLDSggS8P-MdVJ1gW5SVCusZCRhkjk6UX4qQXSFZ4X8w\"}", - "output": { - "metadata": { - "kind": "order", - "to": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", - "from": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", - "id": "order_01hdh7fpzjeh980014a8000t9d", - "exchangeId": "rfq_7zzzzzzqvhffw8002vz0000mwp", - "createdAt": "2023-10-24T16:15:04.032Z" - }, - "data": {}, - "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..FLzrqCirBzDFix3AuIpv-1FtGSUNq7v6ckUQjzrGc5JLDSggS8P-MdVJ1gW5SVCusZCRhkjk6UX4qQXSFZ4X8w" - }, - "errors": "valid" - }, - { - "description": "Close parses from string", - "input": "{\"metadata\":{\"kind\":\"close\",\"to\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"close_7zzzzzzpvqf2480048h0001jm6\",\"exchangeId\":\"rfq_01hdh7fqvpevq8003pxr001a45\",\"createdAt\":\"2023-10-24T16:15:04.037Z\"},\"data\":{\"reason\":\"test reason\"},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..TDtaxXdl1Bljuft8bZlvxTXTK472fKOia12kG_mQA7UhGTVIfwO9cuDCS_86EZHPMhkAvYdOnIiUodouZVba_A\"}", - "output": { - "metadata": { - "kind": "close", - "to": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", - "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", - "id": "close_7zzzzzzpvqf2480048h0001jm6", - "exchangeId": "rfq_01hdh7fqvpevq8003pxr001a45", - "createdAt": "2023-10-24T16:15:04.037Z" - }, - "data": { - "reason": "test reason" - }, - "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..TDtaxXdl1Bljuft8bZlvxTXTK472fKOia12kG_mQA7UhGTVIfwO9cuDCS_86EZHPMhkAvYdOnIiUodouZVba_A" - }, - "errors": "valid" - }, - { - "description": "Order Status parses from string", - "input": "{\"metadata\":{\"kind\":\"orderstatus\",\"to\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"orderstatus_01hdh7fzvffj3r005wgw000ac4\",\"exchangeId\":\"rfq_01hdh7fqvzesf8002pbr001x7t\",\"createdAt\":\"2023-10-24T16:15:04.034Z\"},\"data\":{\"orderStatus\":\"PENDING\"},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..dSZEztUIOWMfb8fLuJSL5A9DblEH7ROszTUztv1b-21dgKEZMCZCAPeju2MEEIObtv7SKvWopenL7IqtP2RpVQ\"}", - "output": { - "metadata": { - "kind": "orderstatus", - "to": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", - "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", - "id": "orderstatus_01hdh7fzvffj3r005wgw000ac4", - "exchangeId": "rfq_01hdh7fqvzesf8002pbr001x7t", - "createdAt": "2023-10-24T16:15:04.034Z" - }, - "data": { - "orderStatus": "PENDING" - }, - "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..dSZEztUIOWMfb8fLuJSL5A9DblEH7ROszTUztv1b-21dgKEZMCZCAPeju2MEEIObtv7SKvWopenL7IqtP2RpVQ" - }, - "errors": false - } - ] -} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/README.md b/hosted/test-vectors/protocol/README.md new file mode 100644 index 00000000..ba5cf435 --- /dev/null +++ b/hosted/test-vectors/protocol/README.md @@ -0,0 +1,21 @@ +## Protocol Test Vectors +This directory contains test vectors containing a collection of valid and invalid TBDex Messages and Resources. Implementations can use these vectors to ensure that they **accept valid messages** and **reject invalid messages**. + +### Using Test Vectors +It is recommended to add this repo as a git submodule to your implementation repo. See [this PR](https://github.com/TBD54566975/tbdex-js/pull/129) in `tbdex-js` for an example. + +### Test Vector Structure +Each vector file must follow the schema in `vectors.json.schema`. +1. `description` : A human readable description of the scenario being tested. +2. `input` : A stringified JSON TBDex object +3. `output` : If the input contains a valid TBDex object: A JSON object of the the expected parsed input. Otherwise, omit. +4. `error` : boolean. True if an error is expected, false if not. + +### Generating Test Vectors +1. Create a new test vector file in `hosted/test-vectors/protocol/vectors/` +2. Use an implementation of TBDex that supports the desired scenario to create the `input`, `output`, and `error`. +3. Validate the test vector structure. + a. Set up with `cd hosted/test-vectors/protocol & npm install`. + b. Run with `npm run validate-vectors`. +4. Test the updated vectors against an implmentation of TBDex. +5. Once you are confident that your test vector works as desired, open a PR against `tbdex`. \ No newline at end of file diff --git a/hosted/test-vectors/protocol/package-lock.json b/hosted/test-vectors/protocol/package-lock.json new file mode 100644 index 00000000..3383fc1f --- /dev/null +++ b/hosted/test-vectors/protocol/package-lock.json @@ -0,0 +1,61 @@ +{ + "name": "protocol", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "ajv": "^8.0.1" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + } + } +} diff --git a/hosted/test-vectors/protocol/package.json b/hosted/test-vectors/protocol/package.json new file mode 100644 index 00000000..b6f988aa --- /dev/null +++ b/hosted/test-vectors/protocol/package.json @@ -0,0 +1,8 @@ +{ + "scripts": { + "validate-vectors": "node validate-vectors.js" + }, + "dependencies": { + "ajv": "^8.0.1" + } +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/validate-vectors.js b/hosted/test-vectors/protocol/validate-vectors.js new file mode 100644 index 00000000..655d09c0 --- /dev/null +++ b/hosted/test-vectors/protocol/validate-vectors.js @@ -0,0 +1,51 @@ +const fs = require('fs'); +const path = require('path'); +const Ajv = require('ajv'); + +const testVectorsDirectoryPath = path.join(__dirname, 'vectors'); +const schemaFilePath = path.join(__dirname, 'vector.schema.json'); + +function readJsonFile(filePath) { + try { + const fileContent = fs.readFileSync(filePath, 'utf8'); + return JSON.parse(fileContent); + } catch (error) { + console.error(`Error reading JSON file at ${filePath}: ${error.message}`); + return null; + } +} + +function validateTestVectors() { + // Load the JSON schema + const schema = readJsonFile(schemaFilePath); + + if (!schema) { + console.error('Unable to load JSON schema. Exiting.'); + process.exit(1); + } + + const ajv = new Ajv(); + const validate = ajv.compile(schema); + + // Read and validate JSON schema of each test vector file + const success = true + fs.readdirSync(testVectorsDirectoryPath) + .filter(file => file.endsWith('.json')) + .map(file => path.join(testVectorsDirectoryPath, file)) + .map(filePath => { + const testVectorJson = readJsonFile(filePath) + if (!testVectorJson || !validate(testVectorJson)) { + console.error(`Error validating JSON Schema of test vector at path ${filePath}: `, validate.errors) + success = false + } + }) + + if (success) { + console.log('SUCCESS: All test vectors are valid') + } else { + console.log('FAIL: There were errors validating test vectors') + } +} + +// Compile the valid JSON files into an array +validateTestVectors(); diff --git a/hosted/test-vectors/protocol/vector.schema.json b/hosted/test-vectors/protocol/vector.schema.json new file mode 100644 index 00000000..a5f4bfaf --- /dev/null +++ b/hosted/test-vectors/protocol/vector.schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "input": { + "type": "string" + }, + "output": { + "type": "object", + "additionalProperties": true + }, + "error": { + "type": "boolean" + } + }, + "required": ["description", "input", "error"] +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/vectors/parse-close.json b/hosted/test-vectors/protocol/vectors/parse-close.json new file mode 100644 index 00000000..6a4370aa --- /dev/null +++ b/hosted/test-vectors/protocol/vectors/parse-close.json @@ -0,0 +1,19 @@ +{ + "description": "Close parses from string", + "input": "{\"metadata\":{\"kind\":\"close\",\"to\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"close_7zzzzzzpvqf2480048h0001jm6\",\"exchangeId\":\"rfq_01hdh7fqvpevq8003pxr001a45\",\"createdAt\":\"2023-10-24T16:15:04.037Z\"},\"data\":{\"reason\":\"test reason\"},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..TDtaxXdl1Bljuft8bZlvxTXTK472fKOia12kG_mQA7UhGTVIfwO9cuDCS_86EZHPMhkAvYdOnIiUodouZVba_A\"}", + "output": { + "metadata": { + "kind": "close", + "to": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", + "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", + "id": "close_7zzzzzzpvqf2480048h0001jm6", + "exchangeId": "rfq_01hdh7fqvpevq8003pxr001a45", + "createdAt": "2023-10-24T16:15:04.037Z" + }, + "data": { + "reason": "test reason" + }, + "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..TDtaxXdl1Bljuft8bZlvxTXTK472fKOia12kG_mQA7UhGTVIfwO9cuDCS_86EZHPMhkAvYdOnIiUodouZVba_A" + }, + "error": false +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/vectors/parse-offering.json b/hosted/test-vectors/protocol/vectors/parse-offering.json new file mode 100644 index 00000000..89aaf914 --- /dev/null +++ b/hosted/test-vectors/protocol/vectors/parse-offering.json @@ -0,0 +1,109 @@ +{ + "description": "can parse and serialize an Offering", + "input": "{\"metadata\":{\"kind\":\"offering\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"offering_01hdh7fyftfkv8002wyr000nj5\",\"createdAt\":\"2023-10-24T16:15:03.662Z\",\"updatedAt\":\"2023-10-24T16:15:03.662Z\"},\"data\":{\"description\":\"A sample offering\",\"payoutUnitsPerPayinUnit\":\"1\",\"payoutCurrency\":{\"currencyCode\":\"USDC\"},\"payinCurrency\":{\"currencyCode\":\"AUD\",\"minSubunits\":\"1\",\"maxSubunits\":\"10000\"},\"payinMethods\":[{\"kind\":\"BTC_ADDRESS\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"phoneNumber\":{\"minLength\":12,\"pattern\":\"^+2547[0-9]{8}$\",\"description\":\"Mobile Money account number of the Recipient\",\"type\":\"string\",\"title\":\"Phone Number\",\"maxLength\":12},\"accountHolderName\":{\"pattern\":\"^[A-Za-zs'-]+$\",\"description\":\"Name of the account holder as it appears on the Mobile Money account\",\"type\":\"string\",\"title\":\"Account Holder Name\",\"maxLength\":32}},\"required\":[\"accountNumber\",\"accountHolderName\"]}}],\"payoutMethods\":[{\"kind\":\"MOMO\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"phoneNumber\":{\"minLength\":12,\"pattern\":\"^+2547[0-9]{8}$\",\"description\":\"Mobile Money account number of the Recipient\",\"type\":\"string\",\"title\":\"Phone Number\",\"maxLength\":12},\"accountHolderName\":{\"pattern\":\"^[A-Za-zs'-]+$\",\"description\":\"Name of the account holder as it appears on the Mobile Money account\",\"type\":\"string\",\"title\":\"Account Holder Name\",\"maxLength\":32}},\"required\":[\"accountNumber\",\"accountHolderName\"]}}],\"requiredClaims\":{\"id\":\"test-pd-id\",\"name\":\"simple PD\",\"purpose\":\"pd for testing\",\"input_descriptors\":[{\"id\":\"whatever\",\"purpose\":\"id for testing\",\"constraints\":{\"fields\":[{\"path\":[\"$.credentialSubject.btcAddress\"]}]}}]}},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..MyaMT4LZAlkLj4w9LZMqQLsaklhHlsrob60p1XmKMKg249kweyXPGABpEnvKD_65_1s1RjdyKlEotgQT15xAYw\"}", + "output": { + "metadata": { + "kind": "offering", + "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", + "id": "offering_01hdh7fyftfkv8002wyr000nj5", + "createdAt": "2023-10-24T16:15:03.662Z", + "updatedAt": "2023-10-24T16:15:03.662Z" + }, + "data": { + "description": "A sample offering", + "payoutUnitsPerPayinUnit": "1", + "payoutCurrency": { + "currencyCode": "USDC" + }, + "payinCurrency": { + "currencyCode": "AUD", + "minSubunits": "1", + "maxSubunits": "10000" + }, + "payinMethods": [ + { + "kind": "BTC_ADDRESS", + "requiredPaymentDetails": { + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "type": "object", + "properties": { + "phoneNumber": { + "minLength": 12, + "pattern": "^+2547[0-9]{8}$", + "description": "Mobile Money account number of the Recipient", + "type": "string", + "title": "Phone Number", + "maxLength": 12 + }, + "accountHolderName": { + "pattern": "^[A-Za-zs'-]+$", + "description": "Name of the account holder as it appears on the Mobile Money account", + "type": "string", + "title": "Account Holder Name", + "maxLength": 32 + } + }, + "required": [ + "accountNumber", + "accountHolderName" + ] + } + } + ], + "payoutMethods": [ + { + "kind": "MOMO", + "requiredPaymentDetails": { + "$schema": "http://json-schema.org/draft-07/schema", + "additionalProperties": false, + "type": "object", + "properties": { + "phoneNumber": { + "minLength": 12, + "pattern": "^+2547[0-9]{8}$", + "description": "Mobile Money account number of the Recipient", + "type": "string", + "title": "Phone Number", + "maxLength": 12 + }, + "accountHolderName": { + "pattern": "^[A-Za-zs'-]+$", + "description": "Name of the account holder as it appears on the Mobile Money account", + "type": "string", + "title": "Account Holder Name", + "maxLength": 32 + } + }, + "required": [ + "accountNumber", + "accountHolderName" + ] + } + } + ], + "requiredClaims": { + "id": "test-pd-id", + "name": "simple PD", + "purpose": "pd for testing", + "input_descriptors": [ + { + "id": "whatever", + "purpose": "id for testing", + "constraints": { + "fields": [ + { + "path": [ + "$.credentialSubject.btcAddress" + ] + } + ] + } + } + ] + } + }, + "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..MyaMT4LZAlkLj4w9LZMqQLsaklhHlsrob60p1XmKMKg249kweyXPGABpEnvKD_65_1s1RjdyKlEotgQT15xAYw" + }, + "error": false +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/vectors/parse-order.json b/hosted/test-vectors/protocol/vectors/parse-order.json new file mode 100644 index 00000000..c73fe41a --- /dev/null +++ b/hosted/test-vectors/protocol/vectors/parse-order.json @@ -0,0 +1,17 @@ +{ + "description": "Order parses from string", + "input": "{\"metadata\":{\"kind\":\"order\",\"to\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"from\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"id\":\"order_01hdh7fpzjeh980014a8000t9d\",\"exchangeId\":\"rfq_7zzzzzzqvhffw8002vz0000mwp\",\"createdAt\":\"2023-10-24T16:15:04.032Z\"},\"data\":{},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..FLzrqCirBzDFix3AuIpv-1FtGSUNq7v6ckUQjzrGc5JLDSggS8P-MdVJ1gW5SVCusZCRhkjk6UX4qQXSFZ4X8w\"}", + "output": { + "metadata": { + "kind": "order", + "to": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", + "from": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", + "id": "order_01hdh7fpzjeh980014a8000t9d", + "exchangeId": "rfq_7zzzzzzqvhffw8002vz0000mwp", + "createdAt": "2023-10-24T16:15:04.032Z" + }, + "data": {}, + "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..FLzrqCirBzDFix3AuIpv-1FtGSUNq7v6ckUQjzrGc5JLDSggS8P-MdVJ1gW5SVCusZCRhkjk6UX4qQXSFZ4X8w" + }, + "error": false +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/vectors/parse-orderstatus.json b/hosted/test-vectors/protocol/vectors/parse-orderstatus.json new file mode 100644 index 00000000..47b3f6a0 --- /dev/null +++ b/hosted/test-vectors/protocol/vectors/parse-orderstatus.json @@ -0,0 +1,19 @@ +{ + "description": "Order Status parses from string", + "input": "{\"metadata\":{\"kind\":\"orderstatus\",\"to\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"orderstatus_01hdh7fzvffj3r005wgw000ac4\",\"exchangeId\":\"rfq_01hdh7fqvzesf8002pbr001x7t\",\"createdAt\":\"2023-10-24T16:15:04.034Z\"},\"data\":{\"orderStatus\":\"PENDING\"},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..dSZEztUIOWMfb8fLuJSL5A9DblEH7ROszTUztv1b-21dgKEZMCZCAPeju2MEEIObtv7SKvWopenL7IqtP2RpVQ\"}", + "output": { + "metadata": { + "kind": "orderstatus", + "to": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", + "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", + "id": "orderstatus_01hdh7fzvffj3r005wgw000ac4", + "exchangeId": "rfq_01hdh7fqvzesf8002pbr001x7t", + "createdAt": "2023-10-24T16:15:04.034Z" + }, + "data": { + "orderStatus": "PENDING" + }, + "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..dSZEztUIOWMfb8fLuJSL5A9DblEH7ROszTUztv1b-21dgKEZMCZCAPeju2MEEIObtv7SKvWopenL7IqtP2RpVQ" + }, + "error": false +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/vectors/parse-quote.json b/hosted/test-vectors/protocol/vectors/parse-quote.json new file mode 100644 index 00000000..ce8b0165 --- /dev/null +++ b/hosted/test-vectors/protocol/vectors/parse-quote.json @@ -0,0 +1,39 @@ +{ + "description": "Quote parses from string", + "input": "{\"metadata\":{\"kind\":\"quote\",\"to\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"quote_7zzzzzzpyrfy2r004fgm0013c7\",\"exchangeId\":\"rfq_7zzzzzzzztfxx8001ff8000ex2\",\"createdAt\":\"2023-10-24T16:15:04.024Z\"},\"data\":{\"expiresAt\":\"2023-10-25T16:15:04.024Z\",\"payin\":{\"currencyCode\":\"AUD\",\"amountSubunits\":\"1000\",\"feeSubunits\":\"1\"},\"payout\":{\"currencyCode\":\"BTC\",\"amountSubunits\":\"12\",\"feeSubunits\":\"2\"},\"paymentInstructions\":{\"payin\":{\"link\":\"https://block.xyz\",\"instruction\":\"payin instruction\"},\"payout\":{\"link\":\"https://block.xyz\",\"instruction\":\"payout instruction\"}}},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..B2n8TL3Tk_Bq0uf8l-1IIj_p44fuLghihElbrF493N1b1TqexdHqkhUuevdh5DKsTi3DgiQyHd8Vijwnz6Ap_A\"}", + "output": { + "metadata": { + "kind": "quote", + "to": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", + "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", + "id": "quote_7zzzzzzpyrfy2r004fgm0013c7", + "exchangeId": "rfq_7zzzzzzzztfxx8001ff8000ex2", + "createdAt": "2023-10-24T16:15:04.024Z" + }, + "data": { + "expiresAt": "2023-10-25T16:15:04.024Z", + "payin": { + "currencyCode": "AUD", + "amountSubunits": "1000", + "feeSubunits": "1" + }, + "payout": { + "currencyCode": "BTC", + "amountSubunits": "12", + "feeSubunits": "2" + }, + "paymentInstructions": { + "payin": { + "link": "https://block.xyz", + "instruction": "payin instruction" + }, + "payout": { + "link": "https://block.xyz", + "instruction": "payout instruction" + } + } + }, + "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..B2n8TL3Tk_Bq0uf8l-1IIj_p44fuLghihElbrF493N1b1TqexdHqkhUuevdh5DKsTi3DgiQyHd8Vijwnz6Ap_A" + }, + "error": false +} \ No newline at end of file diff --git a/hosted/test-vectors/protocol/vectors/parse-rfq.json b/hosted/test-vectors/protocol/vectors/parse-rfq.json new file mode 100644 index 00000000..6f61df3f --- /dev/null +++ b/hosted/test-vectors/protocol/vectors/parse-rfq.json @@ -0,0 +1,36 @@ +{ + "description": "RFQ parses from string", + "input": "{\"metadata\":{\"kind\":\"rfq\",\"to\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"from\":\"did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC\",\"id\":\"rfq_7zzzzzzyzte028007g0g001xdc\",\"exchangeId\":\"rfq_7zzzzzzyzte028007g0g001xdc\",\"createdAt\":\"2023-10-24T16:15:04.010Z\"},\"data\":{\"offeringId\":\"offering_01hdh7fyzzek48003ms0001bv2\",\"payinSubunits\":\"1000\",\"payinMethod\":{\"kind\":\"BTC_ADDRESS\",\"paymentDetails\":{\"address\":\"123456\"}},\"payoutMethod\":{\"kind\":\"MOMO\",\"paymentDetails\":{\"phoneNumber\":\"+254712345678\",\"accountHolderName\":\"Alfred Holder\"}},\"claims\":[\"presentation submission\"]},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..Y9gKs87CGalvHxlChHsL2fx2wtlPbY2-tBDciz7rSKRJkWmeIdyu-7NxwUdVMlQfJ58PTLoYPknXUKL8Hc0v4w\"}", + "output": { + "metadata": { + "kind": "rfq", + "to": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", + "from": "did:key:zQ3shizfQYEiB8dqac96P6SHYtUCCsY7gSci4Qeaebgsfz1VC", + "id": "rfq_7zzzzzzyzte028007g0g001xdc", + "exchangeId": "rfq_7zzzzzzyzte028007g0g001xdc", + "createdAt": "2023-10-24T16:15:04.010Z" + }, + "data": { + "offeringId": "offering_01hdh7fyzzek48003ms0001bv2", + "payinSubunits": "1000", + "payinMethod": { + "kind": "BTC_ADDRESS", + "paymentDetails": { + "address": "123456" + } + }, + "payoutMethod": { + "kind": "MOMO", + "paymentDetails": { + "phoneNumber": "+254712345678", + "accountHolderName": "Alfred Holder" + } + }, + "claims": [ + "presentation submission" + ] + }, + "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaXpmUVlFaUI4ZHFhYzk2UDZTSFl0VUNDc1k3Z1NjaTRRZWFlYmdzZnoxVkMjelEzc2hpemZRWUVpQjhkcWFjOTZQNlNIWXRVQ0NzWTdnU2NpNFFlYWViZ3NmejFWQyIsImFsZyI6IkVTMjU2SyJ9..Y9gKs87CGalvHxlChHsL2fx2wtlPbY2-tBDciz7rSKRJkWmeIdyu-7NxwUdVMlQfJ58PTLoYPknXUKL8Hc0v4w" + }, + "error": false +} \ No newline at end of file diff --git a/hosted/test-vectors/resource/marshal.json b/hosted/test-vectors/resource/marshal.json deleted file mode 100644 index 0ef8f864..00000000 --- a/hosted/test-vectors/resource/marshal.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "description": "Tbdex Resource Marshalling Tests", - "vectors": [ - { - "description": "can parse and serialize an Offering", - "input": "{\"metadata\":{\"kind\":\"offering\",\"from\":\"did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg\",\"id\":\"offering_01hdh7fyftfkv8002wyr000nj5\",\"createdAt\":\"2023-10-24T16:15:03.662Z\",\"updatedAt\":\"2023-10-24T16:15:03.662Z\"},\"data\":{\"description\":\"A sample offering\",\"payoutUnitsPerPayinUnit\":\"1\",\"payoutCurrency\":{\"currencyCode\":\"USDC\"},\"payinCurrency\":{\"currencyCode\":\"AUD\",\"minSubunits\":\"1\",\"maxSubunits\":\"10000\"},\"payinMethods\":[{\"kind\":\"BTC_ADDRESS\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"phoneNumber\":{\"minLength\":12,\"pattern\":\"^+2547[0-9]{8}$\",\"description\":\"Mobile Money account number of the Recipient\",\"type\":\"string\",\"title\":\"Phone Number\",\"maxLength\":12},\"accountHolderName\":{\"pattern\":\"^[A-Za-zs'-]+$\",\"description\":\"Name of the account holder as it appears on the Mobile Money account\",\"type\":\"string\",\"title\":\"Account Holder Name\",\"maxLength\":32}},\"required\":[\"accountNumber\",\"accountHolderName\"]}}],\"payoutMethods\":[{\"kind\":\"MOMO\",\"requiredPaymentDetails\":{\"$schema\":\"http://json-schema.org/draft-07/schema\",\"additionalProperties\":false,\"type\":\"object\",\"properties\":{\"phoneNumber\":{\"minLength\":12,\"pattern\":\"^+2547[0-9]{8}$\",\"description\":\"Mobile Money account number of the Recipient\",\"type\":\"string\",\"title\":\"Phone Number\",\"maxLength\":12},\"accountHolderName\":{\"pattern\":\"^[A-Za-zs'-]+$\",\"description\":\"Name of the account holder as it appears on the Mobile Money account\",\"type\":\"string\",\"title\":\"Account Holder Name\",\"maxLength\":32}},\"required\":[\"accountNumber\",\"accountHolderName\"]}}],\"requiredClaims\":{\"id\":\"test-pd-id\",\"name\":\"simple PD\",\"purpose\":\"pd for testing\",\"input_descriptors\":[{\"id\":\"whatever\",\"purpose\":\"id for testing\",\"constraints\":{\"fields\":[{\"path\":[\"$.credentialSubject.btcAddress\"]}]}}]}},\"signature\":\"eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..MyaMT4LZAlkLj4w9LZMqQLsaklhHlsrob60p1XmKMKg249kweyXPGABpEnvKD_65_1s1RjdyKlEotgQT15xAYw\"}", - "output": { - "metadata": { - "kind": "offering", - "from": "did:key:zQ3shhwZ18aebLvYzCDdkkUH78z6RXec843BQc9hybsMRSoxg", - "id": "offering_01hdh7fyftfkv8002wyr000nj5", - "createdAt": "2023-10-24T16:15:03.662Z", - "updatedAt": "2023-10-24T16:15:03.662Z" - }, - "data": { - "description": "A sample offering", - "payoutUnitsPerPayinUnit": "1", - "payoutCurrency": { - "currencyCode": "USDC" - }, - "payinCurrency": { - "currencyCode": "AUD", - "minSubunits": "1", - "maxSubunits": "10000" - }, - "payinMethods": [ - { - "kind": "BTC_ADDRESS", - "requiredPaymentDetails": { - "$schema": "http://json-schema.org/draft-07/schema", - "additionalProperties": false, - "type": "object", - "properties": { - "phoneNumber": { - "minLength": 12, - "pattern": "^+2547[0-9]{8}$", - "description": "Mobile Money account number of the Recipient", - "type": "string", - "title": "Phone Number", - "maxLength": 12 - }, - "accountHolderName": { - "pattern": "^[A-Za-zs'-]+$", - "description": "Name of the account holder as it appears on the Mobile Money account", - "type": "string", - "title": "Account Holder Name", - "maxLength": 32 - } - }, - "required": [ - "accountNumber", - "accountHolderName" - ] - } - } - ], - "payoutMethods": [ - { - "kind": "MOMO", - "requiredPaymentDetails": { - "$schema": "http://json-schema.org/draft-07/schema", - "additionalProperties": false, - "type": "object", - "properties": { - "phoneNumber": { - "minLength": 12, - "pattern": "^+2547[0-9]{8}$", - "description": "Mobile Money account number of the Recipient", - "type": "string", - "title": "Phone Number", - "maxLength": 12 - }, - "accountHolderName": { - "pattern": "^[A-Za-zs'-]+$", - "description": "Name of the account holder as it appears on the Mobile Money account", - "type": "string", - "title": "Account Holder Name", - "maxLength": 32 - } - }, - "required": [ - "accountNumber", - "accountHolderName" - ] - } - } - ], - "requiredClaims": { - "id": "test-pd-id", - "name": "simple PD", - "purpose": "pd for testing", - "input_descriptors": [ - { - "id": "whatever", - "purpose": "id for testing", - "constraints": { - "fields": [ - { - "path": [ - "$.credentialSubject.btcAddress" - ] - } - ] - } - } - ] - } - }, - "signature": "eyJraWQiOiJkaWQ6a2V5OnpRM3NoaHdaMThhZWJMdll6Q0Rka2tVSDc4ejZSWGVjODQzQlFjOWh5YnNNUlNveGcjelEzc2hod1oxOGFlYkx2WXpDRGRra1VINzh6NlJYZWM4NDNCUWM5aHlic01SU294ZyIsImFsZyI6IkVTMjU2SyJ9..MyaMT4LZAlkLj4w9LZMqQLsaklhHlsrob60p1XmKMKg249kweyXPGABpEnvKD_65_1s1RjdyKlEotgQT15xAYw" - }, - "errors": false - } - ] -} \ No newline at end of file