diff --git a/config/config.js b/config/config.js index 0f9a1866d..d7ff36187 100644 --- a/config/config.js +++ b/config/config.js @@ -9,9 +9,12 @@ config.FIRESTORE_PAYOUT_ROOT = process.env.FIRESTORE_PAYOUT_ROOT; config.FIRESTORE_MISSION_ROOT = process.env.FIRESTORE_MISSION_ROOT; config.FIRESTORE_CONFIG_ROOT = process.env.FIRESTORE_CONFIG_ROOT; config.FIRESTORE_COUPON_ROOT = process.env.FIRESTORE_COUPON_ROOT; +config.FIRESTORE_LIKER_NFT_ROOT = process.env.FIRESTORE_LIKER_NFT_ROOT; config.FIRESTORE_OAUTH_CLIENT_ROOT = process.env.FIRESTORE_OAUTH_CLIENT_ROOT; config.FIREBASE_STORAGE_BUCKET = process.env.FIREBASE_STORAGE_BUCKET; +config.FIRESTORE_ISCN_INFO_ROOT = process.env.FIRESTORE_ISCN_INFO_ROOT; +config.COSMOS_LCD_INDEXER_ENDPOINT = 'https://node.testnet.like.co'; config.COSMOS_LCD_ENDPOINT = 'https://node.testnet.like.co'; config.COSMOS_RPC_ENDPOINT = 'https://node.testnet.like.co/rpc/'; config.COSMOS_SIGNING_RPC_ENDPOINT = 'https://node.testnet.like.co/rpc/'; @@ -19,11 +22,24 @@ config.COSMOS_CHAIN_ID = 'likecoin-public-testnet-5'; config.ISCN_DEV_LCD_ENDPOINT = 'localhost:1317'; config.ISCN_DEV_CHAIN_ID = 'iscn-dev-chain'; config.COSMOS_DENOM = 'nanoekil'; +config.NFT_RPC_ENDPOINT = 'https://node.testnet.like.co'; +config.NFT_SIGNING_RPC_ENDPOINT = 'https://node.testnet.like.co'; +config.NFT_CHAIN_ID = 'likecoin-public-testnet-5'; +config.NFT_COSMOS_DENOM = 'nanoekil'; config.ARWEAVE_LIKE_TARGET_ADDRESS = ''; config.IPFS_ENDPOINT = 'https://ipfs.infura.io:5001/api/v0'; config.REPLICA_IPFS_ENDPOINTS = []; +config.LIKER_NFT_TARGET_ADDRESS = ''; +config.LIKER_NFT_STARTING_PRICE = 8; +config.LIKER_NFT_PRICE_MULTIPLY = 2; +config.LIKER_NFT_PRICE_DECAY = 0.2; +config.LIKER_NFT_DECAY_START_BATCH = 13; +config.LIKER_NFT_DECAY_END_BATCH = 18; +config.LIKER_NFT_GAS_FEE = '200000'; + + config.AUTHCORE_API_ENDPOINT = ''; config.AUTHCORE_PUBLIC_CERT_PATH = ''; config.AUTHCORE_PRIVATE_KEY_PATH = ''; diff --git a/config/secret.js b/config/secret.js index f3a6ee124..58a89a416 100644 --- a/config/secret.js +++ b/config/secret.js @@ -1,5 +1,6 @@ const config = {}; config.COSMOS_PRIVATE_KEY = Buffer.from('1111111111111111111111111111111111111111111111111111111111111111', 'hex'); +config.LIKER_NFT_PRIVATE_KEY = Buffer.from('1111111111111111111111111111111111111111111111111111111111111111', 'hex'); module.exports = config; diff --git a/package-lock.json b/package-lock.json index 0da5a81e1..32d09a5e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1021,44 +1021,44 @@ } }, "@confio/ics23": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.5.tgz", - "integrity": "sha512-1GdPMsaP/l8JSF4P4HWFLBhdcxHcJT8lS0nknBYNSZ1XrJOsJKUy6EkOwd9Pa1qJkXzY2gyNv7MdHR+AIwSTAg==", + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@confio/ics23/-/ics23-0.6.8.tgz", + "integrity": "sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==", "requires": { - "js-sha512": "^0.8.0", - "protobufjs": "^6.8.8", - "ripemd160": "^2.0.2", - "sha.js": "^2.4.11" + "@noble/hashes": "^1.0.0", + "protobufjs": "^6.8.8" } }, "@cosmjs/amino": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.26.1.tgz", - "integrity": "sha512-8jcEwsLrLW2ltJdNQzdbx+g6Ii9lgG3j7hqaSatnqJE+8OyUjjLH1beigrpz9PhRF3qzQS8WFweTNkkTgNEcSA==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/amino/-/amino-0.28.4.tgz", + "integrity": "sha512-b8y5gFC0eGrH0IoYSNtDmTdsTgeQ1KFZ5YVOeIiKmzF91MeiciYO/MNqc027kctacZ+UbnVWGEUGyRBPi9ta/g==", "requires": { - "@cosmjs/crypto": "0.26.1", - "@cosmjs/encoding": "0.26.1", - "@cosmjs/math": "0.26.1", - "@cosmjs/utils": "0.26.1" + "@cosmjs/crypto": "0.28.4", + "@cosmjs/encoding": "0.28.4", + "@cosmjs/math": "0.28.4", + "@cosmjs/utils": "0.28.4" } }, "@cosmjs/crypto": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.26.1.tgz", - "integrity": "sha512-KzX++HMvCYjekdYr6vRRfJmAzJvdB10nRSyudzirn4/055yKh9oKk/wgjq9QGOIrMzEZNoQJNE0RndbS3nRccA==", - "requires": { - "@cosmjs/encoding": "0.26.1", - "@cosmjs/math": "0.26.1", - "@cosmjs/utils": "0.26.1", - "bip39": "^3.0.2", - "bn.js": "^4.11.8", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/crypto/-/crypto-0.28.4.tgz", + "integrity": "sha512-JRxNLlED3DDh9d04A0RcRw3mYkoobN7q7wafUFy3vI1TjoyWx33v0gqqaYE6/hoo9ghUrJSVOfzVihl8fZajJA==", + "requires": { + "@cosmjs/encoding": "0.28.4", + "@cosmjs/math": "0.28.4", + "@cosmjs/utils": "0.28.4", + "@noble/hashes": "^1", + "bn.js": "^5.2.0", "elliptic": "^6.5.3", - "js-sha3": "^0.8.0", - "libsodium-wrappers": "^0.7.6", - "ripemd160": "^2.0.2", - "sha.js": "^2.4.11" + "libsodium-wrappers": "^0.7.6" }, "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, "elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -1084,18 +1084,13 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" } } }, "@cosmjs/encoding": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.26.1.tgz", - "integrity": "sha512-wDFRvSQrTVIX7k4dPPSS/NmaytTU8ludDXi06TsaqVrgL/OR1hcGEkHhoKjodhZ2NS4gLvncI8XagV3SFySGhA==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/encoding/-/encoding-0.28.4.tgz", + "integrity": "sha512-N6Qnjs4dd8KwjW5m9t3L+rWYYGW2wyS+iLtJJ9DD8DiTTxpW9h7/AmUVO/dsRe5H2tV8/DzH/B9pFfpsgro22A==", "requires": { "base64-js": "^1.3.0", "bech32": "^1.1.4", @@ -1110,49 +1105,89 @@ } }, "@cosmjs/json-rpc": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.26.1.tgz", - "integrity": "sha512-DEMkc0XwdyIqePsYrPbN/iheOst8qvzh3zZX0rQXSr9NzptcKu/KrytlwXVBdqvq6hXbZXbsLAwzsS3DX1OrpA==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/json-rpc/-/json-rpc-0.28.4.tgz", + "integrity": "sha512-An8ZQi9OKbnS8ew/MyHhF90zQpXBF8RTj2wdvIH+Hr8yA6QjynY8hxRpUwYUt3Skc5NeUnTZNuWCzlluHnoxVg==", "requires": { - "@cosmjs/stream": "0.26.1", + "@cosmjs/stream": "0.28.4", "xstream": "^11.14.0" } }, "@cosmjs/math": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.26.1.tgz", - "integrity": "sha512-FvCpguKswL2PYsONXHDzbcaq1gFQteFUz2w7DasVXvVlnzStDS8ePz8k36psNQ1efyX6oF62ZqMizxOZgCW33A==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/math/-/math-0.28.4.tgz", + "integrity": "sha512-wsWjbxFXvk46Dsx8jQ5vsBZOIQuiUIyaaZbUvxsgIhAMpuuBnV5O/drK87+B+4cL+umTelFqTbWnkqueVCIFxQ==", "requires": { - "bn.js": "^4.11.8" + "bn.js": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + } } }, "@cosmjs/proto-signing": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.26.1.tgz", - "integrity": "sha512-R6vHulxH5njTru9Ezr8k5+u6fBzenNRE3EbQtbVreL++TLV/jKu0Vl2CFz89X8su7BqWZImqzE9+BAesLUKVfw==", - "requires": { - "@cosmjs/amino": "0.26.1", - "@cosmjs/crypto": "0.26.1", - "@cosmjs/math": "0.26.1", - "cosmjs-types": "^0.2.0", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/proto-signing/-/proto-signing-0.28.4.tgz", + "integrity": "sha512-4vgCLK9gOsdWzD78V5XbAsupSSyntPEzokWYhgRQNwgVTcKX1kg0eKZqUvF5ua5iL9x6MevfH/sgwPyiYleMBw==", + "requires": { + "@cosmjs/amino": "0.28.4", + "@cosmjs/crypto": "0.28.4", + "@cosmjs/encoding": "0.28.4", + "@cosmjs/math": "0.28.4", + "@cosmjs/utils": "0.28.4", + "cosmjs-types": "^0.4.0", "long": "^4.0.0", "protobufjs": "~6.10.2" }, "dependencies": { "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", + "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" + }, + "cosmjs-types": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", + "integrity": "sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog==", + "requires": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + }, + "dependencies": { + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } }, "protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.3.tgz", + "integrity": "sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -1167,61 +1202,92 @@ "@types/long": "^4.0.1", "@types/node": "^13.7.0", "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + } } } } }, "@cosmjs/socket": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.26.1.tgz", - "integrity": "sha512-lZSWuQ2mIE60tsQ+VEjfVNkLJRvXBq7gibY9wud6oJ4Sl3l2sSnffPoFWQzRvQe6jGLvRcOIFpUD4Vy0Wyx2Bg==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/socket/-/socket-0.28.4.tgz", + "integrity": "sha512-jAEL3Ri+s8XuBM3mqgO4yvmeQu+R+704V37lGROC1B6kAbGxWRyOWrMdOOiFJzCZ35sSMB7L+xKjpE8ug0vJjg==", "requires": { - "@cosmjs/stream": "0.26.1", + "@cosmjs/stream": "0.28.4", "isomorphic-ws": "^4.0.1", "ws": "^7", "xstream": "^11.14.0" - }, - "dependencies": { - "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==" - } } }, "@cosmjs/stargate": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.26.1.tgz", - "integrity": "sha512-vF586pSTAP0Z5x8GLbLLd/nw50YQQHO8ZwYmKFV7zv0dMBFOX8nEUAjb8dloFnNYm9xXEqT5UjVKQKbh/4Ds2w==", - "requires": { - "@confio/ics23": "^0.6.3", - "@cosmjs/amino": "0.26.1", - "@cosmjs/encoding": "0.26.1", - "@cosmjs/math": "0.26.1", - "@cosmjs/proto-signing": "0.26.1", - "@cosmjs/stream": "0.26.1", - "@cosmjs/tendermint-rpc": "0.26.1", - "@cosmjs/utils": "0.26.1", - "cosmjs-types": "^0.2.0", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/stargate/-/stargate-0.28.4.tgz", + "integrity": "sha512-tdwudilP5iLNwDm4TOMBjWuL5YehLPqGlC5/7hjJM/kVHyzLFo4Lzt0dVEwr5YegH+RsRXH/VtFLQz+NYlCobw==", + "requires": { + "@confio/ics23": "^0.6.8", + "@cosmjs/amino": "0.28.4", + "@cosmjs/encoding": "0.28.4", + "@cosmjs/math": "0.28.4", + "@cosmjs/proto-signing": "0.28.4", + "@cosmjs/stream": "0.28.4", + "@cosmjs/tendermint-rpc": "0.28.4", + "@cosmjs/utils": "0.28.4", + "cosmjs-types": "^0.4.0", "long": "^4.0.0", "protobufjs": "~6.10.2", "xstream": "^11.14.0" }, "dependencies": { "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", + "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" + }, + "cosmjs-types": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.4.1.tgz", + "integrity": "sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog==", + "requires": { + "long": "^4.0.0", + "protobufjs": "~6.11.2" + }, + "dependencies": { + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } }, "protobufjs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", - "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.3.tgz", + "integrity": "sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -1236,29 +1302,37 @@ "@types/long": "^4.0.1", "@types/node": "^13.7.0", "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==" + } } } } }, "@cosmjs/stream": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.26.1.tgz", - "integrity": "sha512-RVFE7kEjUAyRMp35EYZ25XY6DRsifcXDEa0C6b6PYacqdkVhCTfNXZrYaJ/NCTowQ+dYRSR6QVsM4AfStsDgZA==", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/stream/-/stream-0.28.4.tgz", + "integrity": "sha512-BDwDdFOrOgRx/Wm5nknb9YCV9HHIUcsOxykTDZqdArCUsn4QJBq79QIjp919G05Z8UemkoHwiUCUNB2BfoKmFw==", "requires": { "xstream": "^11.14.0" } }, "@cosmjs/tendermint-rpc": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.26.1.tgz", - "integrity": "sha512-qeFF+0bAl5f55IFHC56B4iXppQ3gYQ994yd1kr6RveDBZEQOhesSi9Khypy7XhhN1mGU9VCxJWQpwOVyPVW1VQ==", - "requires": { - "@cosmjs/crypto": "0.26.1", - "@cosmjs/encoding": "0.26.1", - "@cosmjs/json-rpc": "0.26.1", - "@cosmjs/math": "0.26.1", - "@cosmjs/socket": "0.26.1", - "@cosmjs/stream": "0.26.1", + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.28.4.tgz", + "integrity": "sha512-iz6p4UW2QUZNh55WeJy9wHbMdqM8COo0AJdrGU4Ikb/xU0/H6b0dFPoEK+i6ngR0cSizh+hpTMzh3AA7ySUKlA==", + "requires": { + "@cosmjs/crypto": "0.28.4", + "@cosmjs/encoding": "0.28.4", + "@cosmjs/json-rpc": "0.28.4", + "@cosmjs/math": "0.28.4", + "@cosmjs/socket": "0.28.4", + "@cosmjs/stream": "0.28.4", + "@cosmjs/utils": "0.28.4", "axios": "^0.21.2", "readonly-date": "^1.0.0", "xstream": "^11.14.0" @@ -1273,16 +1347,16 @@ } }, "follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.0.tgz", + "integrity": "sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ==" } } }, "@cosmjs/utils": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.26.1.tgz", - "integrity": "sha512-E7sYhHfcq2V4oB504FNSt8nx6QInTea1KZT5FrtyqONmgQwccfTv5+E2PuRbQs91i56YzHORHuP57rhV7NPn3g==" + "version": "0.28.4", + "resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.28.4.tgz", + "integrity": "sha512-lb3TU6833arPoPZF8HTeG9V418CpurvqH5Aa/ls0I0wYdPDEMO6622+PQNQhQ8Vw8Az2MXoSyc8jsqrgawT84Q==" }, "@ethersproject/abi": { "version": "5.0.0-beta.153", @@ -1518,120 +1592,434 @@ } }, "@firebase/app-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.5.0.tgz", - "integrity": "sha512-8j+vCXTpAkYGcFk86mPZ90V6HMFmn196RIEW9Opi0PN+VrPFC1l/eW0gptM8v7VXaQhECOxws3TN2g+dDaeSYA==" + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.7.0.tgz", + "integrity": "sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==" + }, + "@firebase/auth-interop-types": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.6.tgz", + "integrity": "sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==" }, "@firebase/component": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.1.tgz", - "integrity": "sha512-e9MrCYH10+CvGyJsuntdqH+Gtkbvm33GBEPprKClq9Qh36gXZxtvlUPwXACJfaD34tqxFB2V0pGi7i8iJUA+AA==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.13.tgz", + "integrity": "sha512-hxhJtpD8Ppf/VU2Rlos6KFCEV77TGIGD5bJlkPK1+B/WUe0mC6dTjW7KhZtXTc+qRBp9nFHWcsIORnT8liHP9w==", "requires": { - "@firebase/util": "0.2.36", - "tslib": "1.10.0" + "@firebase/util": "1.5.2", + "tslib": "^2.1.0" }, "dependencies": { "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, "@firebase/database": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.16.tgz", - "integrity": "sha512-m8qrt3irSiSkFP9i75nGWFasZFeFb5KAR6/fvWOoLMXQWE41LU7Z+osUaXWvGvPJxsoHD0EY+4+Blat4XiJx9g==", - "requires": { - "@firebase/component": "0.1.1", - "@firebase/database-types": "0.4.10", - "@firebase/logger": "0.1.33", - "@firebase/util": "0.2.36", - "faye-websocket": "0.11.3", - "tslib": "1.10.0" + "version": "0.12.8", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.8.tgz", + "integrity": "sha512-JBQVfFLzfhxlQbl4OU6ov9fdsddkytBQdtSSR49cz48homj38ccltAhK6seum+BI7f28cV2LFHF9672lcN+qxA==", + "requires": { + "@firebase/auth-interop-types": "0.1.6", + "@firebase/component": "0.5.13", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.2", + "faye-websocket": "0.11.4", + "tslib": "^2.1.0" }, "dependencies": { "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + } + } + }, + "@firebase/database-compat": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.8.tgz", + "integrity": "sha512-dhXr5CSieBuKNdU96HgeewMQCT9EgOIkfF1GNy+iRrdl7BWLxmlKuvLfK319rmIytSs/vnCzcD9uqyxTeU/A3A==", + "requires": { + "@firebase/component": "0.5.13", + "@firebase/database": "0.12.8", + "@firebase/database-types": "0.9.7", + "@firebase/logger": "0.3.2", + "@firebase/util": "1.5.2", + "tslib": "^2.1.0" + }, + "dependencies": { + "@firebase/database-types": { + "version": "0.9.7", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.7.tgz", + "integrity": "sha512-EFhgL89Fz6DY3kkB8TzdHvdu8XaqqvzcF2DLVOXEnQ3Ms7L755p5EO42LfxXoJqb9jKFvgLpFmKicyJG25WFWw==", + "requires": { + "@firebase/app-types": "0.7.0", + "@firebase/util": "1.5.2" + } + }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, "@firebase/database-types": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.4.10.tgz", - "integrity": "sha512-66puLsckt5HASgRN3CfhLn2iuGrgCjfH3u17OL0f5MtEweYLx+yW2QW5d539Wx30xD4B+INEdaRetw6xEa9t7g==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.7.3.tgz", + "integrity": "sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==", "requires": { - "@firebase/app-types": "0.5.0" + "@firebase/app-types": "0.6.3" + }, + "dependencies": { + "@firebase/app-types": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.3.tgz", + "integrity": "sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw==" + } } }, "@firebase/logger": { - "version": "0.1.33", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.33.tgz", - "integrity": "sha512-EiewY1by3mYanihTa5Wsl2/gseFzmRmZr61YtVgQN5TXpX1OlQtqds6cCoR8Hh8VueeZJg6lTV9VLVQqu6iqHw==" - }, - "@firebase/util": { - "version": "0.2.36", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.36.tgz", - "integrity": "sha512-AqrXca+8rMbPyp7zMO9BoZrdbb8wsT5kmqwge9QW4ZBxTTSQrvBs7VylGx5Ede4VbhqRJvkmo7G73/dp2L+wbA==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.2.tgz", + "integrity": "sha512-lzLrcJp9QBWpo40OcOM9B8QEtBw2Fk1zOZQdvv+rWS6gKmhQBCEMc4SMABQfWdjsylBcDfniD1Q+fUX1dcBTXA==", "requires": { - "tslib": "1.10.0" + "tslib": "^2.1.0" }, "dependencies": { "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, - "@google-cloud/common": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.2.5.tgz", - "integrity": "sha512-Iw6LJj7V8XEVFDORCHC/I+YVmK98KmZSa8z10O4h2Wpkzlk/Sjj8Ruz4QJHawj7GwuWjQQ47O2Z4JECXf1S3ag==", - "optional": true, + "@firebase/util": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.5.2.tgz", + "integrity": "sha512-YvBH2UxFcdWG2HdFnhxZptPl2eVFlpOyTH66iDo13JPEYraWzWToZ5AMTtkyRHVmu7sssUpQlU9igy1KET7TOw==", "requires": { - "@google-cloud/projectify": "^1.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^5.5.0", - "retry-request": "^4.0.0", - "teeny-request": "^5.2.1" + "tslib": "^2.1.0" }, "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" } } }, "@google-cloud/firestore": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-2.6.1.tgz", - "integrity": "sha512-ZzjaNn8TLji2HpC/h4uDuOb+h7lf1YCiNRiHhLkCUuEp+xAt1uPAkLFLAamGYW26v9VIe+9H/3l27pkplFsybQ==", + "version": "4.15.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz", + "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==", "optional": true, "requires": { - "bun": "^0.0.12", - "deep-equal": "^1.0.1", + "fast-deep-equal": "^3.1.1", "functional-red-black-tree": "^1.0.1", - "google-gax": "^1.7.5", - "through2": "^3.0.0" + "google-gax": "^2.24.1", + "protobufjs": "^6.8.6" }, "dependencies": { - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "@grpc/grpc-js": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.7.tgz", + "integrity": "sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw==", + "optional": true, + "requires": { + "@grpc/proto-loader": "^0.6.4", + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "optional": true, + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "dependencies": { + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "optional": true + }, + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } + }, + "@types/node": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==", + "optional": true + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "optional": true + }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "optional": true + }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "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==", + "optional": true + }, + "fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig==", + "optional": true + }, + "gaxios": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz", + "integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==", + "optional": true, + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.7" + } + }, + "gcp-metadata": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", + "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", + "optional": true, + "requires": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + } + }, + "google-auth-library": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz", + "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==", "optional": true, "requires": { - "readable-stream": "2 || 3" + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + }, + "google-gax": { + "version": "2.30.5", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.30.5.tgz", + "integrity": "sha512-Jey13YrAN2hfpozHzbtrwEfEHdStJh1GwaQ2+Akh1k0Tv/EuNVSuBtHZoKSBm5wBMvNsxTsEIZ/152NrYyZgxQ==", + "optional": true, + "requires": { + "@grpc/grpc-js": "~1.6.0", + "@grpc/proto-loader": "^0.6.12", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^4.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^7.14.0", + "is-stream-ended": "^0.1.4", + "node-fetch": "^2.6.1", + "object-hash": "^3.0.0", + "proto3-json-serializer": "^0.1.8", + "protobufjs": "6.11.3", + "retry-request": "^4.0.0" + }, + "dependencies": { + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "optional": true + } + } + } + } + }, + "google-p12-pem": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz", + "integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==", + "optional": true, + "requires": { + "node-forge": "^1.3.1" + } + }, + "gtoken": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz", + "integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==", + "optional": true, + "requires": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.1.3", + "jws": "^4.0.0" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "optional": true + }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "optional": true, + "requires": { + "bignumber.js": "^9.0.0" } + }, + "jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", + "optional": true, + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "optional": true + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "optional": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "optional": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true } } }, @@ -1702,89 +2090,285 @@ } }, "@google-cloud/storage": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-4.1.3.tgz", - "integrity": "sha512-79Ag+4eQq+KFJcKB85AimepoqTJOGuDLAmJd7JkLc8NM12a87JTCoGi65oi1eZ4H77AV0uUQxSS2Fo/hZL3+kQ==", + "version": "5.20.5", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.20.5.tgz", + "integrity": "sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==", "optional": true, "requires": { - "@google-cloud/common": "^2.1.1", - "@google-cloud/paginator": "^2.0.0", - "@google-cloud/promisify": "^1.0.0", + "@google-cloud/paginator": "^3.0.7", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "abort-controller": "^3.0.0", "arrify": "^2.0.0", + "async-retry": "^1.3.3", "compressible": "^2.0.12", - "concat-stream": "^2.0.0", - "date-and-time": "^0.11.0", - "duplexify": "^3.5.0", + "configstore": "^5.0.0", + "duplexify": "^4.0.0", + "ent": "^2.2.0", "extend": "^3.0.2", - "gaxios": "^2.0.1", - "gcs-resumable-upload": "^2.2.4", + "gaxios": "^4.0.0", + "google-auth-library": "^7.14.1", "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", + "mime": "^3.0.0", "mime-types": "^2.0.8", - "onetime": "^5.1.0", - "p-limit": "^2.2.0", + "p-limit": "^3.0.1", "pumpify": "^2.0.0", - "readable-stream": "^3.4.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "through2": "^3.0.0", + "retry-request": "^4.2.2", + "stream-events": "^1.0.4", + "teeny-request": "^7.1.3", + "uuid": "^8.0.0", "xdg-basedir": "^4.0.0" }, "dependencies": { + "@google-cloud/paginator": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz", + "integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==", + "optional": true, + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, + "@google-cloud/projectify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz", + "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==", + "optional": true + }, + "@google-cloud/promisify": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz", + "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==", + "optional": true + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "optional": true }, - "concat-stream": { + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "optional": true + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "optional": true, + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "crypto-random-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "optional": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "optional": true, "requires": { - "buffer-from": "^1.0.0", + "ms": "2.1.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "optional": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" } }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "gaxios": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz", + "integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==", + "optional": true, + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.7" + } + }, + "gcp-metadata": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz", + "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==", + "optional": true, + "requires": { + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" + } + }, + "google-auth-library": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz", + "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==", + "optional": true, + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + }, + "google-p12-pem": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz", + "integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==", + "optional": true, + "requires": { + "node-forge": "^1.3.1" + } + }, + "gtoken": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz", + "integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==", + "optional": true, + "requires": { + "gaxios": "^4.0.0", + "google-p12-pem": "^3.1.3", + "jws": "^4.0.0" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "optional": true }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "optional": true }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "optional": true, "requires": { - "mimic-fn": "^2.1.0" + "bignumber.js": "^9.0.0" } }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "jwa": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "optional": true, "requires": { - "p-try": "^2.0.0" + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "jws": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", + "optional": true, + "requires": { + "jwa": "^2.0.0", + "safe-buffer": "^5.0.1" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "optional": true, + "requires": { + "semver": "^6.0.0" + } + }, + "mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "optional": true }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true + }, + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "optional": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "optional": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, "pumpify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", @@ -1794,26 +2378,12 @@ "duplexify": "^4.1.1", "inherits": "^2.0.3", "pump": "^3.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - } } }, "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "optional": true, "requires": { "inherits": "^2.0.3", @@ -1821,13 +2391,47 @@ "util-deprecate": "^1.0.1" } }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "retry-request": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz", + "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==", + "optional": true, + "requires": { + "debug": "^4.1.1", + "extend": "^3.0.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "optional": true + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "optional": true, "requires": { - "readable-stream": "2 || 3" + "crypto-random-string": "^2.0.0" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "optional": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "xdg-basedir": { @@ -1835,6 +2439,12 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "optional": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true } } }, @@ -1880,11 +2490,11 @@ } }, "@likecoin/iscn-js": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@likecoin/iscn-js/-/iscn-js-0.0.7.tgz", - "integrity": "sha512-hUnUiSuOFl/j+2UckKuEp8lKfpCmmggO4vXm8r0cY4N5ut9moApJmHq0nkcSDzbLtIbRSxWd8u9ZMp+MsiHsuA==", + "version": "0.2.0-rc.1", + "resolved": "https://registry.npmjs.org/@likecoin/iscn-js/-/iscn-js-0.2.0-rc.1.tgz", + "integrity": "sha512-sKFgoWmqo5AopVP+30kNc6ubjNVeaMFm+UZl85pAE6CDqIhBtEvnsaq7ml005JchisSTryzomQ42wM++Z8Jn9A==", "requires": { - "@likecoin/iscn-message-types": "^0.0.1", + "@likecoin/iscn-message-types": "0.0.3-rc.1", "bignumber.js": "^9.0.1", "buffer": "^6.0.3", "fast-json-stable-stringify": "^2.1.0" @@ -1917,9 +2527,9 @@ } }, "@likecoin/iscn-message-types": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@likecoin/iscn-message-types/-/iscn-message-types-0.0.1.tgz", - "integrity": "sha512-tNAgwQ/kynXu5k2upFiytOBDrNoixa0SvW/OxaJx91+PQYaGodAL+BQZbZs6VamT2q3JqO0SEZplNqgfxwxTfw==" + "version": "0.0.3-rc.1", + "resolved": "https://registry.npmjs.org/@likecoin/iscn-message-types/-/iscn-message-types-0.0.3-rc.1.tgz", + "integrity": "sha512-shWRi1DZ8WWRsZCVTsf17MNvCAEdy4v5eYAcZjOcmA8w7RyXIr70ol+AMT468JBszbMQgPOIfOyxxado+SM2xA==" }, "@likecoin/likecoin-email-templates": { "version": "1.2.2", @@ -1988,6 +2598,16 @@ "resolved": "https://registry.npmjs.org/@multiformats/base-x/-/base-x-4.0.1.tgz", "integrity": "sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw==" }, + "@noble/hashes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.0.0.tgz", + "integrity": "sha512-DZVbtY62kc3kkBtMHqwCOfXrT/hnoORy5BJ4+HU1IR59X0KWAOqsfzQPcUl/lQLlG7qXbe/fZ3r/emxtAl+sqg==" + }, + "@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -2083,6 +2703,12 @@ "defer-to-connect": "^1.0.1" } }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true + }, "@types/bn.js": { "version": "4.11.5", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.5.tgz", @@ -2091,11 +2717,28 @@ "@types/node": "*" } }, + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "requires": { + "@types/node": "*" + } + }, "@types/duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", @@ -2104,6 +2747,27 @@ "@types/node": "*" } }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.29", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz", + "integrity": "sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", @@ -2114,11 +2778,24 @@ "@types/node": "*" } }, + "@types/jsonwebtoken": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", + "integrity": "sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A==", + "requires": { + "@types/node": "*" + } + }, "@types/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -2147,6 +2824,16 @@ "@types/node": "*" } }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" + }, "@types/request": { "version": "2.48.4", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz", @@ -2178,6 +2865,15 @@ "@types/node": "*" } }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "@types/tough-cookie": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz", @@ -2411,10 +3107,30 @@ "dev": true }, "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "optional": true + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "optional": true, + "requires": { + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true + } + } }, "agentkeepalive": { "version": "4.1.3", @@ -2746,6 +3462,15 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, + "async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "optional": true, + "requires": { + "retry": "0.13.1" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3598,32 +4323,14 @@ }, "bignumber.js": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.0.1.tgz", - "integrity": "sha512-zAySveTJXkgLYCBi0b14xzfnOs+f3G6x36I8w2a1+PFQpWk/dp0mI0F+ZZK2bu+3ELewDcSyP+Cfq++NcHX7sg==" - }, - "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", - "dev": true - }, - "bip39": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", - "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", - "requires": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" - }, - "dependencies": { - "@types/node": { - "version": "11.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" - } - } + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.0.1.tgz", + "integrity": "sha512-zAySveTJXkgLYCBi0b14xzfnOs+f3G6x36I8w2a1+PFQpWk/dp0mI0F+ZZK2bu+3ELewDcSyP+Cfq++NcHX7sg==" + }, + "binary-extensions": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "dev": true }, "bip66": { "version": "1.1.5", @@ -3633,6 +4340,52 @@ "safe-buffer": "^5.0.1" } }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "blakejs": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", @@ -3889,41 +4642,6 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, - "bun": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/bun/-/bun-0.0.12.tgz", - "integrity": "sha512-Toms18J9DqnT+IfWkwxVTB2EaBprHvjlMWrTIsfX4xbu3ZBqVBwrERU0em1IgtRe04wT+wJxMlKHZok24hrcSQ==", - "optional": true, - "requires": { - "readable-stream": "~1.0.32" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "optional": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "optional": true - } - } - }, "busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", @@ -4303,6 +5021,51 @@ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "optional": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", @@ -4328,7 +5091,7 @@ "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==" }, "collection-visit": { "version": "1.0.0", @@ -4363,9 +5126,9 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -4480,7 +5243,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "constants-browserify": { "version": "1.0.0", @@ -4689,28 +5452,28 @@ } }, "cosmjs-types": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.2.0.tgz", - "integrity": "sha512-9/jBr7kxfHg8HCNzUi9hxutU2GldrScXXSjfTZWuZHlFJmn5sJDXlvxSWhpeWIorHRxN8CtxDPmt7zdo/+BYDg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cosmjs-types/-/cosmjs-types-0.5.0.tgz", + "integrity": "sha512-Qy2yxDp5HasBUnBV5OL9EOuTJw94LAbCWfiRb5QcW1sqh93KSSY5PpNMB3rTsxwuPcf/k3CNRY02DeQMjrsJuA==", "requires": { "long": "^4.0.0", "protobufjs": "~6.11.2" }, "dependencies": { "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==" }, "@types/node": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.7.tgz", - "integrity": "sha512-aDDY54sst8sx47CWT6QQqIZp45yURq4dic0+HCYfYNcY5Ejlb/CLmFnRLfy3wQuYafOeh3lB/DAKaqRKBtcZmA==" + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz", + "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==" }, "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -4846,12 +5609,6 @@ "assert-plus": "^1.0.0" } }, - "date-and-time": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-0.11.1.tgz", - "integrity": "sha512-+1JkWME+UWRpCfvE1T0Vfbw629Ego0IcfHH0qtP4KhAXs7IJT2qsg1hNePqZhyD8Wby46HlW393lSL5PZSzDsA==", - "optional": true - }, "date-now": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", @@ -4912,7 +5669,8 @@ "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true }, "deep-extend": { "version": "0.6.0", @@ -5053,7 +5811,7 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, "depd": { "version": "1.1.2", @@ -5077,7 +5835,7 @@ "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==" }, "dicer": { "version": "0.2.5", @@ -5319,6 +6077,12 @@ "integrity": "sha512-r4eRSeStEGf6M5SKdrQhhLK5bOwOBxQhIE3YSTnZE3GpKiLfnnhE+tPtrJE79+eDJgm39BM6LSoI8SCx4HbwlQ==", "dev": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "optional": true + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -5362,7 +6126,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==", "optional": true }, "equal-length": { @@ -5496,8 +6260,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -6549,9 +7312,9 @@ "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" }, "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "requires": { "websocket-driver": ">=0.5.1" } @@ -6677,38 +7440,48 @@ } }, "firebase-admin": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.8.0.tgz", - "integrity": "sha512-IKtyL7doZu3Sh3pCz+O7vFWc/UwxEfXe263X/bPbucu/qEsM+5UdljIklnInSMunO+A1BUXKtsKkQf91iZQ2Ew==", - "requires": { - "@firebase/database": "^0.5.11", - "@google-cloud/firestore": "^2.6.0", - "@google-cloud/storage": "^4.1.2", - "@types/node": "^8.0.53", + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz", + "integrity": "sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==", + "requires": { + "@firebase/database-compat": "^0.1.1", + "@firebase/database-types": "^0.7.2", + "@google-cloud/firestore": "^4.5.0", + "@google-cloud/storage": "^5.3.0", + "@types/node": ">=12.12.47", "dicer": "^0.3.0", - "jsonwebtoken": "8.1.0", - "node-forge": "0.7.4" + "jsonwebtoken": "^8.5.1", + "jwks-rsa": "^2.0.2", + "node-forge": "^0.10.0" }, "dependencies": { "@types/node": { - "version": "8.10.59", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz", - "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==" + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==" }, "dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.1.tgz", + "integrity": "sha512-ObioMtXnmjYs3aRtpIJt9rgQSPCIhKVkFPip+E9GUDyWl8N435znUxK/JfNwGZJ2wnn5JKQ7Ly3vOK5Q5dylGA==", "requires": { - "streamsearch": "0.1.2" + "streamsearch": "^1.1.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" } }, "jsonwebtoken": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz", - "integrity": "sha1-xjl80uX9WD1lwAeoPce7eOaYK4M=", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", "requires": { - "jws": "^3.1.4", + "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", @@ -6716,9 +7489,38 @@ "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", - "ms": "^2.0.0", - "xtend": "^4.0.1" + "ms": "^2.1.1", + "semver": "^5.6.0" } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" } } }, @@ -6954,7 +7756,7 @@ "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "integrity": "sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==", "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -6969,12 +7771,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==" }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", "requires": { "number-is-nan": "^1.0.0" } @@ -6982,7 +7784,7 @@ "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6992,7 +7794,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "requires": { "ansi-regex": "^2.0.0" } @@ -7041,155 +7843,34 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "gcp-metadata": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.3.0.tgz", - "integrity": "sha512-uO3P/aByOQmoDu5bOYBODHmD1oDCZw7/R8SYY0MdmMQSZVEmeTSxmiM1vwde+YHYSpkaQnAAMAIZuOqLvgfp/Q==", - "requires": { - "gaxios": "^2.1.0", - "json-bigint": "^0.3.0" - } - }, - "gcs-resumable-upload": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-2.3.2.tgz", - "integrity": "sha512-OPS0iAmPCV+r7PziOIhyxmQOzsazFCy76yYDOS/Z80O/7cuny1KMfqDQa2T0jLaL8EreTU7EMZG5pUuqBKgzHA==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "configstore": "^5.0.0", - "gaxios": "^2.0.0", - "google-auth-library": "^5.0.0", - "pumpify": "^2.0.0", - "stream-events": "^1.0.4" - }, - "dependencies": { - "configstore": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.0.tgz", - "integrity": "sha512-eE/hvMs7qw7DlcB5JPRnthmrITuHMmACUJAp89v6PT6iOqzoLS7HRWhBtuHMlhNHo2AhUSA/3Dh1bKNJHcublQ==", - "optional": true, - "requires": { - "dot-prop": "^5.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "optional": true - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "optional": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "optional": true - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", - "optional": true, - "requires": { - "semver": "^6.0.0" - } - }, - "pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "optional": true, - "requires": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "optional": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", - "optional": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "optional": true + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, + "gcp-metadata": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.3.0.tgz", + "integrity": "sha512-uO3P/aByOQmoDu5bOYBODHmD1oDCZw7/R8SYY0MdmMQSZVEmeTSxmiM1vwde+YHYSpkaQnAAMAIZuOqLvgfp/Q==", + "requires": { + "gaxios": "^2.1.0", + "json-bigint": "^0.3.0" + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "optional": true + }, "get-iterator": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-iterator/-/get-iterator-1.0.2.tgz", @@ -7223,7 +7904,7 @@ "github-from-package": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "glob": { "version": "7.1.3", @@ -7292,9 +7973,9 @@ "dev": true }, "globalthis": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", - "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "requires": { "define-properties": "^1.1.3" } @@ -7542,7 +8223,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "has-value": { "version": "1.0.0", @@ -7586,13 +8267,10 @@ } }, "hash-stream-validation": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.2.tgz", - "integrity": "sha512-cMlva5CxWZOrlS/cY0C+9qAzesn5srhFA8IT1VPiHc9bWWBLkJfEUIZr7MWoi89oOOGmpg8ymchaOjiArsGu5A==", - "optional": true, - "requires": { - "through2": "^2.0.0" - } + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz", + "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==", + "optional": true }, "hash.js": { "version": "1.1.7", @@ -7656,27 +8334,28 @@ "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" }, "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", + "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==" }, "http-proxy-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-3.0.0.tgz", - "integrity": "sha512-uGuJaBWQWDQCJI5ip0d/VTYZW0nRrlLWXA4A7P1jrsa+f77rW2yXz315oBt6zGCF6l8C2tlMxY7ffULCj+5FhA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", "optional": true, "requires": { - "agent-base": "5", + "@tootallnate/once": "2", + "agent-base": "6", "debug": "4" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "optional": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -7704,22 +8383,22 @@ "dev": true }, "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "optional": true, "requires": { - "agent-base": "5", + "agent-base": "6", "debug": "4" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "optional": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -9123,6 +9802,14 @@ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" }, + "jose": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.5.tgz", + "integrity": "sha512-BAiDNeDKTMgk4tvD0BbxJ8xHEHBZgpeRZ1zGPPsitSyMgjoMWiLGYAE7H7NpP5h0lPppQajQs871E8NHUrzVPA==", + "requires": { + "@panva/asn1.js": "^1.0.0" + } + }, "js-levenshtein": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.4.tgz", @@ -9139,11 +9826,6 @@ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" }, - "js-sha512": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", - "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" - }, "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -9311,6 +9993,34 @@ "safe-buffer": "^5.0.1" } }, + "jwks-rsa": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.4.tgz", + "integrity": "sha512-mpArfgPkUpX11lNtGxsF/szkasUcbWHGplZl/uFvFO2NuMHmt0dQXIihh0rkPU2yQd5niQtuUHbXnG/WKiXF6Q==", + "requires": { + "@types/express": "^4.17.13", + "@types/jsonwebtoken": "^8.5.8", + "debug": "^4.3.4", + "jose": "^2.0.5", + "limiter": "^1.1.5", + "lru-memoizer": "^2.1.4" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "jws": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", @@ -9354,18 +10064,23 @@ } }, "libsodium": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.9.tgz", - "integrity": "sha512-gfeADtR4D/CM0oRUviKBViMGXZDgnFdMKMzHsvBdqLBHd9ySi6EtYnmuhHVDDYgYpAO8eU8hEY+F8vIUAPh08A==" + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.10.tgz", + "integrity": "sha512-eY+z7hDrDKxkAK+QKZVNv92A5KYkxfvIshtBJkmg5TSiCnYqZP3i9OO9whE79Pwgm4jGaoHgkM4ao/b9Cyu4zQ==" }, "libsodium-wrappers": { - "version": "0.7.9", - "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz", - "integrity": "sha512-9HaAeBGk1nKTRFRHkt7nzxqCvnkWTjn1pdjKgcUnZxj0FyOP4CnhgFhMdrFfgNsukijBGyBLpP2m2uKT1vuWhQ==", + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz", + "integrity": "sha512-pO3F1Q9NPLB/MWIhehim42b/Fwb30JNScCNh8TcQ/kIc+qGLQch8ag8wb0keK3EP5kbGakk1H8Wwo7v+36rNQg==", "requires": { "libsodium": "^0.7.0" } }, + "limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -9485,8 +10200,7 @@ "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, "lodash.clonedeepwith": { "version": "4.5.0", @@ -9626,6 +10340,31 @@ "yallist": "^3.0.2" } }, + "lru-memoizer": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.4.tgz", + "integrity": "sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + } + } + }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -10281,9 +11020,9 @@ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "node-forge": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.4.tgz", - "integrity": "sha512-8Df0906+tq/omxuCZD6PqhPaQDYuyJ1d+VITgxoIA8zvQd1ru+nMJcDChHH324MWitIgbVkAkQoGEEVJNpn/PA==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, "node-gyp-build": { "version": "4.3.0", @@ -10471,7 +11210,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==" }, "number-to-bn": { "version": "1.7.0", @@ -12308,14 +13047,14 @@ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", + "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", "requires": { "decompress-response": "^4.2.0", "once": "^1.3.1", @@ -12373,6 +13112,50 @@ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", "dev": true }, + "proto3-json-serializer": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.9.tgz", + "integrity": "sha512-A60IisqvnuI45qNRygJjrnNjX2TMdQGMY+57tR3nul3ZgO2zXkR9OGR8AXxJhkqx84g0FTnrfi3D5fWMSdANdQ==", + "optional": true, + "requires": { + "protobufjs": "^6.11.2" + }, + "dependencies": { + "@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "optional": true + }, + "@types/node": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz", + "integrity": "sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA==", + "optional": true + }, + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "optional": true, + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } + }, "protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", @@ -12411,8 +13194,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.1.31", @@ -12910,6 +13692,12 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "optional": true + }, "require-precompiled": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", @@ -13013,6 +13801,12 @@ "resolved": "https://registry.npmjs.org/retimer/-/retimer-2.0.0.tgz", "integrity": "sha512-KLXY85WkEq2V2bKex/LOO1ViXVn2KGYe4PYysAdYdjmraYIUsVkXu8O4am+8+5UbaaGl1qho4aqAAPHNQ4GSbg==" }, + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "optional": true + }, "retry-request": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.0.0.tgz", @@ -13296,7 +14090,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "set-value": { "version": "2.0.0", @@ -13389,17 +14183,17 @@ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==" }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "requires": { "lru-cache": "^6.0.0" } }, "simple-get": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz", - "integrity": "sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "requires": { "decompress-response": "^6.0.0", "once": "^1.3.1", @@ -13451,7 +14245,7 @@ "simple-swizzle": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "requires": { "is-arrayish": "^0.3.1" }, @@ -13486,12 +14280,6 @@ "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", "dev": true }, - "snakeize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", - "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", - "optional": true - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -13903,7 +14691,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==", "optional": true }, "supertap": { @@ -14108,42 +14896,6 @@ "readable-stream": "^3.1.1" }, "dependencies": { - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - } - } - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -14166,16 +14918,33 @@ } }, "teeny-request": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-5.3.3.tgz", - "integrity": "sha512-t5RRd5xK9ku05x6U5kclFHNpy/cLSNdClcZ2USKQZYcDz4hWux7+2N1eRmuZ+hWNtnkp2RTf9zl8urlSGR5Smg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.2.0.tgz", + "integrity": "sha512-SyY0pek1zWsi0LRVAALem+avzMLc33MKW/JLLakdP4s9+D7+jHcy5x6P+h94g2QNZsAqQNfX5lsbd3WSeJXrrw==", "optional": true, "requires": { - "http-proxy-agent": "^3.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.2.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", "stream-events": "^1.0.5", - "uuid": "^3.3.2" + "uuid": "^8.0.0" + }, + "dependencies": { + "node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "optional": true, + "requires": { + "whatwg-url": "^5.0.0" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true + } } }, "term-size": { @@ -15475,19 +16244,19 @@ } }, "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", + "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" }, "well-known-symbols": { "version": "2.0.0", @@ -15514,11 +16283,11 @@ } }, "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, "widest-line": { @@ -15545,6 +16314,75 @@ "errno": "~0.1.7" } }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "optional": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -15683,6 +16521,67 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "optional": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "optional": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "optional": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "optional": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "optional": true + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "optional": true + } + } + }, "yargs-parser": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", @@ -15691,6 +16590,12 @@ "requires": { "camelcase": "^4.1.0" } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "optional": true } } } diff --git a/package.json b/package.json index 45188551b..9f0f940f5 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,9 @@ ] }, "dependencies": { - "@cosmjs/stargate": "^0.26.1", + "@cosmjs/stargate": "^0.28.4", "@google-cloud/pubsub": "^1.2.0", - "@likecoin/iscn-js": "0.0.7", + "@likecoin/iscn-js": "0.2.0-rc.1", "@likecoin/likecoin-email-templates": "^1.2.2", "@likecoin/secretd-js": "^0.4.3", "@sendgrid/mail": "^6.5.5", @@ -60,7 +60,7 @@ "compression": "^1.7.3", "cookie-parser": "^1.4.3", "cors": "^2.8.5", - "cosmjs-types": "^0.2.0", + "cosmjs-types": "^0.5.0", "create-hash": "^1.2.0", "disposable-email-domains": "^1.0.56", "eth-sig-util": "^2.5.4", @@ -70,7 +70,7 @@ "express-rate-limit": "^3.3.2", "fast-json-stable-stringify": "^2.1.0", "file-type": "^12.4.2", - "firebase-admin": "^8.8.0", + "firebase-admin": "^9.12.0", "i18n": "^0.8.3", "ipfs-http-client": "^53.0.1", "ipfs-only-hash": "^4.0.0", diff --git a/src/assets/book.png b/src/assets/book.png new file mode 100644 index 000000000..cd67d29a3 Binary files /dev/null and b/src/assets/book.png differ diff --git a/src/assets/iscn.png b/src/assets/iscn.png new file mode 100644 index 000000000..82d11cb41 Binary files /dev/null and b/src/assets/iscn.png differ diff --git a/src/constant/index.js b/src/constant/index.js index fe3184d5a..b4478c605 100644 --- a/src/constant/index.js +++ b/src/constant/index.js @@ -19,6 +19,8 @@ export const LOGIN_MESSAGE = 'Login - Reinventing the Like'; export const EXTERNAL_HOSTNAME = process.env.EXTERNAL_HOSTNAME || (IS_TESTNET ? 'rinkeby.like.co' : 'like.co'); +export const API_EXTERNAL_HOSTNAME = process.env.API_EXTERNAL_HOSTNAME || `api.${EXTERNAL_HOSTNAME}`; + export const GETTING_STARTED_TASKS = ['taskSocial', 'taskOnepager', 'taskVideo', 'taskPaymentPage']; export const TRANSACTION_QUERY_LIMIT = 10; @@ -139,3 +141,7 @@ export const LIKE_DEFAULT_PRICE = 0.0082625; export const KICKBOX_DISPOSIBLE_API = 'https://open.kickbox.com/v1/disposable'; export const COINGECKO_AR_LIKE_PRICE_API = 'https://api.coingecko.com/api/v3/simple/price?ids=arweave,likecoin&vs_currencies=usd'; + +export const LIKECOIN_DARK_GREEN_THEME_COLOR = '#28646E'; + +export const APP_LIKE_CO_ISCN_VIEW_URL = `https://app.${IS_TESTNET ? 'rinkeby.' : ''}like.co/view/`; diff --git a/src/middleware/likernft.js b/src/middleware/likernft.js new file mode 100644 index 000000000..b61072269 --- /dev/null +++ b/src/middleware/likernft.js @@ -0,0 +1,26 @@ +import { ValidationError } from '../util/ValidationError'; +import { + getISCNIdByClassId, getCurrentClassIdByISCNId, getISCNPrefixDocName, +} from '../util/api/likernft'; + +export const fetchISCNIdAndClassId = async (req, res, next) => { + try { + let { iscn_id: iscnId, class_id: classId } = req.query; + if (!iscnId && !classId) throw new ValidationError('MISSING_ISCN_OR_CLASS_ID'); + + if (!iscnId) { + iscnId = await getISCNIdByClassId(classId); + } + if (!classId) { + classId = await getCurrentClassIdByISCNId(iscnId); + } + res.locals.iscnId = iscnId; + res.locals.classId = classId; + res.locals.iscnPrefix = getISCNPrefixDocName(iscnId); + next(); + } catch (err) { + next(err); + } +}; + +export default fetchISCNIdAndClassId; diff --git a/src/routes/getPublicInfo.js b/src/routes/getPublicInfo.js index 3c4f4676d..f8e99b8cd 100644 --- a/src/routes/getPublicInfo.js +++ b/src/routes/getPublicInfo.js @@ -14,6 +14,7 @@ import oembed from './oembed'; import cosmos from './cosmos'; import arweave from './arweave'; import iscn from './iscn'; +import likernft from './likernft'; const router = Router(); @@ -31,5 +32,6 @@ router.use('/oembed', oembed); router.use('/cosmos', cosmos); router.use('/arweave', arweave); router.use('/iscn', iscn); +router.use('/likernft', likernft); export default router; diff --git a/src/routes/likernft/history.js b/src/routes/likernft/history.js new file mode 100644 index 000000000..4d8cfdab4 --- /dev/null +++ b/src/routes/likernft/history.js @@ -0,0 +1,83 @@ +import { Router } from 'express'; +import axios from 'axios'; +import { ValidationError } from '../../util/ValidationError'; +import { getISCNDocByClassId } from '../../util/api/likernft'; +import { fetchISCNIdAndClassId } from '../../middleware/likernft'; +import { COSMOS_LCD_INDEXER_ENDPOINT } from '../../../config/config'; + +const router = Router(); + +router.get( + '/history', + fetchISCNIdAndClassId, + async (req, res, next) => { + try { + const { nft_id: nftId } = req.query; + const { classId } = res.locals; + if (nftId && !classId) { + throw new ValidationError('PLEASE_DEFINE_CLASS_ID'); + } + let list = []; + const doc = await getISCNDocByClassId(classId); + let queryObj = await doc.ref.collection('transaction'); + if (nftId) queryObj = queryObj.where('nftId', '==', nftId); + const query = await queryObj.orderBy('timestamp', 'desc').get(); + list = query.docs.map(d => ({ txHash: d.id, ...(d.data() || {}) })); + res.json({ + list, + }); + } catch (err) { + next(err); + } + }, +); + +router.get( + '/events', + fetchISCNIdAndClassId, + async (_, res, next) => { + try { + const { classId } = res.locals; + const [ + { data: newClassData }, + { data: mintData }, + { data: sendData }, + ] = await Promise.all([ + axios.get(`${COSMOS_LCD_INDEXER_ENDPOINT}/cosmos/tx/v1beta1/txs?events=likechain.likenft.v1.EventNewClass.class_id=%27%22${classId}%22%27`), + axios.get(`${COSMOS_LCD_INDEXER_ENDPOINT}/cosmos/tx/v1beta1/txs?events=likechain.likenft.v1.EventMintNFT.class_id=%27%22${classId}%22%27`), + axios.get(`${COSMOS_LCD_INDEXER_ENDPOINT}/cosmos/tx/v1beta1/txs?events=cosmos.nft.v1beta1.EventSend.class_id=%27%22${classId}%22%27`), + ]); + let list = []; + list = list.concat(newClassData.tx_responses || []); + let set = new Set(list.map(t => t.txhash)); + list = list.concat((mintData.tx_responses || []).filter(t => !set.has(t.txhash))); + set = new Set(list.map(t => t.txhash)); + list = list.concat((sendData.tx_responses || []).filter(t => !set.has(t.txhash))); + list = list.map((d) => { + const { + height, + txhash, + code, + logs, + tx, + timestamp, + } = d; + return { + height, + txhash, + code, + logs, + tx, + timestamp, + }; + }).sort((a, b) => b.timestamp - a.timestamp); + res.json({ + list, + }); + } catch (err) { + next(err); + } + }, +); + +export default router; diff --git a/src/routes/likernft/index.js b/src/routes/likernft/index.js new file mode 100644 index 000000000..9dbd9ee9e --- /dev/null +++ b/src/routes/likernft/index.js @@ -0,0 +1,12 @@ +import * as fs from 'fs'; +import { Router } from 'express'; + +const router = Router(); + +fs.readdirSync(__dirname).forEach((file) => { + const name = file.split('.')[0]; + if (!name || name === 'index') return; + router.use(require(`./${name}`).default); // eslint-disable-line import/no-dynamic-require,global-require +}); + +export default router; diff --git a/src/routes/likernft/metadata.js b/src/routes/likernft/metadata.js new file mode 100644 index 000000000..584e220f1 --- /dev/null +++ b/src/routes/likernft/metadata.js @@ -0,0 +1,118 @@ +import { Router } from 'express'; +import axios from 'axios'; +import { ONE_DAY_IN_S, API_EXTERNAL_HOSTNAME } from '../../constant'; +import { likeNFTCollection, iscnInfoCollection } from '../../util/firebase'; +import { filterLikeNFTMetadata } from '../../util/ValidationHelper'; +import { getISCNIdByClassId } from '../../util/api/likernft'; +import { + getLikerNFTDynamicData, getBasicImage, getCombinedImage, getResizedImage, +} from '../../util/api/likernft/metadata'; +import { getNFTISCNData, getNFTClassDataById, getNFTOwner } from '../../util/cosmos/nft'; +import { fetchISCNIdAndClassId } from '../../middleware/likernft'; +import { getISCNPrefix } from '../../util/cosmos/iscn'; +import { LIKER_NFT_TARGET_ADDRESS } from '../../../config/config'; +import { ValidationError } from '../../util/ValidationError'; +import { sleep } from '../../util/misc'; + +const router = Router(); + +router.get( + '/metadata', + fetchISCNIdAndClassId, + async (_, res, next) => { + try { + const { classId, iscnId, iscnPrefix } = res.locals; + const classDocRef = likeNFTCollection.doc(iscnPrefix).collection('class').doc(classId); + + const classDoc = await classDocRef.get(); + const classData = classDoc.data(); + if (!classData) { + res.status(404).send('NFT_DATA_NOT_FOUND'); + return; + } + const [{ owner: iscnOwner, data: iscnData }, chainData, dynamicData] = await Promise.all([ + getNFTISCNData(iscnId).catch((err) => { console.error(err); return {}; }), + getNFTClassDataById(classId).catch(err => console.error(err)), + getLikerNFTDynamicData(classId, classData).catch(err => console.error(err)), + ]); + if (!iscnData) throw new ValidationError('ISCN_NOT_FOUND'); + if (!chainData) throw new ValidationError('NFT_CLASS_NOT_FOUND'); + if (!dynamicData) throw new ValidationError('NFT_CLASS_NOT_REGISTERED'); + + res.set('Cache-Control', `public, max-age=${60}, s-maxage=${60}, stale-if-error=${ONE_DAY_IN_S}`); + res.json(filterLikeNFTMetadata({ + iscnId: getISCNPrefix(iscnId), + iscnOwner, + iscnStakeholders: iscnData.stakeholders, + ...(classData.metadata || {}), + ...chainData, + ...dynamicData, + })); + } catch (err) { + next(err); + } + }, +); + +router.get( + '/metadata/owners', + fetchISCNIdAndClassId, + async (_, res, next) => { + try { + const { classId, iscnPrefix } = res.locals; + const nftQuery = await likeNFTCollection.doc(iscnPrefix) + .collection('class').doc(classId) + .collection('nft') + .where('ownerWallet', '!=', LIKER_NFT_TARGET_ADDRESS) + .get(); + const nftIds = nftQuery.docs.map(n => n.id); + const ownerMap = { + // don't include api holded wallet + // LIKER_NFT_TARGET_ADDRESS: apiOwnedNFTIds, + }; + const owners = await Promise.all(nftIds.map(id => getNFTOwner(classId, id))); + owners.forEach((owner, index) => { + ownerMap[owner] = ownerMap[owner] || []; + ownerMap[owner].push(nftIds[index]); + }); + res.set('Cache-Control', `public, max-age=${60}, s-maxage=${60}, stale-if-error=${ONE_DAY_IN_S}`); + res.json(ownerMap); + } catch (err) { + next(err); + } + }, +); + +router.get( + '/metadata/image/class_(:classId)(.png)?', + async (req, res, next) => { + try { + const { classId } = req.params; + const iscnId = await getISCNIdByClassId(classId); + let iscnData = await iscnInfoCollection.doc(encodeURIComponent(iscnId)).get(); + if (!iscnData.exists) { + await axios.post( + `https://${API_EXTERNAL_HOSTNAME}/like/info`, + { iscnId }, + ); + await sleep(1000); + iscnData = await iscnInfoCollection.doc(encodeURIComponent(iscnId)).get(); + } + let image = ''; + let title = ''; + if (iscnData.exists) { + ({ image, title } = iscnData.data()); + } + const basicImage = await getBasicImage(image, title); + const resizedImage = getResizedImage(); + const combinedImage = await getCombinedImage(); + res.set('Cache-Control', `public, max-age=${60}, s-maxage=${60}, stale-if-error=${ONE_DAY_IN_S}`); + basicImage.pipe(resizedImage).pipe(combinedImage).pipe(res); + return; + } catch (err) { + next(err); + } + }, +); + +export default router; diff --git a/src/routes/likernft/mint.js b/src/routes/likernft/mint.js new file mode 100644 index 000000000..32057468e --- /dev/null +++ b/src/routes/likernft/mint.js @@ -0,0 +1,93 @@ +import { Router } from 'express'; +import { filterLikeNFTISCNData } from '../../util/ValidationHelper'; +import { ValidationError } from '../../util/ValidationError'; +import { likeNFTCollection } from '../../util/firebase'; +import { parseNFTInformationFromSendTxHash, writeMintedNFTInfo } from '../../util/api/likernft/mint'; +import { getISCNPrefixDocName, getISCNDocByClassId } from '../../util/api/likernft'; +import { getNFTsByClassId, getNFTClassIdByISCNId } from '../../util/cosmos/nft'; +import { fetchISCNIdAndClassId } from '../../middleware/likernft'; +import { getISCNPrefix } from '../../util/cosmos/iscn'; +import { LIKER_NFT_TARGET_ADDRESS } from '../../../config/config'; + +const router = Router(); + +router.get( + '/mint', + fetchISCNIdAndClassId, + async (_, res, next) => { + try { + const { classId } = res.locals; + const doc = await getISCNDocByClassId(classId); + const iscnNFTData = doc.data(); + if (!iscnNFTData) { + res.sendStatus(404); + return; + } + const iscnId = decodeURIComponent(doc.id); + res.json(filterLikeNFTISCNData({ iscnId, ...doc.data() })); + } catch (err) { + next(err); + } + }, +); + +router.post( + '/mint', + async (req, res, next) => { + try { + const { + iscn_id: iscnId, + tx_hash: txHash, + class_id: inputClassId, + } = req.query; + if (!iscnId) throw new ValidationError('MISSING_ISCN_ID'); + const iscnPrefix = getISCNPrefixDocName(iscnId); + const likeNFTDoc = await likeNFTCollection.doc(iscnPrefix).get(); + const likeNFTdata = likeNFTDoc.data(); + if (likeNFTdata) { + res.sendStatus(409); + return; + } + + let classId = inputClassId; + let sellerWallet; + if (txHash) { + const info = await parseNFTInformationFromSendTxHash(txHash); + if (info) { + const { + classId: resClassId, + fromWallet, + } = info; + if (classId && classId !== resClassId) throw new ValidationError('CLASS_ID_NOT_MATCH_TX'); + classId = resClassId; + sellerWallet = fromWallet; + } + } + if (!classId) { + classId = await getNFTClassIdByISCNId(iscnId); + } + if (!classId) throw new ValidationError('CANNOT_FETCH_CLASS_ID'); + const { + nfts, + } = await getNFTsByClassId(classId, LIKER_NFT_TARGET_ADDRESS); + if (!nfts[0]) throw new ValidationError('NFT_NOT_RECEIVED'); + + await writeMintedNFTInfo(iscnId, { + classId, + totalCount: nfts.length, + uri: nfts[0].uri, + }, nfts); + + res.json({ + classId, + iscnId: getISCNPrefix(iscnId), + nftCount: nfts.length, + sellerWallet, + }); + } catch (err) { + next(err); + } + }, +); + +export default router; diff --git a/src/routes/likernft/purchase.js b/src/routes/likernft/purchase.js new file mode 100644 index 000000000..6a9f792f0 --- /dev/null +++ b/src/routes/likernft/purchase.js @@ -0,0 +1,83 @@ +import { Router } from 'express'; +import { ValidationError } from '../../util/ValidationError'; +import { filterLikeNFTISCNData } from '../../util/ValidationHelper'; +import { + getLatestNFTPriceAndInfo, + getGasPrice, + checkTxGrantAndAmount, + processNFTPurchase, +} from '../../util/api/likernft/purchase'; +import { getISCNPrefix } from '../../util/cosmos/iscn'; +import { fetchISCNIdAndClassId } from '../../middleware/likernft'; + +const router = Router(); + +router.get( + '/purchase', + fetchISCNIdAndClassId, + async (_, res, next) => { + try { + try { + const { iscnId, classId } = res.locals; + const { price, lastSoldPrice, ...info } = await getLatestNFTPriceAndInfo(iscnId, classId); + const gasFee = getGasPrice(); + res.json({ + price, + gasFee, + totalPrice: price + gasFee, + lastSoldPrice, + metadata: filterLikeNFTISCNData({ + ...info, + iscnId: getISCNPrefix(iscnId), + }), + }); + } catch (err) { + next(err); + } + } catch (err) { + next(err); + } + }, +); + +router.post( + '/purchase', + fetchISCNIdAndClassId, + async (req, res, next) => { + try { + const { tx_hash: txHash } = req.query; + if (!txHash) throw new ValidationError('MISSING_TX_HASH'); + const { iscnId, classId } = res.locals; + const { price: nftPrice } = await getLatestNFTPriceAndInfo(iscnId, classId); + if (nftPrice <= 0) throw new ValidationError('NFT_SOLD_OUT'); + const gasFee = getGasPrice(); + const totalPrice = nftPrice + gasFee; + const result = await checkTxGrantAndAmount(txHash, totalPrice); + if (!result) { + throw new ValidationError('SEND_GRANT_NOT_FOUND'); + } + const { + granter: likeWallet, + spendLimit: grantedAmount, + } = result; + const { + transactionHash, + nftId, + nftPrice: actualNftPrice, + gasFee: actualGasFee, + } = await processNFTPurchase(likeWallet, iscnId, classId, grantedAmount); + res.json({ + txHash: transactionHash, + iscnId: getISCNPrefix(iscnId), + classId, + nftId, + nftPrice: actualNftPrice, + gasFee: actualGasFee, + }); + } catch (err) { + next(err); + } + }, +); + +export default router; diff --git a/src/routes/likernft/user.js b/src/routes/likernft/user.js new file mode 100644 index 000000000..dd4daf991 --- /dev/null +++ b/src/routes/likernft/user.js @@ -0,0 +1,57 @@ +import { Router } from 'express'; +import { db, likeNFTCollection } from '../../util/firebase'; +import { isValidLikeAddress } from '../../util/cosmos'; +import { ValidationError } from '../../util/ValidationError'; + + +const router = Router(); + +router.get( + '/user/:wallet/own', + async (req, res, next) => { + try { + const { wallet } = req.params; + if (!isValidLikeAddress(wallet)) throw new ValidationError('INVALID_WALLET'); + // TODO: swap to chain based query + const query = await db.collectionGroup('nft').where('ownerWallet', '==', wallet).get(); + const list = query.docs.map(d => d.data().classId); + const uniqueList = Array.from(new Set(list)); + res.json({ + list: uniqueList, + }); + } catch (err) { + next(err); + } + }, +); + +router.get( + '/user/:wallet/sell', + async (req, res, next) => { + try { + const { wallet } = req.params; + if (!isValidLikeAddress(wallet)) throw new ValidationError('INVALID_WALLET'); + const [sellingNftsQuery, createdClassesQuery] = await Promise.all([ + db.collectionGroup('nft') + .where('sellerWallet', '==', wallet) + .where('soldCount', '>=', 0).get(), + // TODO: what if iscn owner changed? + likeNFTCollection.where('creatorWallet', '==', wallet).get(), + ]); + const classIdSet = new Set(); + sellingNftsQuery.docs.forEach((doc) => { + classIdSet.add(doc.data().classId); + }); + createdClassesQuery.docs.forEach((doc) => { + classIdSet.add(doc.data().classId); + }); + res.json({ + list: Array.from(classIdSet), + }); + } catch (err) { + next(err); + } + }, +); + +export default router; diff --git a/src/util/ValidationHelper.js b/src/util/ValidationHelper.js index c3bc1d9e1..998dcb1ba 100644 --- a/src/util/ValidationHelper.js +++ b/src/util/ValidationHelper.js @@ -316,6 +316,56 @@ export function filterSocialLinksMeta({ }; } +export function filterLikeNFTISCNData({ + iscnId, + classId, + totalCount, + currentPrice, + basePrice, + soldCount, + classUri, + creatorWallet, +}) { + return { + iscnId, + classId, + totalCount, + currentPrice, + basePrice, + soldCount, + classUri, + creatorWallet, + }; +} + + +export function filterLikeNFTMetadata({ + image, + externalUrl, + description, + name, + backgroundColor, + animationUrl, + youtubeUrl, + iscnOwner, + iscnStakeholders, + iscnId, +}) { + // key with underscore as in https://docs.opensea.io/docs/metadata-standards + return { + image, + external_url: externalUrl, + description, + name, + background_color: backgroundColor, + animation_url: animationUrl, + youtube_url: youtubeUrl, + iscn_id: iscnId, + iscn_owner: iscnOwner, + iscn_stakeholders: iscnStakeholders, + }; +} + export function filterOAuthClientInfo({ avatar, audience, diff --git a/src/util/api/likernft/index.js b/src/util/api/likernft/index.js new file mode 100644 index 000000000..0c8130578 --- /dev/null +++ b/src/util/api/likernft/index.js @@ -0,0 +1,41 @@ +import { parseNFTClassDataFields } from '@likecoin/iscn-js/dist/messages/parsing'; +import { getISCNPrefix } from '../../cosmos/iscn'; +import { ValidationError } from '../../ValidationError'; +import { likeNFTCollection } from '../../firebase'; +import { getNFTQueryClient } from '../../cosmos/nft'; + +export function getISCNPrefixDocName(iscnId) { + const prefix = getISCNPrefix(iscnId); + return encodeURIComponent(prefix); +} + +export async function getCurrentClassIdByISCNId(iscnId) { + const iscnPrefix = getISCNPrefixDocName(iscnId); + const iscnDoc = await likeNFTCollection.doc(iscnPrefix).get(); + const iscnData = iscnDoc.data(); + if (!iscnData) { + throw new ValidationError('ISCN_NFT_NOT_FOUND'); + } + return iscnData.classId; +} + +export async function getISCNDocByClassId(classId) { + const iscnQuery = await likeNFTCollection.where('classId', '==', classId).limit(1).get(); + if (!iscnQuery.docs.length) { + throw new ValidationError('NFT_CLASS_NOT_FOUND'); + } + return iscnQuery.docs[0]; +} + +export async function getISCNIdByClassId(classId) { + const doc = await getISCNDocByClassId(classId); + return decodeURIComponent(doc.id); +} + + +export async function getNFTClassByClassId(classId) { + const c = await getNFTQueryClient(); + const client = await c.getQueryClient(); + const res = await client.nft.class(classId); + return parseNFTClassDataFields(res); +} diff --git a/src/util/api/likernft/metadata.js b/src/util/api/likernft/metadata.js new file mode 100644 index 000000000..8802e854e --- /dev/null +++ b/src/util/api/likernft/metadata.js @@ -0,0 +1,84 @@ +import path from 'path'; +import axios from 'axios'; +import sharp from 'sharp'; +import { API_EXTERNAL_HOSTNAME } from '../../../constant'; + +const IMAGE_HEIGHT = 512; +const IMAGE_WIDTH = 512; + +async function addTextOnImage(text, color) { + const svgImage = ` + + + ${text} + + `; + return Buffer.from(svgImage); +} + +let maskData; +export async function getImageMask() { + if (maskData) return maskData; + const imgPath = path.join(__dirname, '../../../assets/book.png'); + maskData = await sharp(imgPath) + .resize({ + height: IMAGE_HEIGHT, + width: IMAGE_HEIGHT, + }) + .extractChannel('alpha') + .toBuffer(); + return maskData; +} + +export async function getBasicImage(image, title) { + let imageBuffer; + if (image) { + imageBuffer = (await axios.get(image, { responseType: 'stream' })).data; + } else { + const textDataBuffer = await addTextOnImage(title, 'black'); + imageBuffer = await sharp(textDataBuffer) + .png() + .flatten({ background: { r: 250, g: 250, b: 250 } }); + } + return imageBuffer; +} + +export async function getCombinedImage() { + const maskBuffer = await getImageMask(); + return sharp() + .ensureAlpha() + .joinChannel(maskBuffer); +} + +export function getResizedImage() { + return sharp() + .resize({ + fit: sharp.fit.cover, + width: IMAGE_WIDTH, + height: IMAGE_HEIGHT, + }) + .png(); +} + +export async function getDynamicBackgroundColor(soldCount) { + // TODO: replace with actual color map + if (soldCount > 100) { + return '#28646e'; + } if (soldCount > 10) { + return '#16a122'; + } if (soldCount > 1) { + return '#50e3c2'; + } + return '#d2f0f0'; +} + +export async function getLikerNFTDynamicData(classId, classData) { + const { soldCount } = classData; + const backgroundColor = await getDynamicBackgroundColor(soldCount); + return { + image: `https://${API_EXTERNAL_HOSTNAME}/likernft/metadata/image/class_${classId}.png`, + backgroundColor, + }; +} diff --git a/src/util/api/likernft/mint.js b/src/util/api/likernft/mint.js new file mode 100644 index 000000000..46ab8b16c --- /dev/null +++ b/src/util/api/likernft/mint.js @@ -0,0 +1,111 @@ +import { parseTxInfoFromIndexedTx } from '@likecoin/iscn-js/dist/messages/parsing'; +import { getISCNPrefixDocName } from '.'; +import { db, likeNFTCollection } from '../../firebase'; +import { getNFTQueryClient, getNFTISCNData } from '../../cosmos/nft'; +import { LIKER_NFT_TARGET_ADDRESS } from '../../../../config/config'; +import { getNFTBatchInfo } from './purchase'; +import { + AVATAR_DEFAULT_PATH, + APP_LIKE_CO_ISCN_VIEW_URL, + LIKECOIN_DARK_GREEN_THEME_COLOR, +} from '../../../constant'; + +export async function parseNFTInformationFromSendTxHash(txHash, target = LIKER_NFT_TARGET_ADDRESS) { + const client = await getNFTQueryClient(); + const q = await client.getStargateClient(); + const tx = await q.getTx(txHash); + const parsed = parseTxInfoFromIndexedTx(tx); + const messages = parsed.tx.body.messages + .filter(m => m.typeUrl === '/cosmos.nft.v1beta1.MsgSend') + .filter(m => m.value.receiver === target); + if (!messages.length) return null; + const nftIds = messages.map(m => m.value.id); + return { + fromWallet: messages[0].value.sender, + total: messages.length, + classId: messages[0].value.classId, + nftIds, + }; +} + +export async function writeMintedNFTInfo(iscnId, classData, nfts) { + const iscnPrefix = getISCNPrefixDocName(iscnId); + const { + owner: sellerWallet, + data: iscnData, + } = await getNFTISCNData(iscnId); + const url = iscnData.contentMetadata && iscnData.contentMetadata.url; + const timestamp = Date.now(); + const { + classId, + name = '', + description = '', + totalCount, + uri = '', + } = classData; + const currentBatch = 0; + const { price, count } = getNFTBatchInfo(currentBatch); + await Promise.all([ + likeNFTCollection.doc(iscnPrefix).create({ + classId, + classes: [classId], + totalCount, + nftRemainingCount: nfts.length, + currentPrice: price, + currentBatch, + batchRemainingCount: count, + basePrice: price, + soldCount: 0, + classUri: uri, + creatorWallet: sellerWallet, + procrssingCount: 0, + timestamp, + }), + likeNFTCollection.doc(iscnPrefix).collection('class').doc(classId).create({ + id: classId, + uri, + lastSoldPrice: 0, + soldCount: 0, + creatorWallet: sellerWallet, + timestamp, + metadata: { + image: AVATAR_DEFAULT_PATH, // TODO: replace with default NFT image + externalUrl: url || `${APP_LIKE_CO_ISCN_VIEW_URL}${encodeURIComponent(iscnId)}`, + description, + name, + backgroundColor: LIKECOIN_DARK_GREEN_THEME_COLOR, + }, + }), + ]); + let batch = db.batch(); + for (let i = 0; i < nfts.length; i += 1) { + const { + id: nftId, + uri: nftUri, + } = nfts[i]; + batch.create( + likeNFTCollection.doc(iscnPrefix) + .collection('class').doc(classId) + .collection('nft') + .doc(nftId), + { + id: nftId, + uri: nftUri, + price: 0, + soldCount: 0, + isSold: false, + isProcessing: false, + classId, + sellerWallet, + ownerWallet: LIKER_NFT_TARGET_ADDRESS, + timestamp, + }, + ); + if (i % 500 === 0) { + // eslint-disable-next-line no-await-in-loop + await batch.commit(); + batch = db.batch(); + } + } + await batch.commit(); +} diff --git a/src/util/api/likernft/purchase.js b/src/util/api/likernft/purchase.js new file mode 100644 index 000000000..9217dd551 --- /dev/null +++ b/src/util/api/likernft/purchase.js @@ -0,0 +1,362 @@ +import BigNumber from 'bignumber.js'; +import { parseTxInfoFromIndexedTx } from '@likecoin/iscn-js/dist/messages/parsing'; +import { formatMsgExecSendAuthorization } from '@likecoin/iscn-js/dist/messages/authz'; +import { formatMsgSend } from '@likecoin/iscn-js/dist/messages/likenft'; +import { db, likeNFTCollection, FieldValue } from '../../firebase'; +import { + getNFTQueryClient, getNFTISCNData, getLikerNFTSigningClient, getLikerNFTSigningAddressInfo, +} from '../../cosmos/nft'; +import { getISCNStakeholderRewards } from '../../cosmos/iscn'; +import { DEFAULT_GAS_PRICE, calculateTxGasFee, sendTransactionWithSequence } from '../../cosmos/tx'; +import { + NFT_COSMOS_DENOM, + NFT_CHAIN_ID, + LIKER_NFT_TARGET_ADDRESS, + LIKER_NFT_GAS_FEE, + LIKER_NFT_STARTING_PRICE, + LIKER_NFT_PRICE_MULTIPLY, + LIKER_NFT_PRICE_DECAY, + LIKER_NFT_DECAY_START_BATCH, + LIKER_NFT_DECAY_END_BATCH, +} from '../../../../config/config'; +import { ValidationError } from '../../ValidationError'; +import { getISCNPrefixDocName } from '.'; + +const SELLER_RATIO = 0.8; +const STAKEHOLDERS_RATIO = 0.2; +const EXPIRATION_BUFFER_TIME = 10000; + +export async function getLowerestUnsoldNFT(iscnId, classId) { + const iscnPrefix = getISCNPrefixDocName(iscnId); + const res = await likeNFTCollection.doc(iscnPrefix) + .collection('class').doc(classId) + .collection('nft') + .where('isSold', '==', false) + .where('isProcessing', '==', false) + .where('price', '>=', 0) + .orderBy('price') + .limit(1) + .get(); + if (!res.docs.length) return null; + const doc = res.docs[0]; + const payload = { + id: doc.id, + ...doc.data(), + }; + return payload; +} + +export async function getLatestNFTPriceAndInfo(iscnId, classId) { + const iscnPrefix = getISCNPrefixDocName(iscnId); + const [nftData, nftDoc] = await Promise.all([ + getLowerestUnsoldNFT(iscnId, classId), + likeNFTCollection.doc(iscnPrefix).get(), + ]); + const nftDocData = nftDoc.data(); + let price = -1; + const { + currentPrice, + lastSoldPrice, + } = nftDocData; + if (nftData) { + // nft has defined price + if (nftData.price) { + ({ price } = nftData); + } else { + // use current price for 0/undefined price nft + price = currentPrice; + } + } + return { + ...nftDocData, + lastSoldPrice: lastSoldPrice || currentPrice, + price, + }; +} + +export function getGasPrice() { + return new BigNumber(LIKER_NFT_GAS_FEE).multipliedBy(DEFAULT_GAS_PRICE).shiftedBy(-9).toNumber(); +} + +export function getNFTBatchInfo(batchNumber) { + const count = batchNumber + 1; + const baseMultiplier = Math.min(batchNumber, LIKER_NFT_DECAY_START_BATCH); + let price = LIKER_NFT_STARTING_PRICE * (LIKER_NFT_PRICE_MULTIPLY ** baseMultiplier); + const decayMultiplier = Math.min( + LIKER_NFT_DECAY_END_BATCH - LIKER_NFT_DECAY_START_BATCH, + Math.max(batchNumber - LIKER_NFT_DECAY_START_BATCH, 0), + ); + let lastPrice = price; + for (let i = 1; i <= decayMultiplier; i += 1) { + price += Math.round(lastPrice * (1 - LIKER_NFT_PRICE_DECAY * i)); + lastPrice = price; + } + return { + price, + count, + }; +} + +export async function checkTxGrantAndAmount(txHash, totalPrice, target = LIKER_NFT_TARGET_ADDRESS) { + const client = await getNFTQueryClient(); + const q = await client.getStargateClient(); + const tx = await q.getTx(txHash); + const parsed = parseTxInfoFromIndexedTx(tx); + let messages = parsed.tx.body.messages + .filter(m => m.typeUrl === '/cosmos.authz.v1beta1.MsgGrant'); + if (!messages.length) throw new ValidationError('GRANT_MSG_NOT_FOUND'); + messages = messages.filter(m => m.value.grantee === target); + if (!messages.length) throw new ValidationError('INCORRECT_GRANT_TARGET'); + const message = messages.find(m => m.value.grant.authorization.typeUrl === '/cosmos.bank.v1beta1.SendAuthorization'); + if (!message) throw new ValidationError('SEND_GRANT_NOT_FOUND'); + const { granter, grant } = message.value; + const { authorization, expiration } = grant; + if (Date.now() + EXPIRATION_BUFFER_TIME > expiration * 1000) throw new ValidationError('GRANT_EXPIRED'); + const qs = await client.getQueryClient(); + try { + const c = await qs.authz.grants(granter, target, '/cosmos.bank.v1beta1.MsgSend'); + if (!c) throw new ValidationError('GRANT_NOT_FOUND'); + } catch (err) { + if (err.message.includes('no authorization found')) { + throw new ValidationError('GRANT_NOT_FOUND'); + } + throw err; + } + // TODO: parse limit from query instead of tx + const { spendLimit } = authorization.value; + const limit = spendLimit.find(s => s.denom === NFT_COSMOS_DENOM); + if (!limit) throw new ValidationError('SEND_GRANT_DENOM_NOT_FOUND'); + const { amount } = limit; + const amountInLIKE = new BigNumber(amount).shiftedBy(-9); + if (amountInLIKE.lt(totalPrice)) throw new ValidationError('GRANT_AMOUNT_NOT_ENOUGH'); + + const balance = await q.getBalance(granter, NFT_COSMOS_DENOM); + const balanceAmountInLIKE = new BigNumber(balance.amount || 0).shiftedBy(-9); + if (balanceAmountInLIKE.lt(totalPrice)) throw new ValidationError('GRANTER_AMOUNT_NOT_ENOUGH'); + return { + granter, + spendLimit: amountInLIKE.toNumber(), + }; +} + +export async function processNFTPurchase(likeWallet, iscnId, classId, grantedAmount) { + const iscnData = await getNFTISCNData(iscnId); + if (!iscnData) throw new Error('ISCN_DATA_NOT_FOUND'); + const iscnPrefix = getISCNPrefixDocName(iscnId); + + // get price + const nftData = await getLowerestUnsoldNFT(iscnId, classId); + const { + id: nftId, + price: nftItemPrice, + sellerWallet: nftItemSellerWallet, + } = nftData; + + const isFirstSale = !nftItemPrice; // first sale if price = 0; + + const iscnRef = likeNFTCollection.doc(iscnPrefix); + const classRef = iscnRef.collection('class').doc(classId); + const nftRef = classRef.collection('nft').doc(nftId); + + // lock iscn nft + const { price: currentPrice, batch: currentBatch } = await db.runTransaction(async (t) => { + const doc = await t.get(iscnRef); + const nftDoc = await t.get(nftRef); + const { isProcessing } = nftDoc.data(); + if (isProcessing) throw new ValidationError('ANOTHER_PURCHASE_IN_PROGRESS'); + const docData = doc.data(); + if (!docData) throw new ValidationError('ISCN_NFT_NOT_FOUND'); + const { + processingCount = 0, + currentPrice: price, + currentBatch: batch, + batchRemainingCount, + } = docData; + if (processingCount >= batchRemainingCount) { + throw new ValidationError('ANOTHER_PURCHASE_IN_PROGRESS'); + } + if (price > grantedAmount) { + throw new ValidationError('GRANT_NOT_MATCH_UPDATED_PRICE'); + } + t.update(iscnRef, { processingCount: FieldValue.increment(1) }); + t.update(nftRef, { isProcessing: true }); + return { price, batch }; + }); + try { + const gasFee = getGasPrice(); + let sellerWallet; + const { owner, data } = iscnData; + let nftPrice; + if (isFirstSale) { + nftPrice = currentPrice; + sellerWallet = owner; + } else { + nftPrice = nftItemPrice; + sellerWallet = nftItemSellerWallet || owner; + } + + const totalPrice = nftPrice + gasFee; + const totalAmount = new BigNumber(totalPrice).shiftedBy(9).toFixed(0); + const sellerAmount = new BigNumber(nftPrice) + .multipliedBy(SELLER_RATIO).shiftedBy(9).toFixed(0); + const stakeholdersAmount = new BigNumber(nftPrice) + .multipliedBy(STAKEHOLDERS_RATIO).shiftedBy(9).toFixed(0); + const transferMessages = [ + { + typeUrl: '/cosmos.bank.v1beta1.MsgSend', + value: { + fromAddress: LIKER_NFT_TARGET_ADDRESS, + toAddress: sellerWallet, + amount: [{ denom: NFT_COSMOS_DENOM, amount: sellerAmount }], + }, + }, + ]; + + const stakeholderMap = await getISCNStakeholderRewards(data, stakeholdersAmount, owner); + stakeholderMap.forEach((amount, wallet) => { + transferMessages.push( + { + typeUrl: '/cosmos.bank.v1beta1.MsgSend', + value: { + fromAddress: LIKER_NFT_TARGET_ADDRESS, + toAddress: wallet, + amount: [{ denom: NFT_COSMOS_DENOM, amount }], + }, + }, + ); + }); + const signingClient = await getLikerNFTSigningClient(); + const txMessages = [ + formatMsgExecSendAuthorization( + LIKER_NFT_TARGET_ADDRESS, + likeWallet, + LIKER_NFT_TARGET_ADDRESS, + [{ denom: NFT_COSMOS_DENOM, amount: totalAmount }], + ), + formatMsgSend( + LIKER_NFT_TARGET_ADDRESS, + likeWallet, + classId, + nftId, + ), + ...transferMessages, + ]; + let res; + const client = signingClient.getSigningStargateClient(); + const fee = calculateTxGasFee(txMessages.length, NFT_COSMOS_DENOM); + const { address, accountNumber } = await getLikerNFTSigningAddressInfo(); + const txSigningFunction = ({ sequence }) => client.sign( + address, + txMessages, + fee, + 'like.co NFT API', + { + accountNumber, + sequence, + chainId: NFT_CHAIN_ID, + }, + ); + try { + res = await sendTransactionWithSequence( + address, + txSigningFunction, + client, + ); + } catch (err) { + console.error(err); + throw new ValidationError(err); + } + const { transactionHash, code } = res; + if (code !== 0) throw new ValidationError('TX_NOT_SUCCESS'); + const timestamp = Date.now(); + // update price and unlock + await db.runTransaction(async (t) => { + const doc = await t.get(iscnRef); + const docData = doc.data(); + const { + currentPrice: dbCurrentPrice, + currentBatch: dbCurrentBatch, + batchRemainingCount: dbBatchRemainingCount, + processingCount: dbProcessingCount, + } = docData; + const fromWallet = LIKER_NFT_TARGET_ADDRESS; + const toWallet = likeWallet; + let updatedBatch = dbCurrentBatch; + let batchRemainingCount = dbBatchRemainingCount; + let newPrice = dbCurrentPrice; + let processingCount = dbProcessingCount; + if (dbCurrentBatch === currentBatch) { + processingCount = FieldValue.increment(-1); + if (isFirstSale) { + batchRemainingCount -= 1; + const isNewBatch = batchRemainingCount <= 0; + if (isNewBatch) { + processingCount = 0; + updatedBatch = dbCurrentBatch + 1; + ({ price: newPrice, count: batchRemainingCount } = getNFTBatchInfo(updatedBatch)); + } + } + } + t.update(iscnRef, { + currentPrice: newPrice, + currentBatch: updatedBatch, + batchRemainingCount, + processingCount, + soldCount: FieldValue.increment(1), + nftRemainingCount: FieldValue.increment(-1), + lastSoldPrice: nftPrice, + lastSoldTimestamp: timestamp, + }); + t.update(classRef, { + lastSoldPrice: nftPrice, + lastSoldNftId: nftId, + lastSoldTimestamp: timestamp, + soldCount: FieldValue.increment(1), + }); + t.update(nftRef, { + price: nftPrice, + lastSoldPrice: nftPrice, + soldCount: FieldValue.increment(1), + isSold: true, + isProcessing: false, + ownerWallet: toWallet, + lastSoldTimestamp: timestamp, + sellerWallet: null, + }); + t.create(iscnRef.collection('transaction') + .doc(transactionHash), { + txHash: transactionHash, + price: nftPrice, + classId, + nftId, + timestamp, + fromWallet, + toWallet, + sellerWallet, + sellerLIKE: new BigNumber(sellerAmount).shiftedBy(-9).toFixed(), + stakeholderWallets: [...stakeholderMap.keys()], + stakeholderLIKEs: [...stakeholderMap.values()] + .map(a => new BigNumber(a).shiftedBy(-9).toFixed()), + }); + }); + return { + transactionHash, + classId, + nftId, + nftPrice, + gasFee, + }; + } catch (err) { + console.error(err); + // reset lock + await db.runTransaction(async (t) => { + const doc = await t.get(likeNFTCollection.doc(iscnPrefix)); + const docData = doc.data(); + const { currentBatch: docCurrentBatch } = docData; + if (docCurrentBatch === currentBatch) { + t.update(iscnRef, { processingCount: FieldValue.increment(-1) }); + } + }); + throw err; + } +} diff --git a/src/util/cosmos/index.js b/src/util/cosmos/index.js index 656ffb63e..b5248a912 100644 --- a/src/util/cosmos/index.js +++ b/src/util/cosmos/index.js @@ -44,9 +44,9 @@ export async function getCosmosTotalSupply() { let cosmosQueryClient = null; -async function getQueryClient() { +export async function getQueryClient(rpc = cosmosRpcEndpoint) { if (!cosmosQueryClient) { - const tendermint34Client = await Tendermint34Client.connect(cosmosRpcEndpoint); + const tendermint34Client = await Tendermint34Client.connect(rpc); const queryClient = QueryClient.withExtensions( tendermint34Client, setupAuthExtension, @@ -95,6 +95,15 @@ export function verifyCosmosSignInPayload({ return valid; } +export function isValidAddress(address) { + try { + bech32.decode(address); + return true; + } catch (error) { + return false; + } +} + export function isValidCosmosAddress(address) { return /^cosmos1[ac-hj-np-z02-9]{38}$/.test(address); } diff --git a/src/util/cosmos/iscn.js b/src/util/cosmos/iscn.js index 10d859310..b6c531244 100644 --- a/src/util/cosmos/iscn.js +++ b/src/util/cosmos/iscn.js @@ -1,10 +1,14 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing'; +import BigNumber from 'bignumber.js'; import { ISCNQueryClient, ISCNSigningClient } from '@likecoin/iscn-js'; -import { getAccountInfo } from '.'; +import { getAccountInfo, isValidAddress, convertAddressPrefix } from '.'; +import { getUserWithCivicLikerProperties } from '../api/users/getPublicInfo'; import { COSMOS_PRIVATE_KEY } from '../../../config/secret'; import { COSMOS_RPC_ENDPOINT, COSMOS_SIGNING_RPC_ENDPOINT } from '../../../config/config'; +export { parseTxInfoFromIndexedTx } from '@likecoin/iscn-js/dist/messages/parsing'; + let queryClient = null; let signingClient = null; let signingWallet = null; @@ -19,13 +23,18 @@ export async function getISCNQueryClient() { return queryClient; } +export async function createISCNSigningClient(privateKey) { + const privateKeyBytes = Buffer.from(privateKey, 'hex'); + const signer = await DirectSecp256k1Wallet.fromKey(privateKeyBytes, 'like'); + const [wallet] = await signer.getAccounts(); + const client = new ISCNSigningClient(); + await client.connectWithSigner(COSMOS_SIGNING_RPC_ENDPOINT, signer); + return { client, wallet }; +} + export async function getISCNSigningClient() { if (!signingClient) { - const privateKeyBytes = Buffer.from(COSMOS_PRIVATE_KEY, 'hex'); - const signer = await DirectSecp256k1Wallet.fromKey(privateKeyBytes); - const [wallet] = await signer.getAccounts(); - const client = new ISCNSigningClient(); - await client.connectWithSigner(COSMOS_SIGNING_RPC_ENDPOINT, signer); + const { client, wallet } = await createISCNSigningClient(COSMOS_PRIVATE_KEY); signingWallet = wallet; signingClient = client; } @@ -43,3 +52,70 @@ export async function getISCNSigningAddressInfo() { accountNumber: signingAccountNumber, }; } + +export function getISCNPrefix(input) { + const res = /^(iscn:\/\/likecoin-chain\/[A-Za-z0-9-_]+)\/[0-9]+$/.exec(input); + if (!res) return input; + const [, prefix] = res; + return prefix; +} + +export async function getLikeWalletAndLikerIdFromId(id) { + let likeWallet = null; + let likerId = null; + + const res = id.match(/^https:\/\/like\.co\/([a-z0-9_-]{6,20})/); + if (res) { + [, likerId] = res; + const info = await getUserWithCivicLikerProperties(likerId); + if (info) { + ({ likeWallet } = info); + } + } else { + let inputAddress = id; + const addressLengthWithoutPrefixAnd1 = 38; + if (id.startsWith('did:like:')) { + inputAddress = `like1${id.slice(id.length - addressLengthWithoutPrefixAnd1)}`; + } else if (id.startsWith('did:cosmos:')) { + inputAddress = `cosmos1${id.slice(id.length - addressLengthWithoutPrefixAnd1)}`; + } + + if (isValidAddress(inputAddress)) { + likeWallet = convertAddressPrefix(inputAddress, 'like'); + } + } + return { likeWallet, likerId }; +} + +export async function getISCNStakeholderRewards(iscnData, rewardAmount, owner = null) { + const amountMap = new Map(); + const { stakeholders } = iscnData; + if (stakeholders && stakeholders.length) { + const likeWalletsAndLikerIds = await Promise.all(stakeholders.map(async (stakeholder) => { + const id = stakeholder.entity['@id']; + const res = await getLikeWalletAndLikerIdFromId(id); + return res && res.likeWallet; + })); + const weightMap = new Map(); + likeWalletsAndLikerIds.forEach((likeWallet, i) => { + if (likeWallet) { + let weight = new BigNumber(stakeholders[i].rewardProportion); + if (weightMap.has(likeWallet)) { + weight = weightMap.get(likeWallet).plus(weight); + } + weightMap.set(likeWallet, weight); + } + }); + const totalWeight = [...weightMap.values()] + .reduce((prev, curr) => prev.plus(curr), new BigNumber(0)); + weightMap.forEach((weight, address) => { + const amount = weight.times(rewardAmount).div(totalWeight).toFixed(0, 1); + amountMap.set(address, amount); + }); + } + + if (!amountMap.size && owner) { + amountMap.set(owner, rewardAmount); + } + return amountMap; +} diff --git a/src/util/cosmos/nft.js b/src/util/cosmos/nft.js new file mode 100644 index 000000000..d0227c5fa --- /dev/null +++ b/src/util/cosmos/nft.js @@ -0,0 +1,126 @@ + +// eslint-disable-next-line import/no-extraneous-dependencies +import { DirectSecp256k1Wallet } from '@cosmjs/proto-signing'; +import { ISCNQueryClient, ISCNSigningClient } from '@likecoin/iscn-js'; +import { BaseAccount } from 'cosmjs-types/cosmos/auth/v1beta1/auth'; +import { PageRequest } from 'cosmjs-types/cosmos/base/query/v1beta1/pagination'; +import { getQueryClient } from '.'; +import { getISCNPrefix } from './iscn'; +import { LIKER_NFT_PRIVATE_KEY } from '../../../config/secret'; +import { NFT_RPC_ENDPOINT, NFT_SIGNING_RPC_ENDPOINT } from '../../../config/config'; + +let queryClient = null; +let signingClient = null; +let signingWallet = null; +let signingAccountNumber = null; + +export async function getNFTQueryClient() { + if (!queryClient) { + const client = new ISCNQueryClient(); + await client.connect(NFT_RPC_ENDPOINT); + queryClient = client; + } + return queryClient; +} + +export async function getNFTAccountInfo(address) { + const q = await getQueryClient(NFT_RPC_ENDPOINT); + const { value } = await q.auth.account(address); + const accountInfo = BaseAccount.decode(value); + return accountInfo; +} + +export async function createNFTSigningClient(privateKey) { + const privateKeyBytes = Buffer.from(privateKey, 'hex'); + const signer = await DirectSecp256k1Wallet.fromKey(privateKeyBytes, 'like'); + const [wallet] = await signer.getAccounts(); + const client = new ISCNSigningClient(); + await client.connectWithSigner(NFT_SIGNING_RPC_ENDPOINT, signer); + return { client, wallet }; +} + +export async function getNFTISCNData(iscnId) { + const client = await getNFTQueryClient(); + const res = await client.queryRecordsById(iscnId); + if (!res || !res.records || !res.records.length) return {}; + return { + owner: res.owner, + data: res.records[0].data, + }; +} + +export async function getNFTISCNOwner(iscnId) { + const res = await getNFTISCNData(iscnId); + return res && res.owner; +} + +export async function getISCNFromNFTClassId(classId) { + const c = await getNFTQueryClient(); + const client = await c.getQueryClient(); + const res = await client.likenft.ISCNByClass(classId); + if (!res) return null; + const { iscnIdPrefix, owner } = res; + return { + iscnIdPrefix, + owner, + }; +} + +export async function getNFTClassDataById(classId) { + const client = await getNFTQueryClient(); + const res = await client.queryNFTClass(classId); + if (!res) return null; + return res.class; +} + +export async function getNFTsByClassId(classId, address) { + const c = await getNFTQueryClient(); + const client = await c.getQueryClient(); + let nfts = []; + let next = new Uint8Array([0x00]); + do { + /* eslint-disable no-await-in-loop */ + const res = await client.nft.NFTs(classId, address, PageRequest.fromPartial({ key: next })); + ({ nextKey: next } = res.pagination); + nfts = nfts.concat(res.nfts); + } while (next && next.length); + const nftIds = nfts.map(n => n.id); + return { nftIds, nfts }; +} + +export async function getNFTClassIdByISCNId(iscnId) { + const iscnPrefix = getISCNPrefix(iscnId); + const c = await getNFTQueryClient(); + const client = await c.getQueryClient(); + const res = await client.likenft.classesByISCN(iscnPrefix); + if (!res || !res.classes || !res.classes[0]) return ''; + return res.classes[0].id; +} + +export async function getNFTOwner(classId, nftId) { + const c = await getNFTQueryClient(); + const client = await c.getQueryClient(); + const res = await client.nft.owner(classId, nftId); + return res.owner; +} + +export async function getLikerNFTSigningClient() { + if (!signingClient) { + const { client, wallet } = await createNFTSigningClient(LIKER_NFT_PRIVATE_KEY); + signingWallet = wallet; + signingClient = client; + } + return signingClient; +} + +export async function getLikerNFTSigningAddressInfo() { + if (!signingWallet) await getLikerNFTSigningClient(); + if (!signingAccountNumber) { + const { accountNumber } = await getNFTAccountInfo(signingWallet.address); + signingAccountNumber = accountNumber; + } + return { + address: signingWallet.address, + accountNumber: signingAccountNumber, + }; +} diff --git a/src/util/cosmos/tx.js b/src/util/cosmos/tx.js index 38815a783..04523afac 100644 --- a/src/util/cosmos/tx.js +++ b/src/util/cosmos/tx.js @@ -4,6 +4,7 @@ import { StargateClient } from '@cosmjs/stargate'; import { MsgSend } from 'cosmjs-types/cosmos/bank/v1beta1/tx'; import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx'; import createHash from 'create-hash'; +import BigNumber from 'bignumber.js'; import { getAccountInfo } from './index'; import { db, txCollection as txLogRef } from '../firebase'; import { sleep } from '../misc'; @@ -84,8 +85,8 @@ async function computeTransactionHash(signedTx) { return txHash.toUpperCase(); } -async function internalSendTransaction(signedTx) { - const client = await getBroadcastClient(); +async function internalSendTransaction(signedTx, c) { + const client = c || await getBroadcastClient(); const txBytes = TxRaw.encode(signedTx).finish(); try { const res = await client.broadcastTx(txBytes); @@ -100,7 +101,7 @@ async function internalSendTransaction(signedTx) { } } -export async function sendTransactionWithSequence(senderAddress, signingFunction) { +export async function sendTransactionWithSequence(senderAddress, signingFunction, client) { let res; let signedTx; const { sequence: seq1 } = await getAccountInfo(senderAddress); @@ -118,7 +119,7 @@ export async function sendTransactionWithSequence(senderAddress, signingFunction }); signedTx = await signingFunction({ sequence: pendingCount }); try { - res = await internalSendTransaction(signedTx); + res = await internalSendTransaction(signedTx, client); } catch (err) { // eslint-disable-next-line no-console console.error(err); @@ -136,7 +137,7 @@ export async function sendTransactionWithSequence(senderAddress, signingFunction try { if (!res) { - res = await internalSendTransaction(signedTx); + res = await internalSendTransaction(signedTx, client); } await db.runTransaction(t => t.get(counterRef).then((d) => { if (pendingCount + 1 > d.data().value) { @@ -167,13 +168,18 @@ export async function sendTransactionWithSequence(senderAddress, signingFunction }; } -export function generateSendTxData(senderAddress, toAddress, amount) { +export function calculateTxGasFee(messageLength = 1, denom = COSMOS_DENOM) { const gas = DEFAULT_TRANSFER_GAS; - const feeAmount = (gas * DEFAULT_GAS_PRICE).toFixed(0); - const fee = { - amount: [{ denom: COSMOS_DENOM, amount: feeAmount }], - gas: gas.toString(), + const feeAmount = new BigNumber(gas) + .multipliedBy(DEFAULT_GAS_PRICE).multipliedBy(messageLength).toFixed(0); + return { + amount: [{ denom, amount: feeAmount }], + gas: new BigNumber(gas).multipliedBy(messageLength).toFixed(0), }; +} + +export function generateSendTxData(senderAddress, toAddress, amount) { + const fee = calculateTxGasFee(); const messages = [{ typeUrl: '/cosmos.bank.v1beta1.MsgSend', value: { diff --git a/src/util/firebase.js b/src/util/firebase.js index a741c4702..41cbcf1ca 100644 --- a/src/util/firebase.js +++ b/src/util/firebase.js @@ -11,6 +11,8 @@ import { FIRESTORE_COUPON_ROOT, FIRESTORE_CONFIG_ROOT, FIRESTORE_OAUTH_CLIENT_ROOT, + FIRESTORE_LIKER_NFT_ROOT, + FIRESTORE_ISCN_INFO_ROOT, } from '../../config/config'; import serviceAccount from '../../config/serviceAccountKey.json'; @@ -37,6 +39,9 @@ export const payoutCollection = getCollectionIfDefined(FIRESTORE_PAYOUT_ROOT); export const couponCollection = getCollectionIfDefined(FIRESTORE_COUPON_ROOT); export const configCollection = getCollectionIfDefined(FIRESTORE_CONFIG_ROOT); export const oAuthClientCollection = getCollectionIfDefined(FIRESTORE_OAUTH_CLIENT_ROOT); +export const likeNFTCollection = getCollectionIfDefined(FIRESTORE_LIKER_NFT_ROOT); +export const iscnInfoCollection = getCollectionIfDefined(FIRESTORE_ISCN_INFO_ROOT); + export const bucket = FIREBASE_STORAGE_BUCKET ? admin.storage().bucket() : null; export { admin }; diff --git a/test/api/iscn.test.js b/test/api/iscn.test.js index 8ca54509f..58d499871 100644 --- a/test/api/iscn.test.js +++ b/test/api/iscn.test.js @@ -49,7 +49,7 @@ test('estimation: new', async (t) => { }) .catch(err => err.response); t.is(res.status, 200); - t.is(res.data.LIKE, 0.17132514); + t.is(res.data.LIKE, 0.01231472); }); test('estimation: upload', async (t) => { @@ -98,5 +98,5 @@ test('estimation: upload', async (t) => { }) .catch(err => err.response); t.is(res.status, 200); - t.is(res.data.LIKE, 3.17212514); + t.is(res.data.LIKE, 3.01311472); }); diff --git a/test/api/likernft-history.test.js b/test/api/likernft-history.test.js new file mode 100644 index 000000000..6f2e04a4f --- /dev/null +++ b/test/api/likernft-history.test.js @@ -0,0 +1,19 @@ +import test from 'ava'; +import axiosist from './axiosist'; + +const ISCN_ID = 'iscn://likecoin-chain/jDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU/1'; +const CLASS_ID = 'likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa'; + +test('likernft: query history via iscn id', async (t) => { + const res = await axiosist.get(`/api/likernft/history?iscn_id=${ISCN_ID}`) + .catch(err => err.response); + t.is(res.status, 200); + t.is(res.data.list[0].txHash, '5D5FA1727B20D84675FB6F98240712034E1ABDD04B400F9609093F092E2DAAF9'); +}); + +test('likernft: query history via class id', async (t) => { + const res = await axiosist.get(`/api/likernft/history?class_id=${CLASS_ID}`) + .catch(err => err.response); + t.is(res.status, 200); + t.is(res.data.list[0].txHash, '5D5FA1727B20D84675FB6F98240712034E1ABDD04B400F9609093F092E2DAAF9'); +}); diff --git a/test/api/likernft-mint.test.js b/test/api/likernft-mint.test.js new file mode 100644 index 000000000..096b68e73 --- /dev/null +++ b/test/api/likernft-mint.test.js @@ -0,0 +1,31 @@ +import test from 'ava'; +import axiosist from './axiosist'; + +const ISCN_ID = 'iscn://likecoin-chain/jDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU/1'; +const ISCN_ID_PREFIX = 'iscn://likecoin-chain/jDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU'; +const CLASS_ID = 'likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa'; + +test('likernft: get mint info via iscn id', async (t) => { + const res = await axiosist.get(`/api/likernft/mint?iscn_id=${ISCN_ID}`) + .catch(err => err.response); + + t.is(res.status, 200); + t.is(res.data.iscnId, ISCN_ID_PREFIX); + t.is(res.data.classId, CLASS_ID); +}); + +test('likernft: get mint info via class id', async (t) => { + const res = await axiosist.get(`/api/likernft/mint?class_id=${CLASS_ID}`) + .catch(err => err.response); + + t.is(res.status, 200); + t.is(res.data.iscnId, ISCN_ID_PREFIX); + t.is(res.data.classId, CLASS_ID); +}); + +test('likernft: post mint fail due to exist', async (t) => { + const res = await axiosist.post(`/api/likernft/mint?iscn_id=${ISCN_ID}&class_id=${CLASS_ID}`) + .catch(err => err.response); + + t.is(res.status, 409); +}); diff --git a/test/api/likernft-purchase.test.js b/test/api/likernft-purchase.test.js new file mode 100644 index 000000000..364aed1f3 --- /dev/null +++ b/test/api/likernft-purchase.test.js @@ -0,0 +1,40 @@ +import test from 'ava'; +import axiosist from './axiosist'; + +const ISCN_ID = 'iscn://likecoin-chain/jDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU/1'; +const ISCN_ID_PREFIX = 'iscn://likecoin-chain/jDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU'; +const CLASS_ID = 'likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa'; + +test('likernft: get purchase info via iscn id', async (t) => { + const res = await axiosist.get(`/api/likernft/purchase?iscn_id=${ISCN_ID}`) + .catch(err => err.response); + + t.is(res.status, 200); + t.is(res.data.metadata.iscnId, ISCN_ID_PREFIX); + t.is(res.data.metadata.classId, CLASS_ID); +}); + +test('likernft: get purchase info via class id', async (t) => { + const res = await axiosist.get(`/api/likernft/purchase?class_id=${CLASS_ID}`) + .catch(err => err.response); + + t.is(res.status, 200); + t.is(res.data.metadata.iscnId, ISCN_ID_PREFIX); + t.is(res.data.metadata.classId, CLASS_ID); +}); + +test('likernft: get purchase info of sold out nft', async (t) => { + const res = await axiosist.get(`/api/likernft/purchase?iscn_id=${ISCN_ID}`) + .catch(err => err.response); + + t.is(res.status, 200); + t.is(res.data.metadata.iscnId, ISCN_ID_PREFIX); + t.is(res.data.metadata.classId, CLASS_ID); +}); + +test('likernft: post purchase fail due to exist', async (t) => { + const res = await axiosist.post(`/api/likernft/purchase?iscn_id=${ISCN_ID}&class_id=${CLASS_ID}`) + .catch(err => err.response); + + t.is(res.status, 400); +}); diff --git a/test/api/likernft-user.test.js b/test/api/likernft-user.test.js new file mode 100644 index 000000000..9e627d56f --- /dev/null +++ b/test/api/likernft-user.test.js @@ -0,0 +1,19 @@ +import test from 'ava'; +import axiosist from './axiosist'; + +const CLASS_ID = 'likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa'; +const WALLET = 'like1jnns8ttx8nhxleatsgwnrcandgw7a8sx24nc78'; + +test('likernft: get user owned nft', async (t) => { + const res = await axiosist.get(`/api/likernft/user/${WALLET}/own`) + .catch(err => err.response); + t.is(res.status, 200); + t.is(res.data.list[0], CLASS_ID); +}); + +test('likernft: get user selling nft', async (t) => { + const res = await axiosist.get(`/api/likernft/user/${WALLET}/sell`) + .catch(err => err.response); + t.is(res.status, 200); + t.is(res.data.list[0], CLASS_ID); +}); diff --git a/test/data/likernft.json b/test/data/likernft.json new file mode 100644 index 000000000..77be64656 --- /dev/null +++ b/test/data/likernft.json @@ -0,0 +1,76 @@ +{ + "likernft": [ + { + "id": "iscn%3A%2F%2Flikecoin-chain%2FjDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU", + "basePrice": 1, + "classId": "likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa", + "classUri": "https://api.rinkeby.like.co/likernft/metadata?class_id=likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa&nft_id=liker-00027b31-b5a7-429b-84c8-b25a2e45c173", + "classes": ["likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa"], + "creatorWallet": "like1lsagfzrm4gz28he4wunt63sts5xzmczw5a2m42", + "currentPrice": 2, + "isProcessing": false, + "lastSoldTimestamp": 1655442807980, + "soldCount": 1, + "totalCount": 1000, + "collection": { + "class": [ + { + "id": "likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa", + "collection": { + "nft": [ + { + "id": "liker-00027b31-b5a7-429b-84c8-b25a2e45c173", + "classId": "likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa", + "isSold": true, + "isProcessing": false, + "lastSoldTimestamp": 1655442807980, + "ownerWallet": "like1jnns8ttx8nhxleatsgwnrcandgw7a8sx24nc78", + "price": 1, + "sellerWallet": "like1lsagfzrm4gz28he4wunt63sts5xzmczw5a2m42", + "uri": "https://api.rinkeby.like.co/likernft/metadata?class_id=likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa&nft_id=liker-00027b31-b5a7-429b-84c8-b25a2e45c173" + }, { + "id": "liker-0030e3e2-f5f9-40c7-8649-833e61a9bc35", + "classId": "likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa", + "isSold": false, + "isProcessing": false, + "price": 0, + "sellerWallet": "like1jnns8ttx8nhxleatsgwnrcandgw7a8sx24nc78", + "soldCount": 1, + "uri": "https://api.rinkeby.like.co/likernft/metadata?class_id=likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa&nft_id=liker-0030e3e2-f5f9-40c7-8649-833e61a9bc35" + } + ] + }, + "creatorWallet": "like1lsagfzrm4gz28he4wunt63sts5xzmczw5a2m42", + "lastSoldNftId": "liker-00027b31-b5a7-429b-84c8-b25a2e45c173", + "lastSoldPrice": 1, + "lastSoldTimestamp": 1655442807980, + "metadata": { + "backgroundColor": "#28646E", + "description": "", + "externalUrl": "https://app.rinkeby.like.co/view/iscn%3A%2F%2Flikecoin-chain%2FjDIU6eXjSttrEUvIPfvZZaMeGB6ckGOGX0EL4UYGraU%2F1", + "image": "https://static.like.co/likecoin_de-portrait.jpg", + "name": "" + }, + "soldCount": 1, + "uri": "https://api.rinkeby.like.co/likernft/metadata?class_id=likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa&nft_id=liker-00027b31-b5a7-429b-84c8-b25a2e45c173" + } + ], + "transaction": [ + { + "id": "5D5FA1727B20D84675FB6F98240712034E1ABDD04B400F9609093F092E2DAAF9", + "classId": "likenft1swtgvmt2w5atqqrelga3p8vgg67dkrwrgr75hfgpyzh5umlnqtgszvqufa", + "fromWallet": "like1yney2cqn5qdrlc50yr5l53898ufdhxafqz9gxp", + "nftId": "liker-00027b31-b5a7-429b-84c8-b25a2e45c173", + "price": 1, + "sellerLIKE": "0.8", + "sellerWallet": "like1lsagfzrm4gz28he4wunt63sts5xzmczw5a2m42", + "stakeholderLIKEs": ["0.2"], + "stakeholderWallets": ["like1lsagfzrm4gz28he4wunt63sts5xzmczw5a2m42"], + "timestamp": 1655442807980, + "toWallet": "like1jnns8ttx8nhxleatsgwnrcandgw7a8sx24nc78" + } + ] + } + } + ] +} diff --git a/test/stub/util/firebase.js b/test/stub/util/firebase.js index e4f1274b4..b937e04c4 100644 --- a/test/stub/util/firebase.js +++ b/test/stub/util/firebase.js @@ -16,6 +16,7 @@ const userData = require('../../test/data/user.json').users; const subscriptionData = require('../../test/data/subscription.json').subscriptions; const txData = require('../../test/data/tx.json').tx; const missionData = require('../../test/data/mission.json').missions; +const likerNftData = require('../../test/data/likernft.json').likernft; const web3 = new Web3(new Web3.providers.HttpProvider(INFURA_HOST)); @@ -69,6 +70,7 @@ function querySnapshotDocs(data, originalData) { create: (setData, config) => docSet(database, d.id, setData, config), update: updateData => docUpdate(database, d.id, d, updateData), delete: () => docDelete(database, { id: d.id }), + collection: id => createCollection(d.collection[id]), }, data: () => docData(d), exists: true, @@ -91,12 +93,20 @@ function collectionWhere(data, field, op, value) { } } else if (op === 'array-contains') { whereData = data.filter(d => Array.isArray(d[field]) && d[field].includes(value)); + } else if (op === '>=') { + whereData = data.filter(d => d[field] >= value); + } else if (op === '<=') { + whereData = data.filter(d => d[field] <= value); + } else if (op === '!=') { + whereData = data.filter(d => d[field] !== value); + } else if (op) { + console.error(`operator ${op} is not supported`); } const docs = querySnapshotDocs(whereData, data); const queryObj = { where: (sField, sOp, sValue) => collectionWhere(whereData, sField, sOp, sValue), orderBy: (sField, order = 'asc') => { - if (sField in data[0] && (order === 'asc' || order === 'desc')) { + if (!data[0] || (sField in data[0] && (order === 'asc' || order === 'desc'))) { return queryObj; } throw new Error('orderBy is incorrect.'); @@ -182,6 +192,13 @@ function createCollection(data) { }; } +const dbData = [ + userData, + subscriptionData, + txData, + missionData, + likerNftData, +]; export const userCollection = createCollection(userData); export const userAuthCollection = createCollection([]); export const subscriptionUserCollection = createCollection(subscriptionData); @@ -191,6 +208,7 @@ export const missionCollection = createCollection(missionData); export const couponCollection = createCollection([]); export const configCollection = createCollection([]); export const oAuthClientCollection = createCollection([]); +export const likeNFTCollection = createCollection(likerNftData); function runTransaction(updateFunc) { return updateFunc({ @@ -218,6 +236,22 @@ function createDb() { update: (ref, data) => ref.update(data), commit: () => {}, }), + collectionGroup: (group) => { + let data = []; + dbData.forEach((root) => { + root.forEach((d) => { + if (d.collection) { + if (d.collection[group]) data = data.concat(d.collection[group]); + Object.values(d.collection).forEach((c) => { + c.forEach((cd) => { + if (cd.collection && cd.collection[group]) data = data.concat(cd.collection[group]); + }); + }); + } + }); + }); + return collectionWhere(data); + }, }; }