From 8e4b6dadd56d9b83c0604ebcee6d27a6af963ff4 Mon Sep 17 00:00:00 2001 From: Jonathan Alvarez Date: Wed, 10 Jan 2024 19:12:29 -0500 Subject: [PATCH] chore: P-383 add token holding variations for brc20 and ton, trx (#12) Signed-off-by: Jonathan Alvarez --- .../19-token-holding-amount/1-0-0.json | 2 - .../22-token-holding-amount-list/1-0-0.json | 219 +++++++++++++ .../22-token-holding-amount-list/latest.json | 1 + dist/schemas/23-evm-holding-amount/1-0-0.json | 300 ++++++++++++++++++ .../schemas/23-evm-holding-amount/latest.json | 1 + .../token-holding-amount-ton.vc.json | 64 ++++ .../token-holding-amount-trx.vc.json | 64 ++++ .../src/lib/19-token-holding-amount/1-0-0.ts | 2 - .../1-0-0.test.ts | 22 ++ .../lib/22-token-holding-amount-list/1-0-0.ts | 52 +++ .../lib/23-evm-holding-amount/1-0-0.test.ts | 22 ++ .../src/lib/23-evm-holding-amount/1-0-0.ts | 68 ++++ 12 files changed, 813 insertions(+), 4 deletions(-) create mode 100644 dist/schemas/22-token-holding-amount-list/1-0-0.json create mode 120000 dist/schemas/22-token-holding-amount-list/latest.json create mode 100644 dist/schemas/23-evm-holding-amount/1-0-0.json create mode 120000 dist/schemas/23-evm-holding-amount/latest.json create mode 100644 examples/23-evm-holding-amount/token-holding-amount-ton.vc.json create mode 100644 examples/23-evm-holding-amount/token-holding-amount-trx.vc.json create mode 100644 packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.test.ts create mode 100644 packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.ts create mode 100644 packages/schemas/src/lib/23-evm-holding-amount/1-0-0.test.ts create mode 100644 packages/schemas/src/lib/23-evm-holding-amount/1-0-0.ts diff --git a/dist/schemas/19-token-holding-amount/1-0-0.json b/dist/schemas/19-token-holding-amount/1-0-0.json index 49ed975..79a63c8 100644 --- a/dist/schemas/19-token-holding-amount/1-0-0.json +++ b/dist/schemas/19-token-holding-amount/1-0-0.json @@ -135,7 +135,6 @@ "src": { "type": "string", "enum": [ - "$holding_amount", "$wbtc_holding_amount", "$lit_holding_amount", "$usdc_holding_amount", @@ -179,7 +178,6 @@ "src": { "type": "string", "enum": [ - "$holding_amount", "$wbtc_holding_amount", "$lit_holding_amount", "$usdc_holding_amount", diff --git a/dist/schemas/22-token-holding-amount-list/1-0-0.json b/dist/schemas/22-token-holding-amount-list/1-0-0.json new file mode 100644 index 0000000..96ce677 --- /dev/null +++ b/dist/schemas/22-token-holding-amount-list/1-0-0.json @@ -0,0 +1,219 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/litentry/vc-jsonschema/main/dist/schemas/22-token-holding-amount-list/1-0-0.json", + "title": "Token holding amount list", + "description": "The amount of a particular token you are holding", + "type": "object", + "required": [ + "@context", + "issuer", + "issuanceDate", + "credentialSubject", + "proof" + ], + "properties": { + "@context": { + "type": "array", + "items": { + "type": "string", + "format": "uri" + } + }, + "id": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string" + } + }, + "issuer": { + "type": "object", + "required": [ + "id", + "name", + "mrenclave" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "mrenclave": { + "type": "string" + } + } + }, + "issuanceDate": { + "type": "string", + "format": "date-time" + }, + "proof": { + "type": "object", + "required": [ + "created", + "type", + "proofPurpose", + "proofValue", + "verificationMethod" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string" + }, + "proofPurpose": { + "type": "string" + }, + "proofValue": { + "type": "string" + }, + "verificationMethod": { + "type": "string" + } + } + }, + "credentialSubject": { + "title": "Credential Subject of Token holding amount list", + "type": "object", + "required": [ + "id", + "type", + "values", + "endpoint", + "assertions" + ], + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "values": { + "type": "array", + "minItems": 1, + "items": { + "type": "boolean" + } + }, + "endpoint": { + "type": "string", + "format": "uri" + }, + "assertions": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "and" + ], + "properties": { + "and": { + "type": "array", + "minItems": 3, + "maxItems": 3, + "items": [ + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$token" + ] + }, + "op": { + "type": "string", + "enum": [ + "==" + ] + }, + "dst": { + "type": "string", + "enum": [ + "$ordi", + "$sats", + "$rats", + "$MMSS", + "$long", + "$cats", + "$BTCs" + ] + } + } + }, + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$holding_amount" + ] + }, + "op": { + "type": "string", + "enum": [ + ">=" + ] + }, + "dst": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$holding_amount" + ] + }, + "op": { + "type": "string", + "enum": [ + "<" + ] + }, + "dst": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/dist/schemas/22-token-holding-amount-list/latest.json b/dist/schemas/22-token-holding-amount-list/latest.json new file mode 120000 index 0000000..766daa7 --- /dev/null +++ b/dist/schemas/22-token-holding-amount-list/latest.json @@ -0,0 +1 @@ +1-0-0.json \ No newline at end of file diff --git a/dist/schemas/23-evm-holding-amount/1-0-0.json b/dist/schemas/23-evm-holding-amount/1-0-0.json new file mode 100644 index 0000000..8fb2641 --- /dev/null +++ b/dist/schemas/23-evm-holding-amount/1-0-0.json @@ -0,0 +1,300 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/litentry/vc-jsonschema/main/dist/schemas/23-evm-holding-amount/1-0-0.json", + "title": "Token holding amount", + "description": "The amount of a particular token you are holding", + "type": "object", + "required": [ + "@context", + "issuer", + "issuanceDate", + "credentialSubject", + "proof" + ], + "properties": { + "@context": { + "type": "array", + "items": { + "type": "string", + "format": "uri" + } + }, + "id": { + "type": "string" + }, + "type": { + "type": "array", + "items": { + "type": "string" + } + }, + "issuer": { + "type": "object", + "required": [ + "id", + "name", + "mrenclave" + ], + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "mrenclave": { + "type": "string" + } + } + }, + "issuanceDate": { + "type": "string", + "format": "date-time" + }, + "proof": { + "type": "object", + "required": [ + "created", + "type", + "proofPurpose", + "proofValue", + "verificationMethod" + ], + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string" + }, + "proofPurpose": { + "type": "string" + }, + "proofValue": { + "type": "string" + }, + "verificationMethod": { + "type": "string" + } + } + }, + "credentialSubject": { + "title": "Credential Subject of Token holding amount", + "type": "object", + "required": [ + "id", + "type", + "values", + "endpoint", + "assertions" + ], + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "description": { + "type": "string" + }, + "values": { + "type": "array", + "minItems": 1, + "items": { + "type": "boolean" + } + }, + "endpoint": { + "type": "string", + "format": "uri" + }, + "assertions": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": [ + "and" + ], + "properties": { + "and": { + "type": "array", + "minItems": 4, + "maxItems": 4, + "items": [ + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$token" + ] + }, + "op": { + "type": "string", + "enum": [ + "==" + ] + }, + "dst": { + "type": "string", + "enum": [ + "TRX", + "TON" + ] + } + } + }, + { + "type": "object", + "required": [ + "or" + ], + "properties": { + "or": { + "type": "array", + "items": { + "type": "object", + "required": [ + "and" + ], + "properties": { + "and": { + "type": "array", + "minItems": 2, + "maxItems": 2, + "items": [ + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$network" + ] + }, + "op": { + "type": "string", + "enum": [ + "==" + ] + }, + "dst": { + "type": "string", + "enum": [ + "ethereum", + "bsc" + ] + } + } + }, + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$address" + ] + }, + "op": { + "type": "string", + "enum": [ + "==" + ] + }, + "dst": { + "type": "string", + "enum": [ + "0x50327c6c5a14dcade707abad2e27eb517df87ab5", + "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3", + "0x76a797a59ba2c17726896976b7b3747bfd1d220f", + "0x582d872a1b094fc48f5de31d3b73f2d9be47def1" + ] + } + } + } + ] + } + } + } + } + } + }, + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$holding_amount" + ] + }, + "op": { + "type": "string", + "enum": [ + ">=" + ] + }, + "dst": { + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "src", + "op", + "dst" + ], + "properties": { + "src": { + "type": "string", + "enum": [ + "$holding_amount" + ] + }, + "op": { + "type": "string", + "enum": [ + "<" + ] + }, + "dst": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/dist/schemas/23-evm-holding-amount/latest.json b/dist/schemas/23-evm-holding-amount/latest.json new file mode 120000 index 0000000..766daa7 --- /dev/null +++ b/dist/schemas/23-evm-holding-amount/latest.json @@ -0,0 +1 @@ +1-0-0.json \ No newline at end of file diff --git a/examples/23-evm-holding-amount/token-holding-amount-ton.vc.json b/examples/23-evm-holding-amount/token-holding-amount-ton.vc.json new file mode 100644 index 0000000..a1629f0 --- /dev/null +++ b/examples/23-evm-holding-amount/token-holding-amount-ton.vc.json @@ -0,0 +1,64 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "0xde0df2d714cbfde56e05510f7c8f02b1a156357f3027e21979634c8c65231384", + "type": ["VerifiableCredential"], + "credentialSubject": { + "id": "did:litentry:bitcoin:0x03166e0578c4d3a1b59919f139bc773a8e155786f90dba99a0041349774201caf9", + "description": "The amount of a particular token you are holding", + "type": "Token Holding Amount", + "assertionText": "EVMAmountHolding(Ton)", + "assertions": [ + { + "and": [ + { "src": "$token", "op": "==", "dst": "TON" }, + { + "or": [ + { + "and": [ + { "src": "$network", "op": "==", "dst": "ethereum" }, + { + "src": "$address", + "op": "==", + "dst": "0x582d872a1b094fc48f5de31d3b73f2d9be47def1" + } + ] + }, + { + "and": [ + { "src": "$network", "op": "==", "dst": "bsc" }, + { + "src": "$address", + "op": "==", + "dst": "0x76a797a59ba2c17726896976b7b3747bfd1d220f" + } + ] + } + ] + }, + { "src": "$holding_amount", "op": ">=", "dst": "0" }, + { "src": "$holding_amount", "op": "<", "dst": "1" } + ] + } + ], + "values": [false], + "endpoint": "wss://tee-staging.litentry.io" + }, + "issuer": { + "id": "did:litentry:substrate:0xe3107df2d3dc98cda5253a62980431bf71bccd7c4dc56135ef9f9f9a7a78fb18", + "name": "Litentry TEE Worker", + "mrenclave": "DgzoX2SRCmZwF4GVz2xqrREUsCmNYL9truFRHsxGMowc" + }, + "issuanceDate": "2024-01-10T23:59:24.762952328+00:00", + "parachainBlockNumber": 14262, + "sidechainBlockNumber": 28679, + "proof": { + "created": "2024-01-10T23:59:24.763838791+00:00", + "type": "Ed25519Signature2020", + "proofPurpose": "assertionMethod", + "proofValue": "ebc7d2f5d72aa86ee29e42ef9c0d293d3d6eacbd53e86971b0d418bf75528466f2dbcb0e58f05efd00809b0a78f4bef102a5c93b67fd2ad84da3f99f37b8c609", + "verificationMethod": "0xe3107df2d3dc98cda5253a62980431bf71bccd7c4dc56135ef9f9f9a7a78fb18" + } +} diff --git a/examples/23-evm-holding-amount/token-holding-amount-trx.vc.json b/examples/23-evm-holding-amount/token-holding-amount-trx.vc.json new file mode 100644 index 0000000..4c27d7d --- /dev/null +++ b/examples/23-evm-holding-amount/token-holding-amount-trx.vc.json @@ -0,0 +1,64 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/ed25519-2020/v1" + ], + "id": "0x60fff373d5e8d7731aa91bc46ed1fa761ede9774ca8549455e84147691bb6b9b", + "type": ["VerifiableCredential"], + "credentialSubject": { + "id": "did:litentry:bitcoin:0x03166e0578c4d3a1b59919f139bc773a8e155786f90dba99a0041349774201caf9", + "description": "The amount of a particular token you are holding", + "type": "Token Holding Amount", + "assertionText": "EVMAmountHolding(Trx)", + "assertions": [ + { + "and": [ + { "src": "$token", "op": "==", "dst": "TRX" }, + { + "or": [ + { + "and": [ + { "src": "$network", "op": "==", "dst": "ethereum" }, + { + "src": "$address", + "op": "==", + "dst": "0x50327c6c5a14dcade707abad2e27eb517df87ab5" + } + ] + }, + { + "and": [ + { "src": "$network", "op": "==", "dst": "bsc" }, + { + "src": "$address", + "op": "==", + "dst": "0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3" + } + ] + } + ] + }, + { "src": "$holding_amount", "op": ">=", "dst": "0" }, + { "src": "$holding_amount", "op": "<", "dst": "1" } + ] + } + ], + "values": [false], + "endpoint": "wss://tee-staging.litentry.io" + }, + "issuer": { + "id": "did:litentry:substrate:0xe3107df2d3dc98cda5253a62980431bf71bccd7c4dc56135ef9f9f9a7a78fb18", + "name": "Litentry TEE Worker", + "mrenclave": "DgzoX2SRCmZwF4GVz2xqrREUsCmNYL9truFRHsxGMowc" + }, + "issuanceDate": "2024-01-10T21:07:36.807029382+00:00", + "parachainBlockNumber": 13412, + "sidechainBlockNumber": 26961, + "proof": { + "created": "2024-01-10T21:07:36.807282034+00:00", + "type": "Ed25519Signature2020", + "proofPurpose": "assertionMethod", + "proofValue": "ebc7d2f5d72aa86ee29e42ef9c0d293d3d6eacbd53e86971b0d418bf75528466f2dbcb0e58f05efd00809b0a78f4bef102a5c93b67fd2ad84da3f99f37b8c609", + "verificationMethod": "0xe3107df2d3dc98cda5253a62980431bf71bccd7c4dc56135ef9f9f9a7a78fb18" + } +} diff --git a/packages/schemas/src/lib/19-token-holding-amount/1-0-0.ts b/packages/schemas/src/lib/19-token-holding-amount/1-0-0.ts index 0487540..4426a18 100644 --- a/packages/schemas/src/lib/19-token-holding-amount/1-0-0.ts +++ b/packages/schemas/src/lib/19-token-holding-amount/1-0-0.ts @@ -5,8 +5,6 @@ import { resolveGitHubPath } from '../helpers'; import { credentialSubject, assertion } from '../schema-helpers'; const supportedTokens = [ - // https://github.com/litentry/litentry-parachain/blob/dev/tee-worker/litentry/core/credentials/src/nodereal/amount_holding/evm_amount_holding.rs - '$holding_amount', // https://github.com/litentry/litentry-parachain/blob/dev/tee-worker/litentry/core/credentials/src/litentry_profile/token_balance.rs '$wbtc_holding_amount', '$lit_holding_amount', diff --git a/packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.test.ts b/packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.test.ts new file mode 100644 index 0000000..e7fdc70 --- /dev/null +++ b/packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.test.ts @@ -0,0 +1,22 @@ +import * as fs from 'fs'; +import { globSync as glob } from 'fast-glob'; + +import { ajv } from '../ajv'; +import { schema } from './1-0-0'; + +const jsonFiles = glob('examples/22-token-holding-amount-list/*.json'); + +describe('22-token-holding-amount-list/1-0-0', () => { + it.skip.each(jsonFiles)('should work for %s', (example) => { + const validate = ajv.compile(schema); + + expect(validate.errors).toBeNull(); + + const json = JSON.parse(fs.readFileSync(example, 'utf8')); + const valid = validate(json); + + if (!valid) console.log(validate.errors); + + expect(valid).toBeTruthy(); + }); +}); diff --git a/packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.ts b/packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.ts new file mode 100644 index 0000000..c9d9b07 --- /dev/null +++ b/packages/schemas/src/lib/22-token-holding-amount-list/1-0-0.ts @@ -0,0 +1,52 @@ +import { JSONSchema7 } from 'json-schema'; + +import { schema as base } from '../0-base/1-0-0'; +import { resolveGitHubPath } from '../helpers'; +import { credentialSubject, assertion } from '../schema-helpers'; + +// https://github.com/litentry/litentry-parachain/blob/dev/tee-worker/litentry/core/credentials/src/brc20/amount_holder.rs +const supportedTokens = [ + '$ordi', + '$sats', + '$rats', + '$MMSS', + '$long', + '$cats', + '$BTCs', +]; + +export const schema: JSONSchema7 = { + ...base, + + $id: resolveGitHubPath('22-token-holding-amount-list/1-0-0.json'), + + title: 'Token holding amount list', + description: 'The amount of a particular token you are holding', + + properties: { + ...base.properties, + + credentialSubject: credentialSubject({ + title: 'Credential Subject of Token holding amount list', + assertions: assertion.and({ + items: [ + assertion.clause({ + src: ['$token'], + op: ['=='], + dst: supportedTokens, + }), + assertion.clause({ + src: ['$holding_amount'], + op: ['>='], + dst: undefined, // Range based on user holding amount. Format is a string. + }), + assertion.clause({ + src: ['$holding_amount'], + op: ['<'], + dst: undefined, // Range based on user holding amount. Format is a string. + }), + ], + }), + }), + }, +}; diff --git a/packages/schemas/src/lib/23-evm-holding-amount/1-0-0.test.ts b/packages/schemas/src/lib/23-evm-holding-amount/1-0-0.test.ts new file mode 100644 index 0000000..89286f2 --- /dev/null +++ b/packages/schemas/src/lib/23-evm-holding-amount/1-0-0.test.ts @@ -0,0 +1,22 @@ +import * as fs from 'fs'; +import { globSync as glob } from 'fast-glob'; + +import { ajv } from '../ajv'; +import { schema } from './1-0-0'; + +const jsonFiles = glob('examples/23-evm-holding-amount/*.json'); + +describe('23-evm-holding-amount/1-0-0', () => { + it.each(jsonFiles)('should work for %s', (example) => { + const validate = ajv.compile(schema); + + expect(validate.errors).toBeNull(); + + const json = JSON.parse(fs.readFileSync(example, 'utf8')); + const valid = validate(json); + + if (!valid) console.log(validate.errors); + + expect(valid).toBeTruthy(); + }); +}); diff --git a/packages/schemas/src/lib/23-evm-holding-amount/1-0-0.ts b/packages/schemas/src/lib/23-evm-holding-amount/1-0-0.ts new file mode 100644 index 0000000..dc89db8 --- /dev/null +++ b/packages/schemas/src/lib/23-evm-holding-amount/1-0-0.ts @@ -0,0 +1,68 @@ +import { JSONSchema7 } from 'json-schema'; + +import { schema as base } from '../0-base/1-0-0'; +import { resolveGitHubPath } from '../helpers'; +import { credentialSubject, assertion } from '../schema-helpers'; + +// https://github.com/litentry/litentry-parachain/blob/dev/tee-worker/litentry/core/credentials/src/nodereal/amount_holding/evm_amount_holding.rs +const supportedTokens = ['TRX', 'TON']; + +export const schema: JSONSchema7 = { + ...base, + + $id: resolveGitHubPath('23-evm-holding-amount/1-0-0.json'), + + title: 'Token holding amount', + description: 'The amount of a particular token you are holding', + + properties: { + ...base.properties, + + credentialSubject: credentialSubject({ + title: 'Credential Subject of Token holding amount', + assertions: assertion.and({ + items: [ + assertion.clause({ + src: ['$token'], + op: ['=='], + dst: supportedTokens, + }), + assertion.or({ + items: assertion.and({ + // describes the list, no strict items count check + items: [ + assertion.clause({ + src: ['$network'], + op: ['=='], + dst: ['ethereum', 'bsc'], + }), + assertion.clause({ + src: ['$address'], + op: ['=='], + dst: [ + // trx + '0x50327c6c5a14dcade707abad2e27eb517df87ab5', + '0xCE7de646e7208a4Ef112cb6ed5038FA6cC6b12e3', + // ton + '0x76a797a59ba2c17726896976b7b3747bfd1d220f', + '0x582d872a1b094fc48f5de31d3b73f2d9be47def1', + ], + }), + ], + }), + }), + assertion.clause({ + src: ['$holding_amount'], + op: ['>='], + dst: undefined, // Amount, can be any number. Format is a string. + }), + assertion.clause({ + src: ['$holding_amount'], + op: ['<'], + dst: undefined, // Amount, can be any number. Format is a string. + }), + ], + }), + }), + }, +};