From af7dd96a876529f427fb21e07cc49c4ce87c4d11 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Mon, 25 Sep 2023 19:28:45 +0500 Subject: [PATCH 01/41] draft --- ride/grid-trading/account.ride | 61 ++++++++++++++++++++++++++++++++++ ride/grid-trading/factory.ride | 6 ++++ ride/grid-trading/info.md | 13 ++++++++ ride/grid-trading/service.ride | 28 ++++++++++++++++ 4 files changed, 108 insertions(+) create mode 100644 ride/grid-trading/account.ride create mode 100644 ride/grid-trading/factory.ride create mode 100644 ride/grid-trading/info.md create mode 100644 ride/grid-trading/service.ride diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride new file mode 100644 index 00000000..e31b4c88 --- /dev/null +++ b/ride/grid-trading/account.ride @@ -0,0 +1,61 @@ +{-# STDLIB_VERSION 7 #-} +{-# CONTENT_TYPE DAPP #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +let factoryAddress = Address(this.getBinaryValue("factoryAddress")) +let serviceAddress = Address(factoryAddress.getBinaryValue("serviceAddress")) +let ownerAddress = Address(this.getBinaryValue("ownerAddress")) + +func onlyAddress(i: Invocation, address: Address) = { + i.caller == address || throw() +} + +func onlyThis(i: Invocation) = { + onlyAddress(i, this) +} + +func onlyService(i: Invocation) = { + onlyAddress(i, serviceAddress) +} + +func onlyOwner(i: Invocation) = { + onlyAddress(i, ownerAddress) +} + +@Callable(i) +func stringEntry(key: String, val: String) = + if (i.onlyService()) then ([StringEntry(key, val)], key) else ([], unit) + +@Callable(i) +func integerEntry(key: String, val: Int) = + if (i.onlyService()) then ([IntegerEntry(key, val)], key) else ([], unit) + +@Callable(i) +func transferAsset(recipientBytes: ByteVector, amount: Int, assetId: ByteVector) = + if (i.onlyService()) then ([ScriptTransfer(Address(recipientBytes), amount, assetId)], amount) else ([], unit) + +@Callable(i) +func transferWaves(recipientBytes: ByteVector, amount: Int) = + if (i.onlyService()) then ([ScriptTransfer(Address(recipientBytes), amount, unit)], amount) else ([], unit) + +# owner can call only this function +# service address should be replaced to change logic +@Callable(i) +func call(function: String, args: List[String]) = { + if (i.onlyOwner()) then { + let result = serviceAddress.reentrantInvoke(function, args, i.payments) + (nil, result) + } else { + ([], unit) + } +} + +# bot can trade +@Verifier(tx) +func verify() = { + let botPublicKey = this.getBinaryValue("botPublicKey") + match tx { + case _: Order => sigVerify(tx.bodyBytes, tx.proofs[0], botPublicKey) + case _ => throw() + } +} diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride new file mode 100644 index 00000000..8a0bf974 --- /dev/null +++ b/ride/grid-trading/factory.ride @@ -0,0 +1,6 @@ +{-# STDLIB_VERSION 7 #-} +{-# CONTENT_TYPE DAPP #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +# can be updated by voting +let serviceAddress = Address(this.getBinaryValue("serviceAddress")) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md new file mode 100644 index 00000000..68bd20a9 --- /dev/null +++ b/ride/grid-trading/info.md @@ -0,0 +1,13 @@ +* factory + * service address in storage can be changed by the voting +* owner + * can call the account callable functions +* account + * allow orders signed by bot + * pass functions to service + * script can't be updated +* bot + * can use account for trading +* service + * script can't be updated + * functions for account diff --git a/ride/grid-trading/service.ride b/ride/grid-trading/service.ride new file mode 100644 index 00000000..1ff8ea57 --- /dev/null +++ b/ride/grid-trading/service.ride @@ -0,0 +1,28 @@ +{-# STDLIB_VERSION 7 #-} +{-# CONTENT_TYPE DAPP #-} +{-# SCRIPT_TYPE ACCOUNT #-} + +# withdraw from investment account to specified address +@Callable(i) +func withdraw(args: List[String]) = { + let recipient = addressFromStringValue(args[0]) + let amount = parseIntValue(args[1]) + let result = i.caller.invoke("transferWaves", [recipient.bytes, amount], []) + + (nil, result) +} + +# set param example +@Callable(i) +func setIntParam(args: List[String]) = { + let key = args[0] + let val = parseIntValue(args[1]) + let result = i.caller.invoke("integerEntry", [key, val], []) + + (nil, result) +} + +@Verifier(tx) +func verify() = { + false +} \ No newline at end of file From 6cb5b7ec80e1d036dcbec65c646f8120eb1f7e64 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 26 Sep 2023 12:15:30 +0500 Subject: [PATCH 02/41] bot public key on factory --- ride/grid-trading/account.ride | 2 +- ride/grid-trading/factory.ride | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride index e31b4c88..bcf3972f 100644 --- a/ride/grid-trading/account.ride +++ b/ride/grid-trading/account.ride @@ -53,7 +53,7 @@ func call(function: String, args: List[String]) = { # bot can trade @Verifier(tx) func verify() = { - let botPublicKey = this.getBinaryValue("botPublicKey") + let botPublicKey = factoryAddress.getBinaryValue("botPublicKey") match tx { case _: Order => sigVerify(tx.bodyBytes, tx.proofs[0], botPublicKey) case _ => throw() diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index 8a0bf974..a085b6d0 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -4,3 +4,4 @@ # can be updated by voting let serviceAddress = Address(this.getBinaryValue("serviceAddress")) +let botPublicKey = this.getBinaryValue("botPublicKey") From 37d672705f4d09f86fde819869ee971bca74fa94 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:50:49 +0500 Subject: [PATCH 03/41] fixes --- ride/grid-trading/account.ride | 8 ++++---- ride/grid-trading/factory.ride | 2 +- ride/grid-trading/service.ride | 9 +++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride index bcf3972f..0a167145 100644 --- a/ride/grid-trading/account.ride +++ b/ride/grid-trading/account.ride @@ -2,9 +2,9 @@ {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} -let factoryAddress = Address(this.getBinaryValue("factoryAddress")) -let serviceAddress = Address(factoryAddress.getBinaryValue("serviceAddress")) -let ownerAddress = Address(this.getBinaryValue("ownerAddress")) +let factoryAddress = addressFromPublicKey(this.getBinaryValue("factoryPublicKey")) +let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue("servicePublicKey")) +let ownerAddress = addressFromPublicKey(this.getBinaryValue("ownerPublicKey")) func onlyAddress(i: Invocation, address: Address) = { i.caller == address || throw() @@ -43,7 +43,7 @@ func transferWaves(recipientBytes: ByteVector, amount: Int) = @Callable(i) func call(function: String, args: List[String]) = { if (i.onlyOwner()) then { - let result = serviceAddress.reentrantInvoke(function, args, i.payments) + let result = serviceAddress.reentrantInvoke(function, [args], i.payments) (nil, result) } else { ([], unit) diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index a085b6d0..e94ef8f7 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -3,5 +3,5 @@ {-# SCRIPT_TYPE ACCOUNT #-} # can be updated by voting -let serviceAddress = Address(this.getBinaryValue("serviceAddress")) +let serviceAddress = addressFromPublicKey(this.getBinaryValue("servicePublicKey")) let botPublicKey = this.getBinaryValue("botPublicKey") diff --git a/ride/grid-trading/service.ride b/ride/grid-trading/service.ride index 1ff8ea57..96976844 100644 --- a/ride/grid-trading/service.ride +++ b/ride/grid-trading/service.ride @@ -22,6 +22,15 @@ func setIntParam(args: List[String]) = { (nil, result) } +@Callable(i) +func setStrParam(args: List[String]) = { + let key = args[0] + let val = args[1] + let result = i.caller.invoke("stringEntry", [key, val], []) + + (nil, result) +} + @Verifier(tx) func verify() = { false From c3b6ea071b756c514db96acfcde2e452b9a82a67 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:21:47 +0500 Subject: [PATCH 04/41] init functions --- ride/grid-trading/account.ride | 52 +++++++++++++++++++++++----------- ride/grid-trading/factory.ride | 25 ++++++++++++++-- 2 files changed, 59 insertions(+), 18 deletions(-) diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride index 0a167145..1beaca70 100644 --- a/ride/grid-trading/account.ride +++ b/ride/grid-trading/account.ride @@ -2,47 +2,64 @@ {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} -let factoryAddress = addressFromPublicKey(this.getBinaryValue("factoryPublicKey")) -let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue("servicePublicKey")) -let ownerAddress = addressFromPublicKey(this.getBinaryValue("ownerPublicKey")) +let kFactoryPublicKey = "%s__factoryPublicKey" +let kServicePublicKey = "%s__servicePublicKey" +let kOwnerPublicKey = "%s__ownerPublicKey" +let kBotPublicKey = "%s__botPublicKey" -func onlyAddress(i: Invocation, address: Address) = { +let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) +let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue(kServicePublicKey)) +let ownerAddress = addressFromPublicKey(this.getBinaryValue(kOwnerPublicKey)) + +let isReady = this.getBinary(kFactoryPublicKey).isDefined() && this.getBinary(kOwnerPublicKey).isDefined() + +func mustAddress(i: Invocation, address: Address) = { i.caller == address || throw() } -func onlyThis(i: Invocation) = { - onlyAddress(i, this) +func mustThis(i: Invocation) = { + mustAddress(i, this) } -func onlyService(i: Invocation) = { - onlyAddress(i, serviceAddress) +func mustService(i: Invocation) = { + mustAddress(i, serviceAddress) } -func onlyOwner(i: Invocation) = { - onlyAddress(i, ownerAddress) +func mustOwner(i: Invocation) = { + mustAddress(i, ownerAddress) } @Callable(i) func stringEntry(key: String, val: String) = - if (i.onlyService()) then ([StringEntry(key, val)], key) else ([], unit) + if (i.mustService()) then ([StringEntry(key, val)], key) else ([], unit) @Callable(i) func integerEntry(key: String, val: Int) = - if (i.onlyService()) then ([IntegerEntry(key, val)], key) else ([], unit) + if (i.mustService()) then ([IntegerEntry(key, val)], key) else ([], unit) @Callable(i) func transferAsset(recipientBytes: ByteVector, amount: Int, assetId: ByteVector) = - if (i.onlyService()) then ([ScriptTransfer(Address(recipientBytes), amount, assetId)], amount) else ([], unit) + if (i.mustService()) then ([ScriptTransfer(Address(recipientBytes), amount, assetId)], amount) else ([], unit) @Callable(i) func transferWaves(recipientBytes: ByteVector, amount: Int) = - if (i.onlyService()) then ([ScriptTransfer(Address(recipientBytes), amount, unit)], amount) else ([], unit) + if (i.mustService()) then ([ScriptTransfer(Address(recipientBytes), amount, unit)], amount) else ([], unit) + +@Callable(i) +func init(factoryPublicKey: ByteVector, ownerPublicKey: ByteVector) = { + strict checkCaller = i.mustThis() + + ([ + BinaryEntry(kFactoryPublicKey, factoryPublicKey), + BinaryEntry(kOwnerPublicKey, ownerPublicKey) + ], unit) +} # owner can call only this function # service address should be replaced to change logic @Callable(i) func call(function: String, args: List[String]) = { - if (i.onlyOwner()) then { + if (i.mustOwner()) then { let result = serviceAddress.reentrantInvoke(function, [args], i.payments) (nil, result) } else { @@ -53,9 +70,12 @@ func call(function: String, args: List[String]) = { # bot can trade @Verifier(tx) func verify() = { - let botPublicKey = factoryAddress.getBinaryValue("botPublicKey") + let botPublicKey = factoryAddress.getBinaryValue(kBotPublicKey) match tx { case _: Order => sigVerify(tx.bodyBytes, tx.proofs[0], botPublicKey) + case _: InvokeScriptTransaction => if (isReady) then throw() else { + sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) + } case _ => throw() } } diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index e94ef8f7..68eb2968 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -2,6 +2,27 @@ {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} +func mustAddress(i: Invocation, address: Address) = { + i.caller == address || throw() +} + +func mustThis(i: Invocation) = { + mustAddress(i, this) +} + +let kServicePublicKey = "%s__servicePublicKey" +let kBotPublicKey = "%s__botPublicKey" + # can be updated by voting -let serviceAddress = addressFromPublicKey(this.getBinaryValue("servicePublicKey")) -let botPublicKey = this.getBinaryValue("botPublicKey") +let serviceAddress = addressFromPublicKey(this.getBinaryValue(kServicePublicKey)) +let botPublicKey = this.getBinaryValue(kBotPublicKey) + +@Callable(i) +func init(servicePublicKey: ByteVector, botPublicKey: ByteVector) = { + strict checkCaller = i.mustThis() + + ([ + BinaryEntry(kServicePublicKey, servicePublicKey), + BinaryEntry(kBotPublicKey, botPublicKey) + ], unit) +} From b721ba3e6da037d74b98ec079d56242aff8106fc Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 13:25:19 +0500 Subject: [PATCH 05/41] requests draft --- ride/grid-trading/account.ride | 37 +++++++++++++--- ride/grid-trading/factory.ride | 79 ++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 7 deletions(-) diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride index 1beaca70..2a7b282a 100644 --- a/ride/grid-trading/account.ride +++ b/ride/grid-trading/account.ride @@ -6,12 +6,15 @@ let kFactoryPublicKey = "%s__factoryPublicKey" let kServicePublicKey = "%s__servicePublicKey" let kOwnerPublicKey = "%s__ownerPublicKey" let kBotPublicKey = "%s__botPublicKey" +let kVerified = "%s__verified" let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue(kServicePublicKey)) let ownerAddress = addressFromPublicKey(this.getBinaryValue(kOwnerPublicKey)) -let isReady = this.getBinary(kFactoryPublicKey).isDefined() && this.getBinary(kOwnerPublicKey).isDefined() +let isReady = this.getBinary(kFactoryPublicKey).isDefined() + && this.getBinary(kOwnerPublicKey).isDefined() + && this.getBoolean(kVerified).valueOrElse(false) func mustAddress(i: Invocation, address: Address) = { i.caller == address || throw() @@ -29,6 +32,10 @@ func mustOwner(i: Invocation) = { mustAddress(i, ownerAddress) } +func mustFactory(i: Invocation) = { + mustAddress(i, factoryAddress) +} + @Callable(i) func stringEntry(key: String, val: String) = if (i.mustService()) then ([StringEntry(key, val)], key) else ([], unit) @@ -55,16 +62,32 @@ func init(factoryPublicKey: ByteVector, ownerPublicKey: ByteVector) = { ], unit) } +@Callable(i) +func complete(requestId: String, recipientPublicKey: ByteVector) = { + strict checkCaller = i.mustThis() + let result = factoryAddress.reentrantInvoke("complete", [requestId, recipientPublicKey], []) + + (nil, result) +} + +# called by factory to close the contract +@Callable(i) +func approve() = { + strict checkCaller = i.mustFactory() + + ([ + BooleanEntry(kVerified, true) + ], unit) +} + # owner can call only this function # service address should be replaced to change logic @Callable(i) func call(function: String, args: List[String]) = { - if (i.mustOwner()) then { - let result = serviceAddress.reentrantInvoke(function, [args], i.payments) - (nil, result) - } else { - ([], unit) - } + strict checkCaller = i.mustOwner() + let result = serviceAddress.reentrantInvoke(function, [args], i.payments) + + (nil, result) } # bot can trade diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index 68eb2968..f6f5ca50 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -2,6 +2,8 @@ {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} +let separator = "__" + func mustAddress(i: Invocation, address: Address) = { i.caller == address || throw() } @@ -13,6 +15,41 @@ func mustThis(i: Invocation) = { let kServicePublicKey = "%s__servicePublicKey" let kBotPublicKey = "%s__botPublicKey" +# account keys +let kFactoryPublicKey = "%s__factoryPublicKey" +let kOwnerPublicKey = "%s__ownerPublicKey" + +let kAccountScriptHash = "%s__accountScriptHash" +let accountScriptHash = this.getBinary( + kAccountScriptHash +).valueOrErrorMessage("account script hash is not set") + +let kCounter = "%s__counter" +let counter = this.getInteger(kCounter).valueOrElse(0) + +let kRewardAmount = "%s__rewardAmount" +let rewardAmount = this.getInteger( + kRewardAmount +).valueOrErrorMessage("reward amount is not set") + +func kRequestCompleted(requestId: String) = { + ["%s%s", requestId, "completed"].makeString(separator) +} +func requestCompleted(requestId: String) = { + this.getBoolean( + kRequestCompleted(requestId) + ).valueOrErrorMessage("request is not found") +} + +func kRequestOwner(requestId: String) = { + ["%s%s", requestId, "owner"].makeString(separator) +} +func requestOwner(requestId: String) = { + this.getBinary( + kRequestCompleted(requestId) + ).valueOrErrorMessage("request is not found") +} + # can be updated by voting let serviceAddress = addressFromPublicKey(this.getBinaryValue(kServicePublicKey)) let botPublicKey = this.getBinaryValue(kBotPublicKey) @@ -26,3 +63,45 @@ func init(servicePublicKey: ByteVector, botPublicKey: ByteVector) = { BinaryEntry(kBotPublicKey, botPublicKey) ], unit) } + +# called by user +# additional fee in payment +@Callable(i) +func request() = { + strict checks = [ + i.payments.size() == 1 || throw("1 payment is required"), + i.payments[0].assetId == unit || throw("invalid asset"), + i.payments[0].amount == rewardAmount || throw("invalid amount") + ] + + let requestId = sha256(i.caller.bytes + counter.toBytes()).toBase58String() + + ([ + BooleanEntry(kRequestCompleted(requestId), false), + BinaryEntry(kRequestOwner(requestId), i.callerPublicKey) + ], unit) +} + +# called by account script +# additional fee is sent to recipient +@Callable(i) +func complete(requestId: String, recipientPublicKey: ByteVector) = { + strict checks = [ + !requestCompleted(requestId) || throw("request is already completed"), + scriptHash(i.caller) == accountScriptHash || throw("invalid script"), + match i.caller.getBinary(kFactoryPublicKey) { + case b: ByteVector => addressFromPublicKey(b) == this + case _ => false + } || throw("invalid factory public key"), + match i.caller.getBinary(kOwnerPublicKey) { + case b: ByteVector => b == requestOwner(requestId) + case _ => false + } || throw("invalid owner public key") + ] + + let result = i.caller.invoke("approve", [], []) + + ([ + BooleanEntry(kRequestCompleted(requestId), true) + ], result) +} \ No newline at end of file From 0b0701f2ea0a962b553413a9dc060806fb050df1 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:51:19 +0500 Subject: [PATCH 06/41] fixes --- ride/grid-trading/account.ride | 27 ++++++++------------ ride/grid-trading/factory.ride | 46 +++++++++++++++++++++++----------- ride/grid-trading/service.ride | 4 ++- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride index 2a7b282a..b2576f69 100644 --- a/ride/grid-trading/account.ride +++ b/ride/grid-trading/account.ride @@ -5,17 +5,16 @@ let kFactoryPublicKey = "%s__factoryPublicKey" let kServicePublicKey = "%s__servicePublicKey" let kOwnerPublicKey = "%s__ownerPublicKey" +let kCreatorPublicKey = "%s__creatorPublicKey" let kBotPublicKey = "%s__botPublicKey" + let kVerified = "%s__verified" +func verified() = this.getBoolean(kVerified).valueOrElse(false) let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue(kServicePublicKey)) let ownerAddress = addressFromPublicKey(this.getBinaryValue(kOwnerPublicKey)) -let isReady = this.getBinary(kFactoryPublicKey).isDefined() - && this.getBinary(kOwnerPublicKey).isDefined() - && this.getBoolean(kVerified).valueOrElse(false) - func mustAddress(i: Invocation, address: Address) = { i.caller == address || throw() } @@ -53,23 +52,16 @@ func transferWaves(recipientBytes: ByteVector, amount: Int) = if (i.mustService()) then ([ScriptTransfer(Address(recipientBytes), amount, unit)], amount) else ([], unit) @Callable(i) -func init(factoryPublicKey: ByteVector, ownerPublicKey: ByteVector) = { +func init(factoryPublicKey: ByteVector, ownerPublicKey: ByteVector, creatorPublicKey: ByteVector) = { strict checkCaller = i.mustThis() ([ BinaryEntry(kFactoryPublicKey, factoryPublicKey), - BinaryEntry(kOwnerPublicKey, ownerPublicKey) + BinaryEntry(kOwnerPublicKey, ownerPublicKey), + BinaryEntry(kCreatorPublicKey, creatorPublicKey) ], unit) } -@Callable(i) -func complete(requestId: String, recipientPublicKey: ByteVector) = { - strict checkCaller = i.mustThis() - let result = factoryAddress.reentrantInvoke("complete", [requestId, recipientPublicKey], []) - - (nil, result) -} - # called by factory to close the contract @Callable(i) func approve() = { @@ -93,12 +85,15 @@ func call(function: String, args: List[String]) = { # bot can trade @Verifier(tx) func verify() = { + let testnet = this.bytes.drop(1).take(1) == base16'54' let botPublicKey = factoryAddress.getBinaryValue(kBotPublicKey) match tx { case _: Order => sigVerify(tx.bodyBytes, tx.proofs[0], botPublicKey) - case _: InvokeScriptTransaction => if (isReady) then throw() else { + case _: InvokeScriptTransaction => if (verified()) then false else { + sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) + } + case _ => if (!testnet) then false else { sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) } - case _ => throw() } } diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index f6f5ca50..8d2bcd36 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -18,17 +18,18 @@ let kBotPublicKey = "%s__botPublicKey" # account keys let kFactoryPublicKey = "%s__factoryPublicKey" let kOwnerPublicKey = "%s__ownerPublicKey" +let kCreatorPublicKey = "%s__creatorPublicKey" let kAccountScriptHash = "%s__accountScriptHash" -let accountScriptHash = this.getBinary( +func accountScriptHash() = this.getBinary( kAccountScriptHash ).valueOrErrorMessage("account script hash is not set") let kCounter = "%s__counter" -let counter = this.getInteger(kCounter).valueOrElse(0) +func counter() = this.getInteger(kCounter).valueOrElse(0) let kRewardAmount = "%s__rewardAmount" -let rewardAmount = this.getInteger( +func rewardAmount() = this.getInteger( kRewardAmount ).valueOrErrorMessage("reward amount is not set") @@ -46,7 +47,7 @@ func kRequestOwner(requestId: String) = { } func requestOwner(requestId: String) = { this.getBinary( - kRequestCompleted(requestId) + kRequestOwner(requestId) ).valueOrErrorMessage("request is not found") } @@ -55,12 +56,19 @@ let serviceAddress = addressFromPublicKey(this.getBinaryValue(kServicePublicKey) let botPublicKey = this.getBinaryValue(kBotPublicKey) @Callable(i) -func init(servicePublicKey: ByteVector, botPublicKey: ByteVector) = { +func init( + servicePublicKey: ByteVector, + botPublicKey: ByteVector, + accountScriptHash: ByteVector, + rewardAmount: Int +) = { strict checkCaller = i.mustThis() ([ BinaryEntry(kServicePublicKey, servicePublicKey), - BinaryEntry(kBotPublicKey, botPublicKey) + BinaryEntry(kBotPublicKey, botPublicKey), + BinaryEntry(kAccountScriptHash, accountScriptHash), + IntegerEntry(kRewardAmount, rewardAmount) ], unit) } @@ -71,37 +79,45 @@ func request() = { strict checks = [ i.payments.size() == 1 || throw("1 payment is required"), i.payments[0].assetId == unit || throw("invalid asset"), - i.payments[0].amount == rewardAmount || throw("invalid amount") + i.payments[0].amount == rewardAmount() || throw("invalid amount") ] - let requestId = sha256(i.caller.bytes + counter.toBytes()).toBase58String() + let requestId = sha256(i.caller.bytes + counter().toBytes()).toBase58String() ([ BooleanEntry(kRequestCompleted(requestId), false), - BinaryEntry(kRequestOwner(requestId), i.callerPublicKey) + BinaryEntry(kRequestOwner(requestId), i.callerPublicKey), + IntegerEntry(kCounter, counter() + 1) ], unit) } # called by account script # additional fee is sent to recipient @Callable(i) -func complete(requestId: String, recipientPublicKey: ByteVector) = { +func complete(requestId: String, accountPublicKey: ByteVector) = { + let accountAddress = addressFromPublicKey(accountPublicKey) + strict checks = [ !requestCompleted(requestId) || throw("request is already completed"), - scriptHash(i.caller) == accountScriptHash || throw("invalid script"), - match i.caller.getBinary(kFactoryPublicKey) { + scriptHash(accountAddress) == accountScriptHash() || throw("invalid script"), + match accountAddress.getBinary(kFactoryPublicKey) { case b: ByteVector => addressFromPublicKey(b) == this case _ => false } || throw("invalid factory public key"), - match i.caller.getBinary(kOwnerPublicKey) { + match accountAddress.getBinary(kOwnerPublicKey) { case b: ByteVector => b == requestOwner(requestId) case _ => false } || throw("invalid owner public key") ] - let result = i.caller.invoke("approve", [], []) + let creatorPublicKey = accountAddress.getBinary( + kCreatorPublicKey + ).valueOrErrorMessage("creator public key is not set") + let creatorAddress = addressFromPublicKey(creatorPublicKey) + let result = accountAddress.invoke("approve", [], []) ([ - BooleanEntry(kRequestCompleted(requestId), true) + BooleanEntry(kRequestCompleted(requestId), true), + ScriptTransfer(creatorAddress, rewardAmount(), unit) ], result) } \ No newline at end of file diff --git a/ride/grid-trading/service.ride b/ride/grid-trading/service.ride index 96976844..3584f3ee 100644 --- a/ride/grid-trading/service.ride +++ b/ride/grid-trading/service.ride @@ -33,5 +33,7 @@ func setStrParam(args: List[String]) = { @Verifier(tx) func verify() = { - false + let testnet = this.bytes.drop(1).take(1) == base16'54' + + testnet } \ No newline at end of file From 420303aad9c1344e5605fe4a620e636db8a3fc62 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:50:52 +0500 Subject: [PATCH 07/41] info update --- ride/grid-trading/info.md | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 68bd20a9..cd4dae15 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -1,13 +1,36 @@ -* factory - * service address in storage can be changed by the voting -* owner - * can call the account callable functions -* account - * allow orders signed by bot - * pass functions to service - * script can't be updated -* bot - * can use account for trading -* service - * script can't be updated - * functions for account +### Participants: +- factory + - service address in storage can be changed by the voting +- owner + - can call the account callable functions +- account + - allow orders signed by bot + - pass functions to service + - script can't be updated +- bot + - can use account for trading +- service + - script can't be updated + - functions for account + +### Account creation: +```mermaid +sequenceDiagram + User ->> Factory: request account + Note over Factory: save owner, reward id + Creator ->> Account: set script, init + Note over Account: save creator, owner + Creator ->>+ Factory: complete request with account + Note over Factory: check account script, owner, factory + Factory ->> Account: approve + Factory ->>- Creator: transfer reward +``` + +### Withdraw: +```mermaid +sequenceDiagram + User ->> Account: call(withdraw, recipient, amount) + Account ->> Service: withdraw(recipient, amount) + Service ->> Account: transfer(recipient, amount) + Account ->> User: transfer specified amount +``` From ede6c395d11f569d14389c3f31ab9a59c3024eaf Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 17:51:39 +0500 Subject: [PATCH 08/41] info fix --- ride/grid-trading/info.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index cd4dae15..4cc09b97 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -23,7 +23,7 @@ sequenceDiagram Creator ->>+ Factory: complete request with account Note over Factory: check account script, owner, factory Factory ->> Account: approve - Factory ->>- Creator: transfer reward + Factory ->>- Creator: transfer reward to creator ``` ### Withdraw: From 2bd0efb98a8d34ea900e713958ff481ebba0e356 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:01:00 +0500 Subject: [PATCH 09/41] storage info --- ride/grid-trading/info.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 4cc09b97..e4dd29fb 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -1,4 +1,5 @@ -### Participants: +### Participants + - factory - service address in storage can be changed by the voting - owner @@ -13,7 +14,29 @@ - script can't be updated - functions for account -### Account creation: +### Storage + +#### Factory + +| key | type | description | +| ------------------------------ | ------------ | --------------------------- | +| `%s__servicePublicKey` | `ByteVector` | Service public key | +| `%s__botPublicKey` | `ByteVector` | Bot public key | +| `%s__accountScriptHash` | `ByteVector` | Allowed account script hash | +| `%s__rewardAmount` | `Int` | Reward amount | +| `%s%s____completed` | `Boolean` | Request completed | +| `%s%s____owner` | `ByteVector` | Request owner public key | + +#### Account + +| key | type | description | +| ---------------------- | ------------ | ------------------- | +| `%s__verified` | `Boolean` | Verified by factory | +| `%s__factoryPublicKey` | `ByteVector` | Factory public key | +| `%s__ownerPublicKey` | `ByteVector` | Owner public key | + +### Account creation + ```mermaid sequenceDiagram User ->> Factory: request account @@ -26,7 +49,8 @@ sequenceDiagram Factory ->>- Creator: transfer reward to creator ``` -### Withdraw: +### Withdraw + ```mermaid sequenceDiagram User ->> Account: call(withdraw, recipient, amount) From 2ce129431e1d53258e7d2f9a2ac2c9c52e282876 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:02:55 +0500 Subject: [PATCH 10/41] info fix --- ride/grid-trading/info.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index e4dd29fb..50df59c5 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -46,6 +46,7 @@ sequenceDiagram Creator ->>+ Factory: complete request with account Note over Factory: check account script, owner, factory Factory ->> Account: approve + Note over Account: lock script Factory ->>- Creator: transfer reward to creator ``` From 0f3951fd043a8ed24248914456f50b0f2c3369c8 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:09:06 +0500 Subject: [PATCH 11/41] info update --- ride/grid-trading/info.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 50df59c5..0383d83d 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -41,6 +41,7 @@ sequenceDiagram User ->> Factory: request account Note over Factory: save owner, reward id + Factory -->> Creator: new request Creator ->> Account: set script, init Note over Account: save creator, owner Creator ->>+ Factory: complete request with account From 4fd2cf8cd467c972557c56cd8b9b089a2ba031ab Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:16:45 +0500 Subject: [PATCH 12/41] info update --- ride/grid-trading/info.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 0383d83d..19c5926f 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -40,7 +40,7 @@ ```mermaid sequenceDiagram User ->> Factory: request account - Note over Factory: save owner, reward id + Note over Factory: save owner, request id, reward amount Factory -->> Creator: new request Creator ->> Account: set script, init Note over Account: save creator, owner From 1c175c3b32452c5d22af135939e1ad38bec24275 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 27 Sep 2023 18:17:09 +0500 Subject: [PATCH 13/41] update info --- ride/grid-trading/info.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 19c5926f..9f525b14 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -40,15 +40,22 @@ ```mermaid sequenceDiagram User ->> Factory: request account - Note over Factory: save owner, request id, reward amount + activate Factory + Note over User, Factory: payment = reward amount + Note over Factory: save owner, request id Factory -->> Creator: new request + deactivate Factory + activate Creator Creator ->> Account: set script, init Note over Account: save creator, owner - Creator ->>+ Factory: complete request with account + Creator ->> Factory: complete request with account + activate Factory + deactivate Creator Note over Factory: check account script, owner, factory Factory ->> Account: approve Note over Account: lock script - Factory ->>- Creator: transfer reward to creator + Factory ->> Creator: transfer reward to creator + deactivate Factory ``` ### Withdraw From a6f0e0fe545ac640c0647aa60233fe205a1733e7 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 28 Sep 2023 17:40:45 +0500 Subject: [PATCH 14/41] account script instead of hash, request id fix --- ride/grid-trading/factory.ride | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index 8d2bcd36..aad5b4d1 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -20,13 +20,10 @@ let kFactoryPublicKey = "%s__factoryPublicKey" let kOwnerPublicKey = "%s__ownerPublicKey" let kCreatorPublicKey = "%s__creatorPublicKey" -let kAccountScriptHash = "%s__accountScriptHash" -func accountScriptHash() = this.getBinary( - kAccountScriptHash -).valueOrErrorMessage("account script hash is not set") - -let kCounter = "%s__counter" -func counter() = this.getInteger(kCounter).valueOrElse(0) +let kAccountScript = "%s__accountScriptHash" +func accountScript() = this.getBinary( + kAccountScript +).valueOrErrorMessage("account script is not set") let kRewardAmount = "%s__rewardAmount" func rewardAmount() = this.getInteger( @@ -59,7 +56,7 @@ let botPublicKey = this.getBinaryValue(kBotPublicKey) func init( servicePublicKey: ByteVector, botPublicKey: ByteVector, - accountScriptHash: ByteVector, + accountScript: ByteVector, rewardAmount: Int ) = { strict checkCaller = i.mustThis() @@ -67,7 +64,7 @@ func init( ([ BinaryEntry(kServicePublicKey, servicePublicKey), BinaryEntry(kBotPublicKey, botPublicKey), - BinaryEntry(kAccountScriptHash, accountScriptHash), + BinaryEntry(kAccountScript, accountScript), IntegerEntry(kRewardAmount, rewardAmount) ], unit) } @@ -75,19 +72,19 @@ func init( # called by user # additional fee in payment @Callable(i) -func request() = { +func request(amountAssetId: ByteVector, priceAssetId: ByteVector) = { + let requestId = sha256(i.caller.bytes + amountAssetId + priceAssetId).toBase58String() + strict checks = [ i.payments.size() == 1 || throw("1 payment is required"), i.payments[0].assetId == unit || throw("invalid asset"), - i.payments[0].amount == rewardAmount() || throw("invalid amount") + i.payments[0].amount == rewardAmount() || throw("invalid amount"), + this.getBoolean(kRequestCompleted(requestId)) == unit || throw("request exists") ] - let requestId = sha256(i.caller.bytes + counter().toBytes()).toBase58String() - ([ BooleanEntry(kRequestCompleted(requestId), false), - BinaryEntry(kRequestOwner(requestId), i.callerPublicKey), - IntegerEntry(kCounter, counter() + 1) + BinaryEntry(kRequestOwner(requestId), i.callerPublicKey) ], unit) } @@ -99,7 +96,10 @@ func complete(requestId: String, accountPublicKey: ByteVector) = { strict checks = [ !requestCompleted(requestId) || throw("request is already completed"), - scriptHash(accountAddress) == accountScriptHash() || throw("invalid script"), + match scriptHash(accountAddress) { + case b: ByteVector => b == blake2b256_32Kb(accountScript()) + case _ => false + } || throw("invalid script"), match accountAddress.getBinary(kFactoryPublicKey) { case b: ByteVector => addressFromPublicKey(b) == this case _ => false From ca439a28ca9d0d9b9d8c4ae5da8d9f24c2ad94e5 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:17:41 +0500 Subject: [PATCH 15/41] refactor --- ride/grid-trading/account.ride | 41 ++++++++--------- ride/grid-trading/factory.ride | 81 +++++++++++++++++----------------- ride/grid-trading/info.md | 23 +++++----- 3 files changed, 73 insertions(+), 72 deletions(-) diff --git a/ride/grid-trading/account.ride b/ride/grid-trading/account.ride index b2576f69..afb625c3 100644 --- a/ride/grid-trading/account.ride +++ b/ride/grid-trading/account.ride @@ -2,18 +2,26 @@ {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} +let separator = "__" + let kFactoryPublicKey = "%s__factoryPublicKey" let kServicePublicKey = "%s__servicePublicKey" let kOwnerPublicKey = "%s__ownerPublicKey" -let kCreatorPublicKey = "%s__creatorPublicKey" let kBotPublicKey = "%s__botPublicKey" -let kVerified = "%s__verified" -func verified() = this.getBoolean(kVerified).valueOrElse(false) +func kAccountAddressToAccountId(accountAddress: Address) = { + ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) +} +func kAccountOwner(accountId: String) = { + ["%s%s", accountId, "owner"].makeString(separator) +} let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue(kServicePublicKey)) -let ownerAddress = addressFromPublicKey(this.getBinaryValue(kOwnerPublicKey)) + +let accountId = factoryAddress.getStringValue(kAccountAddressToAccountId(this)) +let ownerPublicKey = factoryAddress.getBinaryValue(kAccountOwner(accountId)) +let ownerAddress = addressFromPublicKey(ownerPublicKey) func mustAddress(i: Invocation, address: Address) = { i.caller == address || throw() @@ -31,10 +39,6 @@ func mustOwner(i: Invocation) = { mustAddress(i, ownerAddress) } -func mustFactory(i: Invocation) = { - mustAddress(i, factoryAddress) -} - @Callable(i) func stringEntry(key: String, val: String) = if (i.mustService()) then ([StringEntry(key, val)], key) else ([], unit) @@ -52,23 +56,16 @@ func transferWaves(recipientBytes: ByteVector, amount: Int) = if (i.mustService()) then ([ScriptTransfer(Address(recipientBytes), amount, unit)], amount) else ([], unit) @Callable(i) -func init(factoryPublicKey: ByteVector, ownerPublicKey: ByteVector, creatorPublicKey: ByteVector) = { +func init(requestId: String, factoryPublicKey: ByteVector, creatorPublicKey: ByteVector) = { strict checkCaller = i.mustThis() - ([ - BinaryEntry(kFactoryPublicKey, factoryPublicKey), - BinaryEntry(kOwnerPublicKey, ownerPublicKey), - BinaryEntry(kCreatorPublicKey, creatorPublicKey) - ], unit) -} - -# called by factory to close the contract -@Callable(i) -func approve() = { - strict checkCaller = i.mustFactory() + # throws if accounts is not ok + strict completeRequest = addressFromPublicKey( + factoryPublicKey + ).invoke("complete", [requestId, creatorPublicKey], []) ([ - BooleanEntry(kVerified, true) + BinaryEntry(kFactoryPublicKey, factoryPublicKey) ], unit) } @@ -89,7 +86,7 @@ func verify() = { let botPublicKey = factoryAddress.getBinaryValue(kBotPublicKey) match tx { case _: Order => sigVerify(tx.bodyBytes, tx.proofs[0], botPublicKey) - case _: InvokeScriptTransaction => if (verified()) then false else { + case _: InvokeScriptTransaction => if (this.getBinary(kFactoryPublicKey).isDefined()) then false else { sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) } case _ => if (!testnet) then false else { diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index aad5b4d1..a51961da 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -15,12 +15,7 @@ func mustThis(i: Invocation) = { let kServicePublicKey = "%s__servicePublicKey" let kBotPublicKey = "%s__botPublicKey" -# account keys -let kFactoryPublicKey = "%s__factoryPublicKey" -let kOwnerPublicKey = "%s__ownerPublicKey" -let kCreatorPublicKey = "%s__creatorPublicKey" - -let kAccountScript = "%s__accountScriptHash" +let kAccountScript = "%s__accountScript" func accountScript() = this.getBinary( kAccountScript ).valueOrErrorMessage("account script is not set") @@ -30,22 +25,34 @@ func rewardAmount() = this.getInteger( kRewardAmount ).valueOrErrorMessage("reward amount is not set") -func kRequestCompleted(requestId: String) = { - ["%s%s", requestId, "completed"].makeString(separator) +let ACCOUNT_STATUS_EMPTY = 0 +let ACCOUNT_STATUS_READY = 1 +func kAccountStatus(accountId: String) = { + ["%s%s", accountId, "status"].makeString(separator) } -func requestCompleted(requestId: String) = { - this.getBoolean( - kRequestCompleted(requestId) - ).valueOrErrorMessage("request is not found") +func accountStatus(accountId: String) = { + this.getInteger( + kAccountStatus(accountId) + ).valueOrErrorMessage("account is not found") } -func kRequestOwner(requestId: String) = { - ["%s%s", requestId, "owner"].makeString(separator) +func kAccountCreatorPublicKey(accountId: String) = { + ["%s%s", accountId, "creatorPublicKey"].makeString(separator) +} +func kAccountOwnerPublicKey(accountId: String) = { + ["%s%s", accountId, "ownerPublicKey"].makeString(separator) +} +func kAccountAmountAssetId(accountId: String) = { + ["%s%s", accountId, "amountAssetId"].makeString(separator) +} +func kAccountPriceAssetId(accountId: String) = { + ["%s%s", accountId, "priceAssetId"].makeString(separator) } -func requestOwner(requestId: String) = { - this.getBinary( - kRequestOwner(requestId) - ).valueOrErrorMessage("request is not found") +func kAccountIdToAccountPublicKey(accountId: String) = { + ["%s%s", accountId, "accountIdToAccountPublicKey"].makeString(separator) +} +func kAccountAddressToAccountId(accountAddress: Address) = { + ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) } # can be updated by voting @@ -73,51 +80,45 @@ func init( # additional fee in payment @Callable(i) func request(amountAssetId: ByteVector, priceAssetId: ByteVector) = { - let requestId = sha256(i.caller.bytes + amountAssetId + priceAssetId).toBase58String() + let accountId = sha256(i.caller.bytes + amountAssetId + priceAssetId).toBase58String() strict checks = [ i.payments.size() == 1 || throw("1 payment is required"), i.payments[0].assetId == unit || throw("invalid asset"), i.payments[0].amount == rewardAmount() || throw("invalid amount"), - this.getBoolean(kRequestCompleted(requestId)) == unit || throw("request exists") + this.getInteger(kAccountStatus(accountId)) == unit || throw("account already exists") ] ([ - BooleanEntry(kRequestCompleted(requestId), false), - BinaryEntry(kRequestOwner(requestId), i.callerPublicKey) + IntegerEntry(kAccountStatus(accountId), 0), + BinaryEntry(kAccountOwnerPublicKey(accountId), i.callerPublicKey), + BinaryEntry(kAccountAmountAssetId(accountId), amountAssetId), + BinaryEntry(kAccountPriceAssetId(accountId), priceAssetId) ], unit) } # called by account script # additional fee is sent to recipient @Callable(i) -func complete(requestId: String, accountPublicKey: ByteVector) = { - let accountAddress = addressFromPublicKey(accountPublicKey) +func complete(accountId: String, creatorPublicKey: ByteVector) = { + let accountPublicKey = i.callerPublicKey + let accountAddress = i.caller strict checks = [ - !requestCompleted(requestId) || throw("request is already completed"), + accountStatus(accountId) == ACCOUNT_STATUS_EMPTY || throw("account is already exists"), match scriptHash(accountAddress) { case b: ByteVector => b == blake2b256_32Kb(accountScript()) case _ => false - } || throw("invalid script"), - match accountAddress.getBinary(kFactoryPublicKey) { - case b: ByteVector => addressFromPublicKey(b) == this - case _ => false - } || throw("invalid factory public key"), - match accountAddress.getBinary(kOwnerPublicKey) { - case b: ByteVector => b == requestOwner(requestId) - case _ => false - } || throw("invalid owner public key") + } || throw("invalid script") ] - let creatorPublicKey = accountAddress.getBinary( - kCreatorPublicKey - ).valueOrErrorMessage("creator public key is not set") let creatorAddress = addressFromPublicKey(creatorPublicKey) - let result = accountAddress.invoke("approve", [], []) ([ - BooleanEntry(kRequestCompleted(requestId), true), + IntegerEntry(kAccountStatus(accountId), ACCOUNT_STATUS_READY), + BinaryEntry(kAccountCreatorPublicKey(accountId), creatorPublicKey), + BinaryEntry(kAccountIdToAccountPublicKey(accountId), accountPublicKey), + StringEntry(kAccountAddressToAccountId(accountAddress), accountId), ScriptTransfer(creatorAddress, rewardAmount(), unit) - ], result) + ], unit) } \ No newline at end of file diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 9f525b14..438517ce 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -18,22 +18,25 @@ #### Factory -| key | type | description | -| ------------------------------ | ------------ | --------------------------- | -| `%s__servicePublicKey` | `ByteVector` | Service public key | -| `%s__botPublicKey` | `ByteVector` | Bot public key | -| `%s__accountScriptHash` | `ByteVector` | Allowed account script hash | -| `%s__rewardAmount` | `Int` | Reward amount | -| `%s%s____completed` | `Boolean` | Request completed | -| `%s%s____owner` | `ByteVector` | Request owner public key | +| key | type | description | +| --------------------------------------------------- | ------------ | ------------------------------------- | +| `%s__servicePublicKey` | `ByteVector` | Service public key | +| `%s__botPublicKey` | `ByteVector` | Bot public key | +| `%s__accountScript` | `ByteVector` | Allowed account script | +| `%s__rewardAmount` | `Int` | Reward amount | +| `%s%s____status` | `Integer` | Account status (0 - empty, 1 - ready) | +| `%s%s____ownerPublicKey` | `ByteVector` | Account owner | +| `%s%s____creatorPublicKey` | `ByteVector` | Account creator | +| `%s%s____amountAssetId` | `ByteVector` | Account amount asset id | +| `%s%s____priceAssetId` | `ByteVector` | Account price asset id | +| `%s%s____accountIdToAccountPublicKey` | `ByteVector` | Account id → account public key | +| `%s%s____accountAddressToAccountId` | `String` | Account address → account id | #### Account | key | type | description | | ---------------------- | ------------ | ------------------- | -| `%s__verified` | `Boolean` | Verified by factory | | `%s__factoryPublicKey` | `ByteVector` | Factory public key | -| `%s__ownerPublicKey` | `ByteVector` | Owner public key | ### Account creation From 9ec595b3d658f1c7e53e78c7189e8914d91ac866 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 29 Sep 2023 15:17:48 +0500 Subject: [PATCH 16/41] refactor --- ride/grid-trading/info.md | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 438517ce..918a0e06 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -42,21 +42,25 @@ ```mermaid sequenceDiagram - User ->> Factory: request account + User ->> Factory: request(amount asset id, price asset id) activate Factory Note over User, Factory: payment = reward amount - Note over Factory: save owner, request id + Note over Factory: account id = sha256(owner + amount asset id + price asset id) + Note over Factory: status = 0, save owner, save assets ids Factory -->> Creator: new request deactivate Factory activate Creator - Creator ->> Account: set script, init - Note over Account: save creator, owner - Creator ->> Factory: complete request with account - activate Factory + Creator -->> Account: set script deactivate Creator - Note over Factory: check account script, owner, factory - Factory ->> Account: approve - Note over Account: lock script + Account ->> Account: init(requestId, factoryPublicKey, creatorPublicKey) + activate Account + Account ->> Factory: complete request with account + activate Factory + Note over Factory: check account script, status + Note over Factory: save creator, status = 1 + Factory -->> Account: ok + Note over Account: save factory in state thus lock script + deactivate Account Factory ->> Creator: transfer reward to creator deactivate Factory ``` From 31163b540915b67febb7578be89dc090710b9f33 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 29 Sep 2023 19:34:56 +0500 Subject: [PATCH 17/41] allowed pairs --- ride/grid-trading/factory.ride | 10 ++++++++++ ride/grid-trading/info.md | 33 +++++++++++++++++---------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/ride/grid-trading/factory.ride b/ride/grid-trading/factory.ride index a51961da..2f1057cc 100644 --- a/ride/grid-trading/factory.ride +++ b/ride/grid-trading/factory.ride @@ -55,6 +55,15 @@ func kAccountAddressToAccountId(accountAddress: Address) = { ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) } +func kPairAllowed(amountAssetId: ByteVector, priceAssetId: ByteVector) = { + ["%s%s%s", amountAssetId.toBase58String(), priceAssetId.toBase58String(), "pairAllowed"].makeString(separator) +} +func pairAllowed(amountAssetId: ByteVector, priceAssetId: ByteVector) = { + this.getBoolean( + kPairAllowed(amountAssetId, priceAssetId) + ).valueOrElse(false) +} + # can be updated by voting let serviceAddress = addressFromPublicKey(this.getBinaryValue(kServicePublicKey)) let botPublicKey = this.getBinaryValue(kBotPublicKey) @@ -86,6 +95,7 @@ func request(amountAssetId: ByteVector, priceAssetId: ByteVector) = { i.payments.size() == 1 || throw("1 payment is required"), i.payments[0].assetId == unit || throw("invalid asset"), i.payments[0].amount == rewardAmount() || throw("invalid amount"), + pairAllowed(amountAssetId, priceAssetId) || throw("pair is not allowed"), this.getInteger(kAccountStatus(accountId)) == unit || throw("account already exists") ] diff --git a/ride/grid-trading/info.md b/ride/grid-trading/info.md index 918a0e06..b2cbf376 100644 --- a/ride/grid-trading/info.md +++ b/ride/grid-trading/info.md @@ -18,25 +18,26 @@ #### Factory -| key | type | description | -| --------------------------------------------------- | ------------ | ------------------------------------- | -| `%s__servicePublicKey` | `ByteVector` | Service public key | -| `%s__botPublicKey` | `ByteVector` | Bot public key | -| `%s__accountScript` | `ByteVector` | Allowed account script | -| `%s__rewardAmount` | `Int` | Reward amount | -| `%s%s____status` | `Integer` | Account status (0 - empty, 1 - ready) | -| `%s%s____ownerPublicKey` | `ByteVector` | Account owner | -| `%s%s____creatorPublicKey` | `ByteVector` | Account creator | -| `%s%s____amountAssetId` | `ByteVector` | Account amount asset id | -| `%s%s____priceAssetId` | `ByteVector` | Account price asset id | -| `%s%s____accountIdToAccountPublicKey` | `ByteVector` | Account id → account public key | -| `%s%s____accountAddressToAccountId` | `String` | Account address → account id | +| key | type | description | +| ------------------------------------------------------ | ------------ | ------------------------------------- | +| `%s__servicePublicKey` | `ByteVector` | Service public key | +| `%s__botPublicKey` | `ByteVector` | Bot public key | +| `%s__accountScript` | `ByteVector` | Allowed account script | +| `%s__rewardAmount` | `Int` | Reward amount | +| `%s%s____status` | `Integer` | Account status (0 - empty, 1 - ready) | +| `%s%s____ownerPublicKey` | `ByteVector` | Account owner | +| `%s%s____creatorPublicKey` | `ByteVector` | Account creator | +| `%s%s____amountAssetId` | `ByteVector` | Account amount asset id | +| `%s%s____priceAssetId` | `ByteVector` | Account price asset id | +| `%s%s____accountIdToAccountPublicKey` | `ByteVector` | Account id → account public key | +| `%s%s____accountAddressToAccountId` | `String` | Account address → account id | +| `%s%s%s______pairAllowed` | `Boolean` | Pair allowed | #### Account -| key | type | description | -| ---------------------- | ------------ | ------------------- | -| `%s__factoryPublicKey` | `ByteVector` | Factory public key | +| key | type | description | +| ---------------------- | ------------ | ------------------ | +| `%s__factoryPublicKey` | `ByteVector` | Factory public key | ### Account creation From af1c00308b91b9aa5ba3de3bddf0f33397b65b28 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 3 Oct 2023 19:07:51 +0500 Subject: [PATCH 18/41] move and rename --- ride/{grid-trading/account.ride => grid_trading_account.ride} | 0 ride/{grid-trading/factory.ride => grid_trading_factory.ride} | 0 ride/{grid-trading/info.md => grid_trading_info.md} | 0 ride/{grid-trading/service.ride => grid_trading_service.ride} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename ride/{grid-trading/account.ride => grid_trading_account.ride} (100%) rename ride/{grid-trading/factory.ride => grid_trading_factory.ride} (100%) rename ride/{grid-trading/info.md => grid_trading_info.md} (100%) rename ride/{grid-trading/service.ride => grid_trading_service.ride} (100%) diff --git a/ride/grid-trading/account.ride b/ride/grid_trading_account.ride similarity index 100% rename from ride/grid-trading/account.ride rename to ride/grid_trading_account.ride diff --git a/ride/grid-trading/factory.ride b/ride/grid_trading_factory.ride similarity index 100% rename from ride/grid-trading/factory.ride rename to ride/grid_trading_factory.ride diff --git a/ride/grid-trading/info.md b/ride/grid_trading_info.md similarity index 100% rename from ride/grid-trading/info.md rename to ride/grid_trading_info.md diff --git a/ride/grid-trading/service.ride b/ride/grid_trading_service.ride similarity index 100% rename from ride/grid-trading/service.ride rename to ride/grid_trading_service.ride From 499dae42f6956c1209a3d04f8920b30fecb7e501 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 3 Oct 2023 19:40:00 +0500 Subject: [PATCH 19/41] lib --- ride/common.lib.ride | 13 +++++++++++++ ride/grid_trading_account.ride | 11 +---------- ride/grid_trading_factory.ride | 11 +---------- 3 files changed, 15 insertions(+), 20 deletions(-) create mode 100644 ride/common.lib.ride diff --git a/ride/common.lib.ride b/ride/common.lib.ride new file mode 100644 index 00000000..43f5235b --- /dev/null +++ b/ride/common.lib.ride @@ -0,0 +1,13 @@ +{-# SCRIPT_TYPE ACCOUNT #-} +{-# CONTENT_TYPE LIBRARY #-} +{-# STDLIB_VERSION 7 #-} + +let separator = "__" + +func mustAddress(i: Invocation, address: Address) = { + i.caller == address || throw() +} + +func mustThis(i: Invocation) = { + mustAddress(i, this) +} diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index afb625c3..cf3f5ccd 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -1,8 +1,7 @@ {-# STDLIB_VERSION 7 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} - -let separator = "__" +{-# IMPORT common.lib.ride #-} let kFactoryPublicKey = "%s__factoryPublicKey" let kServicePublicKey = "%s__servicePublicKey" @@ -23,14 +22,6 @@ let accountId = factoryAddress.getStringValue(kAccountAddressToAccountId(this)) let ownerPublicKey = factoryAddress.getBinaryValue(kAccountOwner(accountId)) let ownerAddress = addressFromPublicKey(ownerPublicKey) -func mustAddress(i: Invocation, address: Address) = { - i.caller == address || throw() -} - -func mustThis(i: Invocation) = { - mustAddress(i, this) -} - func mustService(i: Invocation) = { mustAddress(i, serviceAddress) } diff --git a/ride/grid_trading_factory.ride b/ride/grid_trading_factory.ride index 2f1057cc..d9748a25 100644 --- a/ride/grid_trading_factory.ride +++ b/ride/grid_trading_factory.ride @@ -1,16 +1,7 @@ {-# STDLIB_VERSION 7 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} - -let separator = "__" - -func mustAddress(i: Invocation, address: Address) = { - i.caller == address || throw() -} - -func mustThis(i: Invocation) = { - mustAddress(i, this) -} +{-# IMPORT common.lib.ride #-} let kServicePublicKey = "%s__servicePublicKey" let kBotPublicKey = "%s__botPublicKey" From abab8af841646943d5a12e698d84f4528e756455 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 5 Oct 2023 17:30:38 +0500 Subject: [PATCH 20/41] fix lib --- ride/common.lib.ride | 2 -- 1 file changed, 2 deletions(-) diff --git a/ride/common.lib.ride b/ride/common.lib.ride index 43f5235b..00e27849 100644 --- a/ride/common.lib.ride +++ b/ride/common.lib.ride @@ -1,6 +1,4 @@ -{-# SCRIPT_TYPE ACCOUNT #-} {-# CONTENT_TYPE LIBRARY #-} -{-# STDLIB_VERSION 7 #-} let separator = "__" From b650322b9831d8955575d08c4fbd0436db6f5084 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 5 Oct 2023 19:50:41 +0500 Subject: [PATCH 21/41] chainId to lib --- ride/common.lib.ride | 3 +++ ride/grid_trading_account.ride | 3 +-- ride/grid_trading_service.ride | 5 ++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/ride/common.lib.ride b/ride/common.lib.ride index 00e27849..6747f664 100644 --- a/ride/common.lib.ride +++ b/ride/common.lib.ride @@ -1,6 +1,9 @@ {-# CONTENT_TYPE LIBRARY #-} let separator = "__" +let chainId = this.bytes.drop(1).take(1) +let chainIdT = base16'54' +let chainIdW = base16'57' func mustAddress(i: Invocation, address: Address) = { i.caller == address || throw() diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index cf3f5ccd..d0158034 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -73,14 +73,13 @@ func call(function: String, args: List[String]) = { # bot can trade @Verifier(tx) func verify() = { - let testnet = this.bytes.drop(1).take(1) == base16'54' let botPublicKey = factoryAddress.getBinaryValue(kBotPublicKey) match tx { case _: Order => sigVerify(tx.bodyBytes, tx.proofs[0], botPublicKey) case _: InvokeScriptTransaction => if (this.getBinary(kFactoryPublicKey).isDefined()) then false else { sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) } - case _ => if (!testnet) then false else { + case _ => if (chainId == chainIdW) then false else { sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) } } diff --git a/ride/grid_trading_service.ride b/ride/grid_trading_service.ride index 3584f3ee..138c4104 100644 --- a/ride/grid_trading_service.ride +++ b/ride/grid_trading_service.ride @@ -1,6 +1,7 @@ {-# STDLIB_VERSION 7 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} +{-# IMPORT common.lib.ride #-} # withdraw from investment account to specified address @Callable(i) @@ -33,7 +34,5 @@ func setStrParam(args: List[String]) = { @Verifier(tx) func verify() = { - let testnet = this.bytes.drop(1).take(1) == base16'54' - - testnet + chainId == chainIdT } \ No newline at end of file From d3a289626b6c1f15dea681fbba91a127d23a61fa Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 10 Oct 2023 12:28:58 +0500 Subject: [PATCH 22/41] WIP: grid trading test --- test/components/grid_trading/_setup.mjs | 114 +++ test/components/grid_trading/request.spec.mjs | 39 + test/package.json | 1 + test/pnpm-lock.yaml | 854 +++++++++--------- test/utils/utils.mjs | 29 +- 5 files changed, 618 insertions(+), 419 deletions(-) create mode 100644 test/components/grid_trading/_setup.mjs create mode 100644 test/components/grid_trading/request.spec.mjs diff --git a/test/components/grid_trading/_setup.mjs b/test/components/grid_trading/_setup.mjs new file mode 100644 index 00000000..671e3b90 --- /dev/null +++ b/test/components/grid_trading/_setup.mjs @@ -0,0 +1,114 @@ +import wc, { base58Decode, base64Encode } from '@waves/ts-lib-crypto'; +import { + massTransfer, + invokeScript, + issue, +} from '@waves/waves-transactions'; +import { format } from 'path'; +import { table, getBorderCharacters } from 'table'; + +import { readFile } from 'fs/promises'; +import { + chainId, broadcastAndWait, baseSeed, +} from '../../utils/api.mjs'; + +import { + compileScriptFromFile, + setScriptFromFile, +} from '../../utils/utils.mjs'; + +const nonceLength = 3; +const ridePath = '../ride'; +const factoryPath = format({ dir: ridePath, base: 'grid_trading_factory.ride' }); +const servicePath = format({ dir: ridePath, base: 'grid_trading_service.ride' }); +const accountPath = format({ dir: ridePath, base: 'grid_trading_account.ride' }); +const commonLibPath = format({ dir: ridePath, base: 'common.lib.ride' }); + +export const setup = async ({ + rewardAmount = 1000, +} = {}) => { + const nonce = wc.random(nonceLength, 'Buffer').toString('hex'); + const names = [ + 'factory', + 'service', + 'bot', + 'user1', + 'user2', + 'account1', + 'account2', + ]; + const accounts = Object.fromEntries(names.map((item) => { + const seed = `${item}#${nonce}`; + return [item, { seed, address: wc.address(seed, chainId), publicKey: wc.publicKey(seed) }]; + })); + const accountsInfo = Object.entries(accounts) + .map(([name, { address, publicKey }]) => [name, address, publicKey]); + console.log(table(accountsInfo, { + border: getBorderCharacters('norc'), + drawHorizontalLine: (index, size) => index === 0 || index === 1 || index === size, + header: { content: `pid: ${process.pid}, nonce: ${nonce}` }, + })); + const amount = 10e8; + const massTransferTx = massTransfer({ + transfers: Object.values(accounts).map(({ address }) => ({ recipient: address, amount })), + chainId, + }, baseSeed); + await broadcastAndWait(massTransferTx); + + const libraries = { + 'common.lib.ride': await readFile(commonLibPath, { encoding: 'utf-8' }), + }; + + const [ + { id: assetId1 }, + { id: assetId2 }, + ] = await Promise.all([ + broadcastAndWait(issue({ + name: 'assetId1', + description: '', + quantity: 1e6 * 1e8, + decimals: 8, + reissuable: true, + chainId, + }, baseSeed)), + broadcastAndWait(issue({ + name: 'assetId2', + description: '', + quantity: 1e6 * 1e8, + decimals: 8, + reissuable: true, + chainId, + }, baseSeed)), + setScriptFromFile( + factoryPath, + accounts.factory.seed, + null, + libraries, + ), + setScriptFromFile( + servicePath, + accounts.service.seed, + null, + libraries, + ), + ]); + + const { base64: accountScript } = await compileScriptFromFile(accountPath, null, libraries); + await broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'init', + args: [ + { type: 'binary', value: base64Encode(base58Decode(accounts.service.publicKey)) }, + { type: 'binary', value: base64Encode(base58Decode(accounts.bot.publicKey)) }, + { type: 'binary', value: accountScript }, + { type: 'integer', value: rewardAmount }, + ], + }, + chainId, + }, accounts.factory.seed)); + + return { + accounts, rewardAmount, assetId1, assetId2, + }; +}; diff --git a/test/components/grid_trading/request.spec.mjs b/test/components/grid_trading/request.spec.mjs new file mode 100644 index 00000000..842264a5 --- /dev/null +++ b/test/components/grid_trading/request.spec.mjs @@ -0,0 +1,39 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { invokeScript } from '@waves/waves-transactions'; +import { base64Encode } from '@waves/ts-lib-crypto'; +import { chainId, broadcastAndWait } from '../../utils/api.mjs'; +import { setup } from './_setup.mjs'; + +chai.use(chaiAsPromised); +const { expect } = chai; + +describe(`[${process.pid}] grid_trading: request`, () => { + let accounts; + let rewardAmount; + let assetId1; + let assetId2; + + before(async () => { + ({ + accounts, rewardAmount, assetId1, assetId2, + } = await setup()); + }); + + it('pair is not allowed', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: base64Encode(base58Decode(assetId1)) }, + { type: 'binary', value: base64Encode(base58Decode(assetId2)) }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.factory.seed))).to.be.rejectedWith('pair is not allowed'); + }); +}); diff --git a/test/package.json b/test/package.json index ed7a9409..5c795c8b 100644 --- a/test/package.json +++ b/test/package.json @@ -29,6 +29,7 @@ "test-gwx-reward": "mocha -r dotenv/config --parallel --require components/gwx_reward/_hooks.mjs components/gwx_reward", "test-l2mp-staking": "mocha -r dotenv/config --parallel --require components/l2mp_staking/_hooks.mjs components/l2mp_staking", "test-l2mp-swap": "mocha -r dotenv/config --parallel --require components/l2mp_swap/_hooks.mjs components/l2mp_swap", + "test-grid-trading": "mocha -r dotenv/config --parallel components/grid_trading", "ci-test": "node_modules/.bin/concurrently --max-processes 8 --timings npm:test-*", "exchange-test": "mocha -r dotenv/config --parallel --require components/exchange/_hooks.mjs components/exchange", "test": "API_NODE_URL=http://localhost:6869 npm run ci-test", diff --git a/test/pnpm-lock.yaml b/test/pnpm-lock.yaml index a69fdb63..1e4bf135 100644 --- a/test/pnpm-lock.yaml +++ b/test/pnpm-lock.yaml @@ -1,70 +1,97 @@ -lockfileVersion: 5.4 - -specifiers: - '@types/chai': ^4.3.0 - '@types/chai-as-promised': ^7.1.5 - '@types/mocha': ^9.1.0 - '@waves/bignumber': ^1.1.1 - '@waves/node-api-js': ^1.3.0 - '@waves/ride-js': ^2.2.0 - '@waves/ts-lib-crypto': ^1.4.4-beta.1 - '@waves/ts-types': ^1.1.0 - '@waves/waves-transactions': ^4.2.5-beta.3 - axios: ^0.26.1 - chai: ^4.3.6 - chai-as-promised: ^7.1.1 - concurrently: ^7.1.0 - dotenv: ^16.0.3 - eslint: ^8.10.0 - eslint-config-airbnb-base: ^15.0.0 - eslint-plugin-import: ^2.25.4 - level: ^8.0.0 - mocha: ^9.2.1 - ora: ^6.1.0 - prompts: ^2.4.2 - table: ^6.8.0 +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false dependencies: - '@types/chai': 4.3.0 - '@types/chai-as-promised': 7.1.5 - '@types/mocha': 9.1.0 - '@waves/bignumber': 1.1.1 - '@waves/node-api-js': 1.3.0 - '@waves/ride-js': 2.2.0 - '@waves/ts-lib-crypto': 1.4.4-beta.1 - '@waves/ts-types': 1.1.0 - '@waves/waves-transactions': 4.2.5-beta.3 - axios: 0.26.1 - chai: 4.3.6 - chai-as-promised: 7.1.1_chai@4.3.6 - concurrently: 7.1.0 - eslint: 8.10.0 - eslint-config-airbnb-base: 15.0.0_rnagsyfcubvpoxo2ynj23pim7u - eslint-plugin-import: 2.25.4_eslint@8.10.0 - level: 8.0.0 - mocha: 9.2.1 - ora: 6.1.0 - prompts: 2.4.2 - table: 6.8.0 + '@types/chai': + specifier: ^4.3.0 + version: 4.3.0 + '@types/chai-as-promised': + specifier: ^7.1.5 + version: 7.1.5 + '@types/mocha': + specifier: ^9.1.0 + version: 9.1.0 + '@waves/bignumber': + specifier: ^1.1.1 + version: 1.1.1 + '@waves/node-api-js': + specifier: ^1.3.0 + version: 1.3.0 + '@waves/ride-js': + specifier: ^2.2.7 + version: 2.2.7 + '@waves/ts-lib-crypto': + specifier: ^1.4.4-beta.1 + version: 1.4.4-beta.1 + '@waves/ts-types': + specifier: ^1.1.0 + version: 1.1.0 + '@waves/waves-transactions': + specifier: ^4.2.5-beta.3 + version: 4.2.5-beta.3 + axios: + specifier: ^0.26.1 + version: 0.26.1 + chai: + specifier: ^4.3.6 + version: 4.3.6 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.1(chai@4.3.6) + chai-subset: + specifier: ^1.6.0 + version: 1.6.0 + concurrently: + specifier: ^7.1.0 + version: 7.1.0 + eslint: + specifier: ^8.10.0 + version: 8.10.0 + eslint-config-airbnb-base: + specifier: ^15.0.0 + version: 15.0.0(eslint-plugin-import@2.25.4)(eslint@8.10.0) + eslint-plugin-import: + specifier: ^2.25.4 + version: 2.25.4(eslint@8.10.0) + level: + specifier: ^8.0.0 + version: 8.0.0 + mocha: + specifier: ^9.2.1 + version: 9.2.1 + ora: + specifier: ^6.1.0 + version: 6.1.0 + prompts: + specifier: ^2.4.2 + version: 2.4.2 + table: + specifier: ^6.8.0 + version: 6.8.0 devDependencies: - dotenv: 16.0.3 + dotenv: + specifier: ^16.0.3 + version: 16.0.3 packages: - /@babel/code-frame/7.18.6: + /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} dependencies: '@babel/highlight': 7.18.6 dev: false - /@babel/helper-validator-identifier/7.18.6: + /@babel/helper-validator-identifier@7.18.6: resolution: {integrity: sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==} engines: {node: '>=6.9.0'} dev: false - /@babel/highlight/7.18.6: + /@babel/highlight@7.18.6: resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} engines: {node: '>=6.9.0'} dependencies: @@ -73,12 +100,12 @@ packages: js-tokens: 4.0.0 dev: false - /@eslint/eslintrc/1.2.0: + /@eslint/eslintrc@1.2.0: resolution: {integrity: sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 - debug: 4.3.3 + debug: 4.3.3(supports-color@8.1.1) espree: 9.3.1 globals: 13.12.1 ignore: 4.0.6 @@ -90,22 +117,22 @@ packages: - supports-color dev: false - /@humanwhocodes/config-array/0.9.5: + /@humanwhocodes/config-array@0.9.5: resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==} engines: {node: '>=10.10.0'} dependencies: '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.3 + debug: 4.3.3(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color dev: false - /@humanwhocodes/object-schema/1.2.1: + /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: false - /@jest/environment/27.5.1: + /@jest/environment@27.5.1: resolution: {integrity: sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -115,7 +142,7 @@ packages: jest-mock: 27.5.1 dev: false - /@jest/fake-timers/27.5.1: + /@jest/fake-timers@27.5.1: resolution: {integrity: sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -127,7 +154,7 @@ packages: jest-util: 27.5.1 dev: false - /@jest/globals/27.5.1: + /@jest/globals@27.5.1: resolution: {integrity: sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -136,7 +163,7 @@ packages: expect: 27.5.1 dev: false - /@jest/types/27.5.1: + /@jest/types@27.5.1: resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -147,143 +174,143 @@ packages: chalk: 4.1.2 dev: false - /@protobufjs/aspromise/1.1.2: + /@protobufjs/aspromise@1.1.2: resolution: {integrity: sha1-m4sMxmPWaafY9vXQiToU00jzD78=} dev: false - /@protobufjs/base64/1.1.2: + /@protobufjs/base64@1.1.2: resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} dev: false - /@protobufjs/codegen/2.0.4: + /@protobufjs/codegen@2.0.4: resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} dev: false - /@protobufjs/eventemitter/1.1.0: + /@protobufjs/eventemitter@1.1.0: resolution: {integrity: sha1-NVy8mLr61ZePntCV85diHx0Ga3A=} dev: false - /@protobufjs/fetch/1.1.0: + /@protobufjs/fetch@1.1.0: resolution: {integrity: sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=} dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/inquire': 1.1.0 dev: false - /@protobufjs/float/1.0.2: + /@protobufjs/float@1.0.2: resolution: {integrity: sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=} dev: false - /@protobufjs/inquire/1.1.0: + /@protobufjs/inquire@1.1.0: resolution: {integrity: sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=} dev: false - /@protobufjs/path/1.1.2: + /@protobufjs/path@1.1.2: resolution: {integrity: sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=} dev: false - /@protobufjs/pool/1.1.0: + /@protobufjs/pool@1.1.0: resolution: {integrity: sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=} dev: false - /@protobufjs/utf8/1.1.0: + /@protobufjs/utf8@1.1.0: resolution: {integrity: sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=} dev: false - /@sinonjs/commons/1.8.3: + /@sinonjs/commons@1.8.3: resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} dependencies: type-detect: 4.0.8 dev: false - /@sinonjs/fake-timers/8.1.0: + /@sinonjs/fake-timers@8.1.0: resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==} dependencies: '@sinonjs/commons': 1.8.3 dev: false - /@types/base64-js/1.3.0: + /@types/base64-js@1.3.0: resolution: {integrity: sha512-ZmI0sZGAUNXUfMWboWwi4LcfpoVUYldyN6Oe0oJ5cCsHDU/LlRq8nQKPXhYLOx36QYSW9bNIb1vvRrD6K7Llgw==} dev: false - /@types/chai-as-promised/7.1.5: + /@types/chai-as-promised@7.1.5: resolution: {integrity: sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ==} dependencies: '@types/chai': 4.3.0 dev: false - /@types/chai/4.3.0: + /@types/chai@4.3.0: resolution: {integrity: sha512-/ceqdqeRraGolFTcfoXNiqjyQhZzbINDngeoAq9GoHa8PPK1yNzTaxWjA6BFWp5Ua9JpXEMSS4s5i9tS0hOJtw==} dev: false - /@types/istanbul-lib-coverage/2.0.4: + /@types/istanbul-lib-coverage@2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: false - /@types/istanbul-lib-report/3.0.0: + /@types/istanbul-lib-report@3.0.0: resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} dependencies: '@types/istanbul-lib-coverage': 2.0.4 dev: false - /@types/istanbul-reports/3.0.1: + /@types/istanbul-reports@3.0.1: resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} dependencies: '@types/istanbul-lib-report': 3.0.0 dev: false - /@types/json5/0.0.29: + /@types/json5@0.0.29: resolution: {integrity: sha1-7ihweulOEdK4J7y+UnC86n8+ce4=} dev: false - /@types/long/4.0.1: + /@types/long@4.0.1: resolution: {integrity: sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==} dev: false - /@types/mocha/9.1.0: + /@types/mocha@9.1.0: resolution: {integrity: sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==} dev: false - /@types/node-fetch/2.6.1: + /@types/node-fetch@2.6.1: resolution: {integrity: sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA==} dependencies: '@types/node': 18.0.1 form-data: 3.0.1 dev: false - /@types/node/17.0.21: + /@types/node@17.0.21: resolution: {integrity: sha512-DBZCJbhII3r90XbQxI8Y9IjjiiOGlZ0Hr32omXIZvwwZ7p4DMMXGrKXVyPfuoBOri9XNtL0UK69jYIBIsRX3QQ==} dev: false - /@types/node/18.0.1: + /@types/node@18.0.1: resolution: {integrity: sha512-CmR8+Tsy95hhwtZBKJBs0/FFq4XX7sDZHlGGf+0q+BRZfMbOTkzkj0AFAuTyXbObDIoanaBBW0+KEW+m3N16Wg==} dev: false - /@types/stack-utils/2.0.1: + /@types/stack-utils@2.0.1: resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} dev: false - /@types/yargs-parser/21.0.0: + /@types/yargs-parser@21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} dev: false - /@types/yargs/16.0.4: + /@types/yargs@16.0.4: resolution: {integrity: sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==} dependencies: '@types/yargs-parser': 21.0.0 dev: false - /@ungap/promise-all-settled/1.1.2: + /@ungap/promise-all-settled@1.1.2: resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} dev: false - /@waves/bignumber/1.1.1: + /@waves/bignumber@1.1.1: resolution: {integrity: sha512-WUY0R0y0Rd92nbyQHbIFDXCWh2YMtf5FYtpoTv4yRomM75cRLJ0/NIQ828guUXLKeVytKzWgvDYj1CZfxatDkg==} dependencies: bignumber.js: 9.0.2 dev: false - /@waves/marshall/0.14.0: + /@waves/marshall@0.14.0: resolution: {integrity: sha512-zcmDEwlD3dgzaTX6d2UM57KaGO6DK759b9EfdGa48UzwsjLdqX+v/6hrcqZEPUYMeymD6fO8O4/S+0RDxue8Wg==} dependencies: '@types/base64-js': 1.3.0 @@ -293,7 +320,7 @@ packages: long: 4.0.0 dev: false - /@waves/node-api-js/1.3.0: + /@waves/node-api-js@1.3.0: resolution: {integrity: sha512-FEI42KM1C6hE541kexV/eqWDeBrVxeMswZbHQ9kRlFdso/kKmouhhjV73NI/zFCSwMzbFI4YDe2ElOSim0DyEA==} dependencies: '@types/node-fetch': 2.6.1 @@ -305,19 +332,19 @@ packages: - encoding dev: false - /@waves/parse-json-bignumber/1.0.3: + /@waves/parse-json-bignumber@1.0.3: resolution: {integrity: sha512-zBHIQUjjMYMQXNQcwJwzNShUZnoTM6JfVJDwa0eDGUVk+JAKVGiXxv/k29Ng9TsIDi97hwVravlPPwfZcy4XXQ==} dev: false - /@waves/protobuf-serialization/1.4.1-beta.1: + /@waves/protobuf-serialization@1.4.1-beta.1: resolution: {integrity: sha512-IjEwyWmjyesjURvhvB2DK/QZ8mKFuBg7zz5SvgG6q8/ofnC4oplSOsWsgT2DjOG4OzGaMUv7Kkv/ZV1qTQxO9g==} dependencies: '@types/long': 4.0.1 protobufjs: 6.11.2 dev: false - /@waves/ride-js/2.2.0: - resolution: {integrity: sha512-a46cZYAE9Cp2DjXPcqrx4CQRtTGLIr+gIvPomRCkDqZpgtd2DvSh6alLJryYMSeMHlgugmZv/qos5Z7OMAs4eQ==} + /@waves/ride-js@2.2.7: + resolution: {integrity: sha512-mL0BgWVMFnqvoL5d9XYbKJfAE6FXs3FXgrsQpRJj5RiOxtIplFWM2Q+EbiIvSmAZ6EUhP/5ufaIbbZeNkMMOIA==} dependencies: '@jest/globals': 27.5.1 '@waves/ts-lib-crypto': 1.4.3 @@ -326,29 +353,29 @@ packages: - supports-color dev: false - /@waves/ts-lib-crypto/1.4.3: + /@waves/ts-lib-crypto@1.4.3: resolution: {integrity: sha512-2pKgyvtLapgM5vpaUEYzX7NYe2bkB+HdWn9W/4d7UFKwyg6zoOYhRQWyb6GuLi3OLHTETgiqpcMZvciFA0Ds6g==} dependencies: js-sha3: 0.8.0 node-forge: 0.8.5 dev: false - /@waves/ts-lib-crypto/1.4.4-beta.1: + /@waves/ts-lib-crypto@1.4.4-beta.1: resolution: {integrity: sha512-tlvThkMCoCDicOznW82wDZWQqfAWcm6ulQnuNzR++X9o0EOHM3Cj8LlS2pkgF0YjZrqEYHTp/4e0RXXYVY+dpw==} dependencies: js-sha3: 0.8.0 node-forge: 0.10.0 dev: false - /@waves/ts-types/1.0.6-beta.4: + /@waves/ts-types@1.0.6-beta.4: resolution: {integrity: sha512-TyFzgYiWkJ5PF7F3XxAE1dudti5a9MVh2BgtGhYKIrSanXNPXhT9KYYRkQRIemYP+HQ4y89rEBf/CUszTdnaag==} dev: false - /@waves/ts-types/1.1.0: + /@waves/ts-types@1.1.0: resolution: {integrity: sha512-SGHj4cIIvMAhDPiDhbpEzP2UqNF3VgTssGf6UaJ7vwzxq0W1pqz2lKMDe9pZup9p9rEETGW4Yy3+K1G7OGOLxA==} dev: false - /@waves/waves-transactions/4.2.5-beta.3: + /@waves/waves-transactions@4.2.5-beta.3: resolution: {integrity: sha512-LiEya9gV0KAaxEVusKEPiXb6fZYuVOUePUfC9YjasODjGT4KLOFp5Po3u746Rt7T04S/3cUaxk19WhdfbpGBtQ==} dependencies: '@waves/marshall': 0.14.0 @@ -363,7 +390,7 @@ packages: - supports-color dev: false - /abstract-level/1.0.3: + /abstract-level@1.0.3: resolution: {integrity: sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==} engines: {node: '>=12'} dependencies: @@ -376,7 +403,7 @@ packages: queue-microtask: 1.2.3 dev: false - /acorn-jsx/5.3.2_acorn@8.7.0: + /acorn-jsx@5.3.2(acorn@8.7.0): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -384,13 +411,13 @@ packages: acorn: 8.7.0 dev: false - /acorn/8.7.0: + /acorn@8.7.0: resolution: {integrity: sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==} engines: {node: '>=0.4.0'} hasBin: true dev: false - /ajv/6.12.6: + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} dependencies: fast-deep-equal: 3.1.3 @@ -399,7 +426,7 @@ packages: uri-js: 4.4.1 dev: false - /ajv/8.11.0: + /ajv@8.11.0: resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} dependencies: fast-deep-equal: 3.1.3 @@ -408,41 +435,41 @@ packages: uri-js: 4.4.1 dev: false - /ansi-colors/4.1.1: + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} dev: false - /ansi-regex/5.0.1: + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} dev: false - /ansi-regex/6.0.1: + /ansi-regex@6.0.1: resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} engines: {node: '>=12'} dev: false - /ansi-styles/3.2.1: + /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} dependencies: color-convert: 1.9.3 dev: false - /ansi-styles/4.3.0: + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} dependencies: color-convert: 2.0.1 dev: false - /ansi-styles/5.2.0: + /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} dev: false - /anymatch/3.1.2: + /anymatch@3.1.2: resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} engines: {node: '>= 8'} dependencies: @@ -450,11 +477,11 @@ packages: picomatch: 2.3.1 dev: false - /argparse/2.0.1: + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} dev: false - /array-includes/3.1.4: + /array-includes@3.1.4: resolution: {integrity: sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==} engines: {node: '>= 0.4'} dependencies: @@ -465,7 +492,7 @@ packages: is-string: 1.0.7 dev: false - /array.prototype.flat/1.2.5: + /array.prototype.flat@1.2.5: resolution: {integrity: sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==} engines: {node: '>= 0.4'} dependencies: @@ -474,20 +501,20 @@ packages: es-abstract: 1.19.1 dev: false - /assertion-error/1.1.0: + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: false - /astral-regex/2.0.0: + /astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} dev: false - /asynckit/0.4.0: + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios/0.19.2: + /axios@0.19.2: resolution: {integrity: sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==} deprecated: Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410 dependencies: @@ -496,7 +523,7 @@ packages: - supports-color dev: false - /axios/0.26.1: + /axios@0.26.1: resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} dependencies: follow-redirects: 1.14.9 @@ -504,24 +531,24 @@ packages: - debug dev: false - /balanced-match/1.0.2: + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: false - /base64-js/1.5.1: + /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} dev: false - /bignumber.js/9.0.2: + /bignumber.js@9.0.2: resolution: {integrity: sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==} dev: false - /binary-extensions/2.2.0: + /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} dev: false - /bl/5.0.0: + /bl@5.0.0: resolution: {integrity: sha512-8vxFNZ0pflFfi0WXA3WQXlj6CaMEwsmh63I1CNp0q+wWv8sD0ARx1KovSQd0l2GkwrMIOyedq0EF1FxI+RCZLQ==} dependencies: buffer: 6.0.3 @@ -529,21 +556,21 @@ packages: readable-stream: 3.6.0 dev: false - /brace-expansion/1.1.11: + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 dev: false - /braces/3.0.2: + /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} engines: {node: '>=8'} dependencies: fill-range: 7.0.1 dev: false - /browser-level/1.0.1: + /browser-level@1.0.1: resolution: {integrity: sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==} dependencies: abstract-level: 1.0.3 @@ -552,40 +579,40 @@ packages: run-parallel-limit: 1.1.0 dev: false - /browser-stdout/1.3.1: + /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: false - /buffer/6.0.3: + /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 dev: false - /call-bind/1.0.2: + /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: function-bind: 1.1.1 get-intrinsic: 1.1.1 dev: false - /callsites/3.1.0: + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} dev: false - /camelcase/6.3.0: + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} dev: false - /catering/2.1.1: + /catering@2.1.1: resolution: {integrity: sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==} engines: {node: '>=6'} dev: false - /chai-as-promised/7.1.1_chai@4.3.6: + /chai-as-promised@7.1.1(chai@4.3.6): resolution: {integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==} peerDependencies: chai: '>= 2.1.2 < 5' @@ -594,7 +621,12 @@ packages: check-error: 1.0.2 dev: false - /chai/4.3.6: + /chai-subset@1.6.0: + resolution: {integrity: sha512-K3d+KmqdS5XKW5DWPd5sgNffL3uxdDe+6GdnJh3AYPhwnBGRY5urfvfcbRtWIvvpz+KxkL9FeBB6MZewLUNwug==} + engines: {node: '>=4'} + dev: false + + /chai@4.3.6: resolution: {integrity: sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==} engines: {node: '>=4'} dependencies: @@ -607,7 +639,7 @@ packages: type-detect: 4.0.8 dev: false - /chalk/2.4.2: + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} dependencies: @@ -616,7 +648,7 @@ packages: supports-color: 5.5.0 dev: false - /chalk/4.1.2: + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} dependencies: @@ -624,16 +656,16 @@ packages: supports-color: 7.2.0 dev: false - /chalk/5.0.1: + /chalk@5.0.1: resolution: {integrity: sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} dev: false - /check-error/1.0.2: + /check-error@1.0.2: resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=} dev: false - /chokidar/3.5.3: + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} dependencies: @@ -648,11 +680,11 @@ packages: fsevents: 2.3.2 dev: false - /ci-info/3.3.2: + /ci-info@3.3.2: resolution: {integrity: sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==} dev: false - /classic-level/1.2.0: + /classic-level@1.2.0: resolution: {integrity: sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==} engines: {node: '>=12'} requiresBuild: true @@ -664,19 +696,19 @@ packages: node-gyp-build: 4.4.0 dev: false - /cli-cursor/4.0.0: + /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: restore-cursor: 4.0.0 dev: false - /cli-spinners/2.6.1: + /cli-spinners@2.6.1: resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} engines: {node: '>=6'} dev: false - /cliui/7.0.4: + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: string-width: 4.2.3 @@ -684,44 +716,44 @@ packages: wrap-ansi: 7.0.0 dev: false - /clone/1.0.4: + /clone@1.0.4: resolution: {integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4=} engines: {node: '>=0.8'} dev: false - /color-convert/1.9.3: + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: color-name: 1.1.3 dev: false - /color-convert/2.0.1: + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 dev: false - /color-name/1.1.3: + /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} dev: false - /color-name/1.1.4: + /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: false - /combined-stream/1.0.8: + /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 dev: false - /concat-map/0.0.1: + /concat-map@0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} dev: false - /concurrently/7.1.0: + /concurrently@7.1.0: resolution: {integrity: sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==} engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} hasBin: true @@ -736,11 +768,11 @@ packages: yargs: 16.2.0 dev: false - /confusing-browser-globals/1.0.11: + /confusing-browser-globals@1.0.11: resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} dev: false - /cross-spawn/7.0.3: + /cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} dependencies: @@ -749,12 +781,12 @@ packages: which: 2.0.2 dev: false - /date-fns/2.28.0: + /date-fns@2.28.0: resolution: {integrity: sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==} engines: {node: '>=0.11'} dev: false - /debug/2.6.9: + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: supports-color: '*' @@ -765,7 +797,7 @@ packages: ms: 2.0.0 dev: false - /debug/3.1.0: + /debug@3.1.0: resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} peerDependencies: supports-color: '*' @@ -776,7 +808,7 @@ packages: ms: 2.0.0 dev: false - /debug/3.2.7: + /debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: supports-color: '*' @@ -787,19 +819,7 @@ packages: ms: 2.1.3 dev: false - /debug/4.3.3: - resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: false - - /debug/4.3.3_supports-color@8.1.1: + /debug@4.3.3(supports-color@8.1.1): resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} engines: {node: '>=6.0'} peerDependencies: @@ -812,74 +832,74 @@ packages: supports-color: 8.1.1 dev: false - /decamelize/4.0.0: + /decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} dev: false - /deep-eql/3.0.1: + /deep-eql@3.0.1: resolution: {integrity: sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==} engines: {node: '>=0.12'} dependencies: type-detect: 4.0.8 dev: false - /deep-is/0.1.4: + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: false - /defaults/1.0.3: + /defaults@1.0.3: resolution: {integrity: sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=} dependencies: clone: 1.0.4 dev: false - /define-properties/1.1.3: + /define-properties@1.1.3: resolution: {integrity: sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==} engines: {node: '>= 0.4'} dependencies: object-keys: 1.1.1 dev: false - /delayed-stream/1.0.0: + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} dev: false - /diff-sequences/27.5.1: + /diff-sequences@27.5.1: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dev: false - /diff/5.0.0: + /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} dev: false - /doctrine/2.1.0: + /doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} dependencies: esutils: 2.0.3 dev: false - /doctrine/3.0.0: + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 dev: false - /dotenv/16.0.3: + /dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} dev: true - /emoji-regex/8.0.0: + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} dev: false - /es-abstract/1.19.1: + /es-abstract@1.19.1: resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==} engines: {node: '>= 0.4'} dependencies: @@ -905,7 +925,7 @@ packages: unbox-primitive: 1.0.1 dev: false - /es-to-primitive/1.2.1: + /es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} engines: {node: '>= 0.4'} dependencies: @@ -914,27 +934,27 @@ packages: is-symbol: 1.0.4 dev: false - /escalade/3.1.1: + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} dev: false - /escape-string-regexp/1.0.5: + /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} dev: false - /escape-string-regexp/2.0.0: + /escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} dev: false - /escape-string-regexp/4.0.0: + /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} dev: false - /eslint-config-airbnb-base/15.0.0_rnagsyfcubvpoxo2ynj23pim7u: + /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.25.4)(eslint@8.10.0): resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -943,13 +963,13 @@ packages: dependencies: confusing-browser-globals: 1.0.11 eslint: 8.10.0 - eslint-plugin-import: 2.25.4_eslint@8.10.0 + eslint-plugin-import: 2.25.4(eslint@8.10.0) object.assign: 4.1.2 object.entries: 1.1.5 semver: 6.3.0 dev: false - /eslint-import-resolver-node/0.3.6: + /eslint-import-resolver-node@0.3.6: resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} dependencies: debug: 3.2.7 @@ -958,7 +978,7 @@ packages: - supports-color dev: false - /eslint-module-utils/2.7.3_ulu2225r2ychl26a37c6o2rfje: + /eslint-module-utils@2.7.3(eslint-import-resolver-node@0.3.6): resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} peerDependencies: @@ -983,7 +1003,7 @@ packages: - supports-color dev: false - /eslint-plugin-import/2.25.4_eslint@8.10.0: + /eslint-plugin-import@2.25.4(eslint@8.10.0): resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} engines: {node: '>=4'} peerDependencies: @@ -999,7 +1019,7 @@ packages: doctrine: 2.1.0 eslint: 8.10.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3_ulu2225r2ychl26a37c6o2rfje + eslint-module-utils: 2.7.3(eslint-import-resolver-node@0.3.6) has: 1.0.3 is-core-module: 2.8.1 is-glob: 4.0.3 @@ -1013,7 +1033,7 @@ packages: - supports-color dev: false - /eslint-scope/7.1.1: + /eslint-scope@7.1.1: resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: @@ -1021,7 +1041,7 @@ packages: estraverse: 5.3.0 dev: false - /eslint-utils/3.0.0_eslint@8.10.0: + /eslint-utils@3.0.0(eslint@8.10.0): resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: @@ -1031,17 +1051,17 @@ packages: eslint-visitor-keys: 2.1.0 dev: false - /eslint-visitor-keys/2.1.0: + /eslint-visitor-keys@2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} dev: false - /eslint-visitor-keys/3.3.0: + /eslint-visitor-keys@3.3.0: resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false - /eslint/8.10.0: + /eslint@8.10.0: resolution: {integrity: sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true @@ -1051,11 +1071,11 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.3 + debug: 4.3.3(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.10.0 + eslint-utils: 3.0.0(eslint@8.10.0) eslint-visitor-keys: 3.3.0 espree: 9.3.1 esquery: 1.4.0 @@ -1085,40 +1105,40 @@ packages: - supports-color dev: false - /espree/9.3.1: + /espree@9.3.1: resolution: {integrity: sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.7.0 - acorn-jsx: 5.3.2_acorn@8.7.0 + acorn-jsx: 5.3.2(acorn@8.7.0) eslint-visitor-keys: 3.3.0 dev: false - /esquery/1.4.0: + /esquery@1.4.0: resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 dev: false - /esrecurse/4.3.0: + /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 dev: false - /estraverse/5.3.0: + /estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} dev: false - /esutils/2.0.3: + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} dev: false - /expect/27.5.1: + /expect@27.5.1: resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1128,40 +1148,40 @@ packages: jest-message-util: 27.5.1 dev: false - /fast-deep-equal/3.1.3: + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: false - /fast-json-stable-stringify/2.1.0: + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: false - /fast-levenshtein/2.0.6: + /fast-levenshtein@2.0.6: resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=} dev: false - /file-entry-cache/6.0.1: + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 dev: false - /fill-range/7.0.1: + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 dev: false - /find-up/2.1.0: + /find-up@2.1.0: resolution: {integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=} engines: {node: '>=4'} dependencies: locate-path: 2.0.0 dev: false - /find-up/5.0.0: + /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} dependencies: @@ -1169,7 +1189,7 @@ packages: path-exists: 4.0.0 dev: false - /flat-cache/3.0.4: + /flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: @@ -1177,16 +1197,16 @@ packages: rimraf: 3.0.2 dev: false - /flat/5.0.2: + /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true dev: false - /flatted/3.2.5: + /flatted@3.2.5: resolution: {integrity: sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==} dev: false - /follow-redirects/1.14.9: + /follow-redirects@1.14.9: resolution: {integrity: sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==} engines: {node: '>=4.0'} peerDependencies: @@ -1196,7 +1216,7 @@ packages: optional: true dev: false - /follow-redirects/1.5.10: + /follow-redirects@1.5.10: resolution: {integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==} engines: {node: '>=4.0'} dependencies: @@ -1205,7 +1225,7 @@ packages: - supports-color dev: false - /form-data/3.0.1: + /form-data@3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} dependencies: @@ -1214,11 +1234,11 @@ packages: mime-types: 2.1.34 dev: false - /fs.realpath/1.0.0: + /fs.realpath@1.0.0: resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} dev: false - /fsevents/2.3.2: + /fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] @@ -1226,24 +1246,24 @@ packages: dev: false optional: true - /function-bind/1.1.1: + /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} dev: false - /functional-red-black-tree/1.0.1: + /functional-red-black-tree@1.0.1: resolution: {integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=} dev: false - /get-caller-file/2.0.5: + /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} dev: false - /get-func-name/2.0.0: + /get-func-name@2.0.0: resolution: {integrity: sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=} dev: false - /get-intrinsic/1.1.1: + /get-intrinsic@1.1.1: resolution: {integrity: sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==} dependencies: function-bind: 1.1.1 @@ -1251,7 +1271,7 @@ packages: has-symbols: 1.0.2 dev: false - /get-symbol-description/1.0.0: + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} dependencies: @@ -1259,21 +1279,21 @@ packages: get-intrinsic: 1.1.1 dev: false - /glob-parent/5.1.2: + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 dev: false - /glob-parent/6.0.2: + /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 dev: false - /glob/7.2.0: + /glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} dependencies: fs.realpath: 1.0.0 @@ -1284,75 +1304,75 @@ packages: path-is-absolute: 1.0.1 dev: false - /globals/13.12.1: + /globals@13.12.1: resolution: {integrity: sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 dev: false - /graceful-fs/4.2.10: + /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} dev: false - /growl/1.10.5: + /growl@1.10.5: resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} engines: {node: '>=4.x'} dev: false - /has-bigints/1.0.1: + /has-bigints@1.0.1: resolution: {integrity: sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==} dev: false - /has-flag/3.0.0: + /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} dev: false - /has-flag/4.0.0: + /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} dev: false - /has-symbols/1.0.2: + /has-symbols@1.0.2: resolution: {integrity: sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==} engines: {node: '>= 0.4'} dev: false - /has-tostringtag/1.0.0: + /has-tostringtag@1.0.0: resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.2 dev: false - /has/1.0.3: + /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 dev: false - /he/1.2.0: + /he@1.2.0: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true dev: false - /ieee754/1.2.1: + /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false - /ignore/4.0.6: + /ignore@4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} dev: false - /ignore/5.2.0: + /ignore@5.2.0: resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} engines: {node: '>= 4'} dev: false - /import-fresh/3.3.0: + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} dependencies: @@ -1360,23 +1380,23 @@ packages: resolve-from: 4.0.0 dev: false - /imurmurhash/0.1.4: + /imurmurhash@0.1.4: resolution: {integrity: sha1-khi5srkoojixPcT7a21XbyMUU+o=} engines: {node: '>=0.8.19'} dev: false - /inflight/1.0.6: + /inflight@1.0.6: resolution: {integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=} dependencies: once: 1.4.0 wrappy: 1.0.2 dev: false - /inherits/2.0.4: + /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} dev: false - /internal-slot/1.0.3: + /internal-slot@1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} engines: {node: '>= 0.4'} dependencies: @@ -1385,20 +1405,20 @@ packages: side-channel: 1.0.4 dev: false - /is-bigint/1.0.4: + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: has-bigints: 1.0.1 dev: false - /is-binary-path/2.1.0: + /is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 dev: false - /is-boolean-object/1.1.2: + /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: @@ -1406,74 +1426,74 @@ packages: has-tostringtag: 1.0.0 dev: false - /is-buffer/2.0.5: + /is-buffer@2.0.5: resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} engines: {node: '>=4'} dev: false - /is-callable/1.2.4: + /is-callable@1.2.4: resolution: {integrity: sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==} engines: {node: '>= 0.4'} dev: false - /is-core-module/2.8.1: + /is-core-module@2.8.1: resolution: {integrity: sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==} dependencies: has: 1.0.3 dev: false - /is-date-object/1.0.5: + /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: false - /is-extglob/2.1.1: + /is-extglob@2.1.1: resolution: {integrity: sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=} engines: {node: '>=0.10.0'} dev: false - /is-fullwidth-code-point/3.0.0: + /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} dev: false - /is-glob/4.0.3: + /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 dev: false - /is-interactive/2.0.0: + /is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} dev: false - /is-negative-zero/2.0.2: + /is-negative-zero@2.0.2: resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} engines: {node: '>= 0.4'} dev: false - /is-number-object/1.0.6: + /is-number-object@1.0.6: resolution: {integrity: sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: false - /is-number/7.0.0: + /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} dev: false - /is-plain-obj/2.1.0: + /is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} dev: false - /is-regex/1.1.4: + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: @@ -1481,45 +1501,45 @@ packages: has-tostringtag: 1.0.0 dev: false - /is-shared-array-buffer/1.0.1: + /is-shared-array-buffer@1.0.1: resolution: {integrity: sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==} dev: false - /is-string/1.0.7: + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: has-tostringtag: 1.0.0 dev: false - /is-symbol/1.0.4: + /is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.2 dev: false - /is-unicode-supported/0.1.0: + /is-unicode-supported@0.1.0: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} dev: false - /is-unicode-supported/1.2.0: + /is-unicode-supported@1.2.0: resolution: {integrity: sha512-wH+U77omcRzevfIG8dDhTS0V9zZyweakfD01FULl97+0EHiJTTZtJqxPSkIIo/SDPv/i07k/C9jAPY+jwLLeUQ==} engines: {node: '>=12'} dev: false - /is-weakref/1.0.2: + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: call-bind: 1.0.2 dev: false - /isexe/2.0.0: + /isexe@2.0.0: resolution: {integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=} dev: false - /jest-diff/27.5.1: + /jest-diff@27.5.1: resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1529,12 +1549,12 @@ packages: pretty-format: 27.5.1 dev: false - /jest-get-type/27.5.1: + /jest-get-type@27.5.1: resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dev: false - /jest-matcher-utils/27.5.1: + /jest-matcher-utils@27.5.1: resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1544,7 +1564,7 @@ packages: pretty-format: 27.5.1 dev: false - /jest-message-util/27.5.1: + /jest-message-util@27.5.1: resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1559,7 +1579,7 @@ packages: stack-utils: 2.0.5 dev: false - /jest-mock/27.5.1: + /jest-mock@27.5.1: resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1567,7 +1587,7 @@ packages: '@types/node': 18.0.1 dev: false - /jest-util/27.5.1: + /jest-util@27.5.1: resolution: {integrity: sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1579,51 +1599,51 @@ packages: picomatch: 2.3.1 dev: false - /js-sha3/0.8.0: + /js-sha3@0.8.0: resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} dev: false - /js-tokens/4.0.0: + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} dev: false - /js-yaml/4.1.0: + /js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true dependencies: argparse: 2.0.1 dev: false - /json-schema-traverse/0.4.1: + /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} dev: false - /json-schema-traverse/1.0.0: + /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: false - /json-stable-stringify-without-jsonify/1.0.1: + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=} dev: false - /json5/1.0.1: + /json5@1.0.1: resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} hasBin: true dependencies: minimist: 1.2.5 dev: false - /kleur/3.0.3: + /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} dev: false - /level-supports/4.0.1: + /level-supports@4.0.1: resolution: {integrity: sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==} engines: {node: '>=12'} dev: false - /level-transcoder/1.0.1: + /level-transcoder@1.0.1: resolution: {integrity: sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==} engines: {node: '>=12'} dependencies: @@ -1631,7 +1651,7 @@ packages: module-error: 1.0.2 dev: false - /level/8.0.0: + /level@8.0.0: resolution: {integrity: sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==} engines: {node: '>=12'} dependencies: @@ -1639,7 +1659,7 @@ packages: classic-level: 1.2.0 dev: false - /levn/0.4.1: + /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} dependencies: @@ -1647,7 +1667,7 @@ packages: type-check: 0.4.0 dev: false - /locate-path/2.0.0: + /locate-path@2.0.0: resolution: {integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=} engines: {node: '>=4'} dependencies: @@ -1655,26 +1675,26 @@ packages: path-exists: 3.0.0 dev: false - /locate-path/6.0.0: + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} dependencies: p-locate: 5.0.0 dev: false - /lodash.merge/4.6.2: + /lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: false - /lodash.truncate/4.4.2: + /lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} dev: false - /lodash/4.17.21: + /lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: false - /log-symbols/4.1.0: + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} dependencies: @@ -1682,7 +1702,7 @@ packages: is-unicode-supported: 0.1.0 dev: false - /log-symbols/5.1.0: + /log-symbols@5.1.0: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} engines: {node: '>=12'} dependencies: @@ -1690,17 +1710,17 @@ packages: is-unicode-supported: 1.2.0 dev: false - /long/4.0.0: + /long@4.0.0: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} dev: false - /loupe/2.3.4: + /loupe@2.3.4: resolution: {integrity: sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==} dependencies: get-func-name: 2.0.0 dev: false - /micromatch/4.0.5: + /micromatch@4.0.5: resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} engines: {node: '>=8.6'} dependencies: @@ -1708,40 +1728,40 @@ packages: picomatch: 2.3.1 dev: false - /mime-db/1.51.0: + /mime-db@1.51.0: resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} engines: {node: '>= 0.6'} dev: false - /mime-types/2.1.34: + /mime-types@2.1.34: resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.51.0 dev: false - /mimic-fn/2.1.0: + /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} dev: false - /minimatch/3.0.4: + /minimatch@3.0.4: resolution: {integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==} dependencies: brace-expansion: 1.1.11 dev: false - /minimatch/3.1.2: + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 dev: false - /minimist/1.2.5: + /minimist@1.2.5: resolution: {integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==} dev: false - /mocha/9.2.1: + /mocha@9.2.1: resolution: {integrity: sha512-T7uscqjJVS46Pq1XDXyo9Uvey9gd3huT/DD9cYBb4K2Xc/vbKRPUWK067bxDQRK0yIz6Jxk73IrnimvASzBNAQ==} engines: {node: '>= 12.0.0'} hasBin: true @@ -1750,7 +1770,7 @@ packages: ansi-colors: 4.1.1 browser-stdout: 1.3.1 chokidar: 3.5.3 - debug: 4.3.3_supports-color@8.1.1 + debug: 4.3.3(supports-color@8.1.1) diff: 5.0.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -1772,38 +1792,38 @@ packages: yargs-unparser: 2.0.0 dev: false - /module-error/1.0.2: + /module-error@1.0.2: resolution: {integrity: sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==} engines: {node: '>=10'} dev: false - /ms/2.0.0: + /ms@2.0.0: resolution: {integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=} dev: false - /ms/2.1.2: + /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} dev: false - /ms/2.1.3: + /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} dev: false - /nanoid/3.2.0: + /nanoid@3.2.0: resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: false - /napi-macros/2.0.0: + /napi-macros@2.0.0: resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} dev: false - /natural-compare/1.4.0: + /natural-compare@1.4.0: resolution: {integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=} dev: false - /node-fetch/2.6.7: + /node-fetch@2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} peerDependencies: @@ -1815,36 +1835,36 @@ packages: whatwg-url: 5.0.0 dev: false - /node-forge/0.10.0: + /node-forge@0.10.0: resolution: {integrity: sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==} engines: {node: '>= 6.0.0'} dev: false - /node-forge/0.8.5: + /node-forge@0.8.5: resolution: {integrity: sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==} engines: {node: '>= 4.5.0'} dev: false - /node-gyp-build/4.4.0: + /node-gyp-build@4.4.0: resolution: {integrity: sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==} hasBin: true dev: false - /normalize-path/3.0.0: + /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} dev: false - /object-inspect/1.12.0: + /object-inspect@1.12.0: resolution: {integrity: sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==} dev: false - /object-keys/1.1.1: + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} dev: false - /object.assign/4.1.2: + /object.assign@4.1.2: resolution: {integrity: sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==} engines: {node: '>= 0.4'} dependencies: @@ -1854,7 +1874,7 @@ packages: object-keys: 1.1.1 dev: false - /object.entries/1.1.5: + /object.entries@1.1.5: resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} engines: {node: '>= 0.4'} dependencies: @@ -1863,7 +1883,7 @@ packages: es-abstract: 1.19.1 dev: false - /object.values/1.1.5: + /object.values@1.1.5: resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} engines: {node: '>= 0.4'} dependencies: @@ -1872,20 +1892,20 @@ packages: es-abstract: 1.19.1 dev: false - /once/1.4.0: + /once@1.4.0: resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=} dependencies: wrappy: 1.0.2 dev: false - /onetime/5.1.2: + /onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 dev: false - /optionator/0.9.1: + /optionator@0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} dependencies: @@ -1897,7 +1917,7 @@ packages: word-wrap: 1.2.3 dev: false - /ora/6.1.0: + /ora@6.1.0: resolution: {integrity: sha512-CxEP6845hLK+NHFWZ+LplGO4zfw4QSfxTlqMfvlJ988GoiUeZDMzCvqsZkFHv69sPICmJH1MDxZoQFOKXerAVw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: @@ -1912,85 +1932,85 @@ packages: wcwidth: 1.0.1 dev: false - /p-limit/1.3.0: + /p-limit@1.3.0: resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} engines: {node: '>=4'} dependencies: p-try: 1.0.0 dev: false - /p-limit/3.1.0: + /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 dev: false - /p-locate/2.0.0: + /p-locate@2.0.0: resolution: {integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=} engines: {node: '>=4'} dependencies: p-limit: 1.3.0 dev: false - /p-locate/5.0.0: + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} dependencies: p-limit: 3.1.0 dev: false - /p-try/1.0.0: + /p-try@1.0.0: resolution: {integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=} engines: {node: '>=4'} dev: false - /parent-module/1.0.1: + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} dependencies: callsites: 3.1.0 dev: false - /path-exists/3.0.0: + /path-exists@3.0.0: resolution: {integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=} engines: {node: '>=4'} dev: false - /path-exists/4.0.0: + /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} dev: false - /path-is-absolute/1.0.1: + /path-is-absolute@1.0.1: resolution: {integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=} engines: {node: '>=0.10.0'} dev: false - /path-key/3.1.1: + /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} dev: false - /path-parse/1.0.7: + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: false - /pathval/1.1.1: + /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: false - /picomatch/2.3.1: + /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} dev: false - /prelude-ls/1.2.1: + /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} dev: false - /pretty-format/27.5.1: + /pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: @@ -1999,7 +2019,7 @@ packages: react-is: 17.0.2 dev: false - /prompts/2.4.2: + /prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} dependencies: @@ -2007,7 +2027,7 @@ packages: sisteransi: 1.0.5 dev: false - /protobufjs/6.11.2: + /protobufjs@6.11.2: resolution: {integrity: sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==} hasBin: true requiresBuild: true @@ -2027,26 +2047,26 @@ packages: long: 4.0.0 dev: false - /punycode/2.1.1: + /punycode@2.1.1: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} dev: false - /queue-microtask/1.2.3: + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: false - /randombytes/2.1.0: + /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 dev: false - /react-is/17.0.2: + /react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} dev: false - /readable-stream/3.6.0: + /readable-stream@3.6.0: resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} engines: {node: '>= 6'} dependencies: @@ -2055,34 +2075,34 @@ packages: util-deprecate: 1.0.2 dev: false - /readdirp/3.6.0: + /readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 dev: false - /regexpp/3.2.0: + /regexpp@3.2.0: resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} engines: {node: '>=8'} dev: false - /require-directory/2.1.1: + /require-directory@2.1.1: resolution: {integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=} engines: {node: '>=0.10.0'} dev: false - /require-from-string/2.0.2: + /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} dev: false - /resolve-from/4.0.0: + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} dev: false - /resolve/1.22.0: + /resolve@1.22.0: resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} hasBin: true dependencies: @@ -2091,7 +2111,7 @@ packages: supports-preserve-symlinks-flag: 1.0.0 dev: false - /restore-cursor/4.0.0: + /restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: @@ -2099,54 +2119,54 @@ packages: signal-exit: 3.0.7 dev: false - /rimraf/3.0.2: + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true dependencies: glob: 7.2.0 dev: false - /run-parallel-limit/1.1.0: + /run-parallel-limit@1.1.0: resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==} dependencies: queue-microtask: 1.2.3 dev: false - /rxjs/6.6.7: + /rxjs@6.6.7: resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} engines: {npm: '>=2.0.0'} dependencies: tslib: 1.14.1 dev: false - /safe-buffer/5.2.1: + /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: false - /semver/6.3.0: + /semver@6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true dev: false - /serialize-javascript/6.0.0: + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: randombytes: 2.1.0 dev: false - /shebang-command/2.0.0: + /shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 dev: false - /shebang-regex/3.0.0: + /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} dev: false - /side-channel/1.0.4: + /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.2 @@ -2154,20 +2174,20 @@ packages: object-inspect: 1.12.0 dev: false - /signal-exit/3.0.7: + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} dev: false - /sisteransi/1.0.5: + /sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} dev: false - /slash/3.0.0: + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} dev: false - /slice-ansi/4.0.0: + /slice-ansi@4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} dependencies: @@ -2176,18 +2196,18 @@ packages: is-fullwidth-code-point: 3.0.0 dev: false - /spawn-command/0.0.2-1: + /spawn-command@0.0.2-1: resolution: {integrity: sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=} dev: false - /stack-utils/2.0.5: + /stack-utils@2.0.5: resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} engines: {node: '>=10'} dependencies: escape-string-regexp: 2.0.0 dev: false - /string-width/4.2.3: + /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} dependencies: @@ -2196,77 +2216,77 @@ packages: strip-ansi: 6.0.1 dev: false - /string.prototype.trimend/1.0.4: + /string.prototype.trimend@1.0.4: resolution: {integrity: sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 dev: false - /string.prototype.trimstart/1.0.4: + /string.prototype.trimstart@1.0.4: resolution: {integrity: sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==} dependencies: call-bind: 1.0.2 define-properties: 1.1.3 dev: false - /string_decoder/1.3.0: + /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 dev: false - /strip-ansi/6.0.1: + /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 dev: false - /strip-ansi/7.0.1: + /strip-ansi@7.0.1: resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} engines: {node: '>=12'} dependencies: ansi-regex: 6.0.1 dev: false - /strip-bom/3.0.0: + /strip-bom@3.0.0: resolution: {integrity: sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=} engines: {node: '>=4'} dev: false - /strip-json-comments/3.1.1: + /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: false - /supports-color/5.5.0: + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} dependencies: has-flag: 3.0.0 dev: false - /supports-color/7.2.0: + /supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} dependencies: has-flag: 4.0.0 dev: false - /supports-color/8.1.1: + /supports-color@8.1.1: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} dependencies: has-flag: 4.0.0 dev: false - /supports-preserve-symlinks-flag/1.0.0: + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} dev: false - /table/6.8.0: + /table@6.8.0: resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} engines: {node: '>=10.0.0'} dependencies: @@ -2277,27 +2297,27 @@ packages: strip-ansi: 6.0.1 dev: false - /text-table/0.2.0: + /text-table@0.2.0: resolution: {integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=} dev: false - /to-regex-range/5.0.1: + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 dev: false - /tr46/0.0.3: + /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false - /tree-kill/1.2.2: + /tree-kill@1.2.2: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true dev: false - /tsconfig-paths/3.12.0: + /tsconfig-paths@3.12.0: resolution: {integrity: sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==} dependencies: '@types/json5': 0.0.29 @@ -2306,32 +2326,32 @@ packages: strip-bom: 3.0.0 dev: false - /tslib/1.14.1: + /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} dev: false - /type-check/0.4.0: + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 dev: false - /type-detect/4.0.8: + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} dev: false - /type-fest/0.20.2: + /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} dev: false - /typed-ts-events/1.2.1: + /typed-ts-events@1.2.1: resolution: {integrity: sha512-+Fy9cqWA/Kv1QX0k6m5ZflGcG2jQSZQGr+jLGXYUM22yihhkHs243LEXvY4cs54lAVyj5gokm0TbgkmL4qDsTg==} dev: false - /unbox-primitive/1.0.1: + /unbox-primitive@1.0.1: resolution: {integrity: sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==} dependencies: function-bind: 1.1.1 @@ -2340,38 +2360,38 @@ packages: which-boxed-primitive: 1.0.2 dev: false - /uri-js/4.4.1: + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.1.1 dev: false - /util-deprecate/1.0.2: + /util-deprecate@1.0.2: resolution: {integrity: sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=} dev: false - /v8-compile-cache/2.3.0: + /v8-compile-cache@2.3.0: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} dev: false - /wcwidth/1.0.1: + /wcwidth@1.0.1: resolution: {integrity: sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=} dependencies: defaults: 1.0.3 dev: false - /webidl-conversions/3.0.1: + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false - /whatwg-url/5.0.0: + /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 dev: false - /which-boxed-primitive/1.0.2: + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: is-bigint: 1.0.4 @@ -2381,7 +2401,7 @@ packages: is-symbol: 1.0.4 dev: false - /which/2.0.2: + /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true @@ -2389,16 +2409,16 @@ packages: isexe: 2.0.0 dev: false - /word-wrap/1.2.3: + /word-wrap@1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} dev: false - /workerpool/6.2.0: + /workerpool@6.2.0: resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} dev: false - /wrap-ansi/7.0.0: + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} dependencies: @@ -2407,21 +2427,21 @@ packages: strip-ansi: 6.0.1 dev: false - /wrappy/1.0.2: + /wrappy@1.0.2: resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=} dev: false - /y18n/5.0.8: + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} dev: false - /yargs-parser/20.2.4: + /yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} dev: false - /yargs-unparser/2.0.0: + /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} engines: {node: '>=10'} dependencies: @@ -2431,7 +2451,7 @@ packages: is-plain-obj: 2.1.0 dev: false - /yargs/16.2.0: + /yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} dependencies: @@ -2444,7 +2464,7 @@ packages: yargs-parser: 20.2.4 dev: false - /yocto-queue/0.1.0: + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: false diff --git a/test/utils/utils.mjs b/test/utils/utils.mjs index 7da45605..195b6475 100644 --- a/test/utils/utils.mjs +++ b/test/utils/utils.mjs @@ -9,6 +9,30 @@ const apiBase = process.env.API_NODE_URL; const chainId = 'R'; const api = create(apiBase); +export const compileScriptFromFile = async ( + path, + transform = null, + libraries = {}, +) => { + let transformFunc = transform; + if (!transform) transformFunc = (x) => x; + const estimatorVersion = undefined; + const compact = false; + const removeUnused = false; + const compilation = ride.compile( + transformFunc(await readFile(path, { encoding: 'utf-8' })), + estimatorVersion, + compact, + removeUnused, + libraries, + ); + if (compilation.error) { + throw new Error(compilation.error); + } + + return compilation.result; +}; + /** * @param {string} path * @param {string} account @@ -17,9 +41,10 @@ const api = create(apiBase); export const setScriptFromFile = async ( path, account, - transform = (content) => content, + transform = null, + libraries = {}, ) => { - const { base64, size } = ride.compile(transform(await readFile(path, { encoding: 'utf-8' }))).result; + const { base64, size } = await compileScriptFromFile(path, transform, libraries); const waveletsPerKilobyte = 1e5; const bitsInByte = 1024; const min = 1000000; From 011c74949b79c85a6aab5de8be7bc2fc1d17da79 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:00:27 +0500 Subject: [PATCH 23/41] successfull request --- test/components/grid_trading/request.spec.mjs | 126 +++++++++++++++++- 1 file changed, 120 insertions(+), 6 deletions(-) diff --git a/test/components/grid_trading/request.spec.mjs b/test/components/grid_trading/request.spec.mjs index 842264a5..74fef743 100644 --- a/test/components/grid_trading/request.spec.mjs +++ b/test/components/grid_trading/request.spec.mjs @@ -1,8 +1,10 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { invokeScript } from '@waves/waves-transactions'; -import { base64Encode } from '@waves/ts-lib-crypto'; -import { chainId, broadcastAndWait } from '../../utils/api.mjs'; +import { data, invokeScript, transfer } from '@waves/waves-transactions'; +import { + base58Decode, base58Encode, base64Encode, sha256, +} from '@waves/ts-lib-crypto'; +import { chainId, broadcastAndWait, baseSeed } from '../../utils/api.mjs'; import { setup } from './_setup.mjs'; chai.use(chaiAsPromised); @@ -20,20 +22,132 @@ describe(`[${process.pid}] grid_trading: request`, () => { } = await setup()); }); + it('1 payment is required', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [], + chainId, + }, accounts.user1.seed))).to.be.rejectedWith('1 payment is required'); + }); + + it('invalid asset', async () => { + await broadcastAndWait(transfer({ + recipient: accounts.user1.address, + assetId: assetId1, + amount: 1e8, + }, baseSeed)); + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: assetId1, amount: rewardAmount }, + ], + chainId, + }, accounts.user1.seed))).to.be.rejectedWith('invalid asset'); + }); + + it('invalid amount', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount - 1 }, + ], + chainId, + }, accounts.user1.seed))).to.be.rejectedWith('pair is not allowed'); + }); + it('pair is not allowed', async () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { function: 'request', args: [ - { type: 'binary', value: base64Encode(base58Decode(assetId1)) }, - { type: 'binary', value: base64Encode(base58Decode(assetId2)) }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.user1.seed))).to.be.rejectedWith('pair is not allowed'); + }); + + it('successfully create request', async () => { + await broadcastAndWait(data({ + data: [ + { key: `%s%s%s__${assetId1}__${assetId2}__pairAllowed`, type: 'boolean', value: true }, + ], + chainId, + }, accounts.factory.seed)).catch(({ message }) => { throw new Error(message); }); + + const { stateChanges } = await broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, ], }, payment: [ { assetId: null, amount: rewardAmount }, ], chainId, - }, accounts.factory.seed))).to.be.rejectedWith('pair is not allowed'); + }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); + + // let accountId = sha256(i.caller.bytes + amountAssetId + priceAssetId).toBase58String() + const accountId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); + + const accountStatusEmpty = 0; + + const expected = [ + { + key: `%s%s__${accountId}__status`, + type: 'integer', + value: accountStatusEmpty, + }, + { + key: `%s%s__${accountId}__ownerPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.user1.publicKey))}`, + }, + { + key: `%s%s__${accountId}__amountAssetId`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(assetId1))}`, + }, + { + key: `%s%s__${accountId}__priceAssetId`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(assetId2))}`, + }, + ]; + + expect(stateChanges.data).to.deep.equal(expected); }); }); From 4641b1053b19a727958fb9825be9d7a85eb216e6 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:52:14 +0500 Subject: [PATCH 24/41] test: account already exists --- test/components/grid_trading/request.spec.mjs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/components/grid_trading/request.spec.mjs b/test/components/grid_trading/request.spec.mjs index 74fef743..b23db092 100644 --- a/test/components/grid_trading/request.spec.mjs +++ b/test/components/grid_trading/request.spec.mjs @@ -150,4 +150,21 @@ describe(`[${process.pid}] grid_trading: request`, () => { expect(stateChanges.data).to.deep.equal(expected); }); + + it('account already exists', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.user1.seed))).to.be.rejectedWith('account already exists'); + }); }); From 460440ccad6c8b0acc8095993725d72790d7d9d9 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 10 Oct 2023 19:56:46 +0500 Subject: [PATCH 25/41] test refactor --- test/components/grid_trading/_setup.mjs | 1 + .../grid_trading/{request.spec.mjs => factory_request.spec.mjs} | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) rename test/components/grid_trading/{request.spec.mjs => factory_request.spec.mjs} (98%) diff --git a/test/components/grid_trading/_setup.mjs b/test/components/grid_trading/_setup.mjs index 671e3b90..6dacee45 100644 --- a/test/components/grid_trading/_setup.mjs +++ b/test/components/grid_trading/_setup.mjs @@ -32,6 +32,7 @@ export const setup = async ({ 'factory', 'service', 'bot', + 'creator', 'user1', 'user2', 'account1', diff --git a/test/components/grid_trading/request.spec.mjs b/test/components/grid_trading/factory_request.spec.mjs similarity index 98% rename from test/components/grid_trading/request.spec.mjs rename to test/components/grid_trading/factory_request.spec.mjs index b23db092..dc8bcd1a 100644 --- a/test/components/grid_trading/request.spec.mjs +++ b/test/components/grid_trading/factory_request.spec.mjs @@ -10,7 +10,7 @@ import { setup } from './_setup.mjs'; chai.use(chaiAsPromised); const { expect } = chai; -describe(`[${process.pid}] grid_trading: request`, () => { +describe(`[${process.pid}] grid_trading: factory request`, () => { let accounts; let rewardAmount; let assetId1; From 06107c5701f683c6e70234a5e8c8847ef8bebe20 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Wed, 11 Oct 2023 19:27:07 +0500 Subject: [PATCH 26/41] test account init --- .../grid_trading/account_init.spec.mjs | 181 ++++++++++++++++++ test/utils/utils.mjs | 17 +- 2 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 test/components/grid_trading/account_init.spec.mjs diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs new file mode 100644 index 00000000..ab6b153d --- /dev/null +++ b/test/components/grid_trading/account_init.spec.mjs @@ -0,0 +1,181 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { data, invokeScript, setScript } from '@waves/waves-transactions'; +import { + base58Decode, base58Encode, base64Encode, sha256, +} from '@waves/ts-lib-crypto'; +import { + chainId, broadcastAndWait, api, +} from '../../utils/api.mjs'; +import { setup } from './_setup.mjs'; +import { compileScript } from '../../utils/utils.mjs'; + +chai.use(chaiAsPromised); +const { expect } = chai; + +describe(`[${process.pid}] grid_trading: account init`, () => { + let accounts; + let rewardAmount; + let assetId1; + let assetId2; + let accountId; + + before(async () => { + ({ + accounts, rewardAmount, assetId1, assetId2, + } = await setup()); + + await broadcastAndWait(data({ + data: [ + { key: `%s%s%s__${assetId1}__${assetId2}__pairAllowed`, type: 'boolean', value: true }, + ], + chainId, + }, accounts.factory.seed)).catch(({ message }) => { throw new Error(message); }); + + await broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); + + accountId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); + }); + + it('account is not found', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'complete', + args: [ + { type: 'string', value: base58Encode([1, 2, 3]) }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + }, accounts.account1.seed))).to.be.rejectedWith('account is not found'); + }); + + it('no script', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'complete', + args: [ + { type: 'string', value: accountId }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + }, accounts.account1.seed))).to.be.rejectedWith('invalid script'); + }); + + it('invalid script', async () => { + const script = `{-# STDLIB_VERSION 7 #-} + {-# CONTENT_TYPE DAPP #-} + {-# SCRIPT_TYPE ACCOUNT #-} + `; + + await broadcastAndWait(setScript({ + script: `base64:${compileScript(script).base64}`, + chainId, + }, accounts.account1.seed)); + + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'complete', + args: [ + { type: 'string', value: accountId }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + }, accounts.account1.seed))).to.be.rejectedWith('invalid script'); + }); + + it('successfull init account', async () => { + const kAccountScript = '%s__accountScript'; + const script = await api.addresses.fetchDataKey( + accounts.factory.address, + kAccountScript, + ).then(({ value }) => value); + + await broadcastAndWait(setScript({ + script, + chainId, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + + const creatorBalanceBefore = await api.addresses.fetchBalance( + accounts.creator.address, + ).then(({ balance }) => balance); + + await broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'init', + args: [ + { type: 'string', value: accountId }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + additionalFee: 4e5, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + + const accountState = await api.addresses.data(accounts.account1.address); + expect(accountState).to.deep.equal([ + { + key: '%s__factoryPublicKey', + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}`, + }, + ]); + + const creatorBalanceAfter = await api.addresses.fetchBalance( + accounts.creator.address, + ).then(({ balance }) => balance); + expect(creatorBalanceAfter - creatorBalanceBefore).to.equal(rewardAmount); + + const factoryState = await api.addresses.data(accounts.factory.address); + expect(factoryState).to.deep.include.members([ + { + key: `%s%s__${accountId}__status`, + type: 'integer', + value: 1, + }, + { + key: `%s%s__${accountId}__creatorPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}`, + }, + { + key: `%s%s__${accountId}__accountIdToAccountPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.account1.publicKey))}`, + }, + { + key: `%s%s__${accounts.account1.address}__accountAddressToAccountId`, + type: 'string', + value: accountId, + }, + ]); + }); +}); diff --git a/test/utils/utils.mjs b/test/utils/utils.mjs index 195b6475..cff8f54a 100644 --- a/test/utils/utils.mjs +++ b/test/utils/utils.mjs @@ -9,8 +9,8 @@ const apiBase = process.env.API_NODE_URL; const chainId = 'R'; const api = create(apiBase); -export const compileScriptFromFile = async ( - path, +export const compileScript = ( + script, transform = null, libraries = {}, ) => { @@ -20,7 +20,7 @@ export const compileScriptFromFile = async ( const compact = false; const removeUnused = false; const compilation = ride.compile( - transformFunc(await readFile(path, { encoding: 'utf-8' })), + transformFunc(script), estimatorVersion, compact, removeUnused, @@ -33,6 +33,17 @@ export const compileScriptFromFile = async ( return compilation.result; }; +export const compileScriptFromFile = async ( + path, + transform = null, + libraries = {}, +) => { + const script = await readFile(path, { encoding: 'utf-8' }); + const result = compileScript(script, transform, libraries); + + return result; +}; + /** * @param {string} path * @param {string} account From 28a6c8113ef440e546fde484e91121c1371e7123 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 12 Oct 2023 16:51:15 +0500 Subject: [PATCH 27/41] account exists test --- .../grid_trading/account_init.spec.mjs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs index ab6b153d..ecf3579b 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/account_init.spec.mjs @@ -154,12 +154,13 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ).then(({ balance }) => balance); expect(creatorBalanceAfter - creatorBalanceBefore).to.equal(rewardAmount); + const accountStatusReady = 1; const factoryState = await api.addresses.data(accounts.factory.address); expect(factoryState).to.deep.include.members([ { key: `%s%s__${accountId}__status`, type: 'integer', - value: 1, + value: accountStatusReady, }, { key: `%s%s__${accountId}__creatorPublicKey`, @@ -178,4 +179,19 @@ describe(`[${process.pid}] grid_trading: account init`, () => { }, ]); }); + + it('account is already exists', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'complete', + args: [ + { type: 'string', value: accountId }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + }, accounts.account1.seed))).to.be.rejectedWith('account is already exists'); + }); }); From 7dd9b81b45a6ef5a0ede4c55c82c882114a3866b Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:42:34 +0500 Subject: [PATCH 28/41] account init test fix --- .../grid_trading/account_init.spec.mjs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs index ecf3579b..9369dcf8 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/account_init.spec.mjs @@ -80,6 +80,7 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ], }, payment: [], + additionalFee: 4e5, chainId, }, accounts.account1.seed))).to.be.rejectedWith('invalid script'); }); @@ -105,6 +106,7 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ], }, payment: [], + additionalFee: 4e5, chainId, }, accounts.account1.seed))).to.be.rejectedWith('invalid script'); }); @@ -180,18 +182,31 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ]); }); - it('account is already exists', async () => { + it('successfull init account', async () => { + const kAccountScript = '%s__accountScript'; + const script = await api.addresses.fetchDataKey( + accounts.factory.address, + kAccountScript, + ).then(({ value }) => value); + + await broadcastAndWait(setScript({ + script, + chainId, + }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); + expect(broadcastAndWait(invokeScript({ - dApp: accounts.factory.address, + dApp: accounts.account2.address, call: { - function: 'complete', + function: 'init', args: [ { type: 'string', value: accountId }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], }, payment: [], chainId, - }, accounts.account1.seed))).to.be.rejectedWith('account is already exists'); + additionalFee: 4e5, + }, accounts.account2.seed))).to.be.rejectedWith('account is already exists'); }); }); From b22e8af24c04b98933d0260d6e489f868df5b097 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:45:02 +0500 Subject: [PATCH 29/41] account init test refactor --- .../grid_trading/account_init.spec.mjs | 25 ++++++++----------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs index 9369dcf8..737e3693 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/account_init.spec.mjs @@ -19,6 +19,7 @@ describe(`[${process.pid}] grid_trading: account init`, () => { let assetId1; let assetId2; let accountId; + let validScript; before(async () => { ({ @@ -52,6 +53,12 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ...base58Decode(assetId1), ...base58Decode(assetId2), ])); + + const kAccountScript = '%s__accountScript'; + validScript = await api.addresses.fetchDataKey( + accounts.factory.address, + kAccountScript, + ).then(({ value }) => value); }); it('account is not found', async () => { @@ -112,14 +119,8 @@ describe(`[${process.pid}] grid_trading: account init`, () => { }); it('successfull init account', async () => { - const kAccountScript = '%s__accountScript'; - const script = await api.addresses.fetchDataKey( - accounts.factory.address, - kAccountScript, - ).then(({ value }) => value); - await broadcastAndWait(setScript({ - script, + script: validScript, chainId, }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); @@ -182,15 +183,9 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ]); }); - it('successfull init account', async () => { - const kAccountScript = '%s__accountScript'; - const script = await api.addresses.fetchDataKey( - accounts.factory.address, - kAccountScript, - ).then(({ value }) => value); - + it('account exists', async () => { await broadcastAndWait(setScript({ - script, + script: validScript, chainId, }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); From 16a8292c9a80a3756f24d8accfca37f696c1db88 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:47:13 +0500 Subject: [PATCH 30/41] common lib fix --- ride/common.lib.ride | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ride/common.lib.ride b/ride/common.lib.ride index 6747f664..afff2c91 100644 --- a/ride/common.lib.ride +++ b/ride/common.lib.ride @@ -6,7 +6,7 @@ let chainIdT = base16'54' let chainIdW = base16'57' func mustAddress(i: Invocation, address: Address) = { - i.caller == address || throw() + i.caller == address || throw("permission denied") } func mustThis(i: Invocation) = { From cf877afe9f3ba08ba6fd1fbd79103f8837cc32db Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:49:36 +0500 Subject: [PATCH 31/41] account fix + permission test --- ride/grid_trading_account.ride | 2 +- .../grid_trading/account_call.spec.mjs | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 test/components/grid_trading/account_call.spec.mjs diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index d0158034..7f2463fd 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -12,7 +12,7 @@ func kAccountAddressToAccountId(accountAddress: Address) = { ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) } func kAccountOwner(accountId: String) = { - ["%s%s", accountId, "owner"].makeString(separator) + ["%s%s", accountId, "ownerPublicKey"].makeString(separator) } let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs new file mode 100644 index 00000000..e28c2324 --- /dev/null +++ b/test/components/grid_trading/account_call.spec.mjs @@ -0,0 +1,102 @@ +import chai from 'chai'; +import chaiAsPromised from 'chai-as-promised'; +import { data, invokeScript, setScript } from '@waves/waves-transactions'; +import { + base58Decode, base58Encode, base64Encode, sha256, +} from '@waves/ts-lib-crypto'; +import { + chainId, broadcastAndWait, api, +} from '../../utils/api.mjs'; +import { setup } from './_setup.mjs'; + +chai.use(chaiAsPromised); +const { expect } = chai; + +describe(`[${process.pid}] grid_trading: account call`, () => { + let accounts; + let rewardAmount; + let assetId1; + let assetId2; + let accountId; + + before(async () => { + ({ + accounts, rewardAmount, assetId1, assetId2, + } = await setup()); + + await broadcastAndWait(data({ + data: [ + { key: `%s%s%s__${assetId1}__${assetId2}__pairAllowed`, type: 'boolean', value: true }, + ], + chainId, + }, accounts.factory.seed)).catch(({ message }) => { throw new Error(message); }); + + await broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); + + accountId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); + + const kAccountScript = '%s__accountScript'; + const script = await api.addresses.fetchDataKey( + accounts.factory.address, + kAccountScript, + ).then(({ value }) => value); + + await broadcastAndWait(setScript({ + script, + chainId, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + + await broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'init', + args: [ + { type: 'string', value: accountId }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + additionalFee: 4e5, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + }); + + it('permission denied', async () => { + expect(broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'call', + args: [ + { type: 'string', value: 'setIntParam' }, + { + type: 'list', + value: [ + { type: 'string', value: 'test' }, + { type: 'string', value: '1' }, + ], + }, + ], + }, + payment: [], + chainId, + }, accounts.user2.seed))).to.be.rejectedWith('permission denied'); + }); +}); From cadfdfb50bae6be5f65678beb6f431c8c36a75b9 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Thu, 12 Oct 2023 18:02:16 +0500 Subject: [PATCH 32/41] account set int param --- .../grid_trading/account_call.spec.mjs | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs index e28c2324..cd45e2af 100644 --- a/test/components/grid_trading/account_call.spec.mjs +++ b/test/components/grid_trading/account_call.spec.mjs @@ -99,4 +99,40 @@ describe(`[${process.pid}] grid_trading: account call`, () => { chainId, }, accounts.user2.seed))).to.be.rejectedWith('permission denied'); }); + + it('successfully set int param', async () => { + const targetFunction = 'setIntParam'; + const entryKey = 'test'; + const entryValue = 1; + const { stateChanges } = await broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'call', + args: [ + { type: 'string', value: targetFunction }, + { + type: 'list', + value: [ + { type: 'string', value: entryKey }, + { type: 'string', value: entryValue.toString() }, + ], + }, + ], + }, + payment: [], + chainId, + }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); + + expect(stateChanges.invokes[0].dApp).to.equal(accounts.service.address); + expect(stateChanges.invokes[0].call.function).to.equal(targetFunction); + + const accountState = await api.addresses.data(accounts.account1.address); + expect(accountState).to.deep.include.members([ + { + key: entryKey, + type: 'integer', + value: entryValue, + }, + ]); + }); }); From 779f40c665637915a3a2f5e465f3e2b07d28945e Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:45:58 +0500 Subject: [PATCH 33/41] change service test --- test/components/grid_trading/_setup.mjs | 1 + .../grid_trading/account_call.spec.mjs | 44 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/test/components/grid_trading/_setup.mjs b/test/components/grid_trading/_setup.mjs index 6dacee45..08627ec6 100644 --- a/test/components/grid_trading/_setup.mjs +++ b/test/components/grid_trading/_setup.mjs @@ -31,6 +31,7 @@ export const setup = async ({ const names = [ 'factory', 'service', + 'serviceNew', 'bot', 'creator', 'user1', diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs index cd45e2af..33e2d566 100644 --- a/test/components/grid_trading/account_call.spec.mjs +++ b/test/components/grid_trading/account_call.spec.mjs @@ -8,6 +8,7 @@ import { chainId, broadcastAndWait, api, } from '../../utils/api.mjs'; import { setup } from './_setup.mjs'; +import { compileScript } from '../../utils/utils.mjs'; chai.use(chaiAsPromised); const { expect } = chai; @@ -135,4 +136,47 @@ describe(`[${process.pid}] grid_trading: account call`, () => { }, ]); }); + + it('change service address', async () => { + const errorMessage = 'forbidden'; + const script = `{-# STDLIB_VERSION 7 #-} + {-# CONTENT_TYPE DAPP #-} + {-# SCRIPT_TYPE ACCOUNT #-} + + @Callable(i) + func setIntParam(args: List[String]) = throw("${errorMessage}") + `; + + await broadcastAndWait(setScript({ + script: `base64:${compileScript(script).base64}`, + chainId, + }, accounts.serviceNew.seed)); + + const kServicePublicKey = '%s__servicePublicKey'; + await broadcastAndWait(data({ + data: [ + { key: kServicePublicKey, type: 'binary', value: base64Encode(base58Decode(accounts.serviceNew.publicKey)) }, + ], + chainId, + }, accounts.factory.seed)); + + expect(broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'call', + args: [ + { type: 'string', value: 'setIntParam' }, + { + type: 'list', + value: [ + { type: 'string', value: 'test' }, + { type: 'string', value: '1' }, + ], + }, + ], + }, + payment: [], + chainId, + }, accounts.user1.seed))).to.be.rejectedWith(errorMessage); + }); }); From 5d04893f475d3147898da2da33311ee85500d0bb Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 13 Oct 2023 16:56:36 +0500 Subject: [PATCH 34/41] service test with 2 accounts --- .../grid_trading/account_call.spec.mjs | 105 +++++++++++++++++- 1 file changed, 101 insertions(+), 4 deletions(-) diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs index 33e2d566..ac4bad6c 100644 --- a/test/components/grid_trading/account_call.spec.mjs +++ b/test/components/grid_trading/account_call.spec.mjs @@ -18,7 +18,8 @@ describe(`[${process.pid}] grid_trading: account call`, () => { let rewardAmount; let assetId1; let assetId2; - let accountId; + let accountId1; + let accountId2; before(async () => { ({ @@ -47,12 +48,33 @@ describe(`[${process.pid}] grid_trading: account call`, () => { chainId, }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); - accountId = base58Encode(sha256([ + await broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.user2.seed)).catch(({ message }) => { throw new Error(message); }); + + accountId1 = base58Encode(sha256([ ...base58Decode(accounts.user1.address), ...base58Decode(assetId1), ...base58Decode(assetId2), ])); + accountId2 = base58Encode(sha256([ + ...base58Decode(accounts.user2.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); + const kAccountScript = '%s__accountScript'; const script = await api.addresses.fetchDataKey( accounts.factory.address, @@ -64,12 +86,17 @@ describe(`[${process.pid}] grid_trading: account call`, () => { chainId, }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + await broadcastAndWait(setScript({ + script, + chainId, + }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); + await broadcastAndWait(invokeScript({ dApp: accounts.account1.address, call: { function: 'init', args: [ - { type: 'string', value: accountId }, + { type: 'string', value: accountId1 }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], @@ -78,6 +105,21 @@ describe(`[${process.pid}] grid_trading: account call`, () => { chainId, additionalFee: 4e5, }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + + await broadcastAndWait(invokeScript({ + dApp: accounts.account2.address, + call: { + function: 'init', + args: [ + { type: 'string', value: accountId2 }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + additionalFee: 4e5, + }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); }); it('permission denied', async () => { @@ -101,7 +143,7 @@ describe(`[${process.pid}] grid_trading: account call`, () => { }, accounts.user2.seed))).to.be.rejectedWith('permission denied'); }); - it('successfully set int param', async () => { + it('successfully set int param on account 1', async () => { const targetFunction = 'setIntParam'; const entryKey = 'test'; const entryValue = 1; @@ -137,6 +179,42 @@ describe(`[${process.pid}] grid_trading: account call`, () => { ]); }); + it('successfully set int param on account 2', async () => { + const targetFunction = 'setIntParam'; + const entryKey = 'test'; + const entryValue = 1; + const { stateChanges } = await broadcastAndWait(invokeScript({ + dApp: accounts.account2.address, + call: { + function: 'call', + args: [ + { type: 'string', value: targetFunction }, + { + type: 'list', + value: [ + { type: 'string', value: entryKey }, + { type: 'string', value: entryValue.toString() }, + ], + }, + ], + }, + payment: [], + chainId, + }, accounts.user2.seed)).catch(({ message }) => { throw new Error(message); }); + + expect(stateChanges.invokes[0].dApp).to.equal(accounts.service.address); + expect(stateChanges.invokes[0].call.function).to.equal(targetFunction); + + const accountState = await api.addresses.data(accounts.account2.address); + expect(accountState).to.deep.include.members([ + { + key: entryKey, + type: 'integer', + value: entryValue, + }, + ]); + }); + it('change service address', async () => { const errorMessage = 'forbidden'; const script = `{-# STDLIB_VERSION 7 #-} @@ -178,5 +256,24 @@ describe(`[${process.pid}] grid_trading: account call`, () => { payment: [], chainId, }, accounts.user1.seed))).to.be.rejectedWith(errorMessage); + + expect(broadcastAndWait(invokeScript({ + dApp: accounts.account2.address, + call: { + function: 'call', + args: [ + { type: 'string', value: 'setIntParam' }, + { + type: 'list', + value: [ + { type: 'string', value: 'test' }, + { type: 'string', value: '1' }, + ], + }, + ], + }, + payment: [], + chainId, + }, accounts.user2.seed))).to.be.rejectedWith(errorMessage); }); }); From efa34c112a097d19605ce2d7b1d7381b0cd31b6b Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 13 Oct 2023 18:32:58 +0500 Subject: [PATCH 35/41] test refactor --- .../grid_trading/account_call.spec.mjs | 146 +++++++++--------- .../grid_trading/account_init.spec.mjs | 24 +-- 2 files changed, 87 insertions(+), 83 deletions(-) diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs index ac4bad6c..5d18505e 100644 --- a/test/components/grid_trading/account_call.spec.mjs +++ b/test/components/grid_trading/account_call.spec.mjs @@ -26,43 +26,6 @@ describe(`[${process.pid}] grid_trading: account call`, () => { accounts, rewardAmount, assetId1, assetId2, } = await setup()); - await broadcastAndWait(data({ - data: [ - { key: `%s%s%s__${assetId1}__${assetId2}__pairAllowed`, type: 'boolean', value: true }, - ], - chainId, - }, accounts.factory.seed)).catch(({ message }) => { throw new Error(message); }); - - await broadcastAndWait(invokeScript({ - dApp: accounts.factory.address, - call: { - function: 'request', - args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, - ], - }, - payment: [ - { assetId: null, amount: rewardAmount }, - ], - chainId, - }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); - - await broadcastAndWait(invokeScript({ - dApp: accounts.factory.address, - call: { - function: 'request', - args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, - ], - }, - payment: [ - { assetId: null, amount: rewardAmount }, - ], - chainId, - }, accounts.user2.seed)).catch(({ message }) => { throw new Error(message); }); - accountId1 = base58Encode(sha256([ ...base58Decode(accounts.user1.address), ...base58Decode(assetId1), @@ -81,45 +44,86 @@ describe(`[${process.pid}] grid_trading: account call`, () => { kAccountScript, ).then(({ value }) => value); - await broadcastAndWait(setScript({ - script, - chainId, - }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); - - await broadcastAndWait(setScript({ - script, + await broadcastAndWait(data({ + data: [ + { key: `%s%s%s__${assetId1}__${assetId2}__pairAllowed`, type: 'boolean', value: true }, + ], chainId, - }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); + }, accounts.factory.seed)).catch(({ message }) => { throw new Error(message); }); - await broadcastAndWait(invokeScript({ - dApp: accounts.account1.address, - call: { - function: 'init', - args: [ - { type: 'string', value: accountId1 }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + await Promise.all([ + broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, ], - }, - payment: [], - chainId, - additionalFee: 4e5, - }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + chainId, + }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }), - await broadcastAndWait(invokeScript({ - dApp: accounts.account2.address, - call: { - function: 'init', - args: [ - { type: 'string', value: accountId2 }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'request', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, ], - }, - payment: [], - chainId, - additionalFee: 4e5, - }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); + chainId, + }, accounts.user2.seed)).catch(({ message }) => { throw new Error(message); }), + + broadcastAndWait(setScript({ + script, + chainId, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }), + + broadcastAndWait(setScript({ + script, + chainId, + }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }), + ]); + + await Promise.all([ + broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'init', + args: [ + { type: 'string', value: accountId1 }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + additionalFee: 4e5, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }), + + broadcastAndWait(invokeScript({ + dApp: accounts.account2.address, + call: { + function: 'init', + args: [ + { type: 'string', value: accountId2 }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + additionalFee: 4e5, + }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }), + ]); }); it('permission denied', async () => { diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs index 737e3693..1369c998 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/account_init.spec.mjs @@ -26,6 +26,18 @@ describe(`[${process.pid}] grid_trading: account init`, () => { accounts, rewardAmount, assetId1, assetId2, } = await setup()); + accountId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); + + const kAccountScript = '%s__accountScript'; + validScript = await api.addresses.fetchDataKey( + accounts.factory.address, + kAccountScript, + ).then(({ value }) => value); + await broadcastAndWait(data({ data: [ { key: `%s%s%s__${assetId1}__${assetId2}__pairAllowed`, type: 'boolean', value: true }, @@ -47,18 +59,6 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ], chainId, }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); - - accountId = base58Encode(sha256([ - ...base58Decode(accounts.user1.address), - ...base58Decode(assetId1), - ...base58Decode(assetId2), - ])); - - const kAccountScript = '%s__accountScript'; - validScript = await api.addresses.fetchDataKey( - accounts.factory.address, - kAccountScript, - ).then(({ value }) => value); }); it('account is not found', async () => { From b595986cbdd057344e647b49c30f3c64dd8b9281 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:47:02 +0500 Subject: [PATCH 36/41] asset id string + tests --- ride/grid_trading_factory.ride | 26 ++++++++--- .../grid_trading/account_call.spec.mjs | 30 ++++++------- .../grid_trading/account_init.spec.mjs | 16 +++---- .../grid_trading/factory_request.spec.mjs | 45 +++++++++---------- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/ride/grid_trading_factory.ride b/ride/grid_trading_factory.ride index d9748a25..3986a84c 100644 --- a/ride/grid_trading_factory.ride +++ b/ride/grid_trading_factory.ride @@ -3,6 +3,16 @@ {-# SCRIPT_TYPE ACCOUNT #-} {-# IMPORT common.lib.ride #-} +let wavesString = "WAVES" + +func parseAssetId(input: String) = { + if (input == wavesString) then unit else input.fromBase58String() +} + +func assetIdToString(input: ByteVector|Unit) = { + if (input == unit) then wavesString else input.value().toBase58String() +} + let kServicePublicKey = "%s__servicePublicKey" let kBotPublicKey = "%s__botPublicKey" @@ -46,10 +56,10 @@ func kAccountAddressToAccountId(accountAddress: Address) = { ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) } -func kPairAllowed(amountAssetId: ByteVector, priceAssetId: ByteVector) = { - ["%s%s%s", amountAssetId.toBase58String(), priceAssetId.toBase58String(), "pairAllowed"].makeString(separator) +func kPairAllowed(amountAssetId: ByteVector|Unit, priceAssetId: ByteVector|Unit) = { + ["%s%s%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), "pairAllowed"].makeString(separator) } -func pairAllowed(amountAssetId: ByteVector, priceAssetId: ByteVector) = { +func pairAllowed(amountAssetId: ByteVector|Unit, priceAssetId: ByteVector|Unit) = { this.getBoolean( kPairAllowed(amountAssetId, priceAssetId) ).valueOrElse(false) @@ -79,8 +89,10 @@ func init( # called by user # additional fee in payment @Callable(i) -func request(amountAssetId: ByteVector, priceAssetId: ByteVector) = { - let accountId = sha256(i.caller.bytes + amountAssetId + priceAssetId).toBase58String() +func request(amountAssetIdStr: String, priceAssetIdStr: String) = { + let accountId = [i.caller.toString(), amountAssetIdStr, priceAssetIdStr].makeString(":") + let amountAssetId = parseAssetId(amountAssetIdStr) + let priceAssetId = parseAssetId(priceAssetIdStr) strict checks = [ i.payments.size() == 1 || throw("1 payment is required"), @@ -93,8 +105,8 @@ func request(amountAssetId: ByteVector, priceAssetId: ByteVector) = { ([ IntegerEntry(kAccountStatus(accountId), 0), BinaryEntry(kAccountOwnerPublicKey(accountId), i.callerPublicKey), - BinaryEntry(kAccountAmountAssetId(accountId), amountAssetId), - BinaryEntry(kAccountPriceAssetId(accountId), priceAssetId) + StringEntry(kAccountAmountAssetId(accountId), amountAssetIdStr), + StringEntry(kAccountPriceAssetId(accountId), priceAssetIdStr) ], unit) } diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs index 5d18505e..58589719 100644 --- a/test/components/grid_trading/account_call.spec.mjs +++ b/test/components/grid_trading/account_call.spec.mjs @@ -2,7 +2,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { data, invokeScript, setScript } from '@waves/waves-transactions'; import { - base58Decode, base58Encode, base64Encode, sha256, + base58Decode, base64Encode, } from '@waves/ts-lib-crypto'; import { chainId, broadcastAndWait, api, @@ -26,17 +26,17 @@ describe(`[${process.pid}] grid_trading: account call`, () => { accounts, rewardAmount, assetId1, assetId2, } = await setup()); - accountId1 = base58Encode(sha256([ - ...base58Decode(accounts.user1.address), - ...base58Decode(assetId1), - ...base58Decode(assetId2), - ])); + accountId1 = [ + accounts.user1.address, + assetId1, + assetId2, + ].join(':'); - accountId2 = base58Encode(sha256([ - ...base58Decode(accounts.user2.address), - ...base58Decode(assetId1), - ...base58Decode(assetId2), - ])); + accountId2 = [ + accounts.user2.address, + assetId1, + assetId2, + ].join(':'); const kAccountScript = '%s__accountScript'; const script = await api.addresses.fetchDataKey( @@ -57,8 +57,8 @@ describe(`[${process.pid}] grid_trading: account call`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ @@ -72,8 +72,8 @@ describe(`[${process.pid}] grid_trading: account call`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs index 1369c998..ed8e7b81 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/account_init.spec.mjs @@ -2,7 +2,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { data, invokeScript, setScript } from '@waves/waves-transactions'; import { - base58Decode, base58Encode, base64Encode, sha256, + base58Decode, base58Encode, base64Encode, } from '@waves/ts-lib-crypto'; import { chainId, broadcastAndWait, api, @@ -26,11 +26,11 @@ describe(`[${process.pid}] grid_trading: account init`, () => { accounts, rewardAmount, assetId1, assetId2, } = await setup()); - accountId = base58Encode(sha256([ - ...base58Decode(accounts.user1.address), - ...base58Decode(assetId1), - ...base58Decode(assetId2), - ])); + accountId = [ + accounts.user1.address, + assetId1, + assetId2, + ].join(':'); const kAccountScript = '%s__accountScript'; validScript = await api.addresses.fetchDataKey( @@ -50,8 +50,8 @@ describe(`[${process.pid}] grid_trading: account init`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ diff --git a/test/components/grid_trading/factory_request.spec.mjs b/test/components/grid_trading/factory_request.spec.mjs index dc8bcd1a..72482667 100644 --- a/test/components/grid_trading/factory_request.spec.mjs +++ b/test/components/grid_trading/factory_request.spec.mjs @@ -2,7 +2,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { data, invokeScript, transfer } from '@waves/waves-transactions'; import { - base58Decode, base58Encode, base64Encode, sha256, + base58Decode, base64Encode, } from '@waves/ts-lib-crypto'; import { chainId, broadcastAndWait, baseSeed } from '../../utils/api.mjs'; import { setup } from './_setup.mjs'; @@ -28,8 +28,8 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [], @@ -48,8 +48,8 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ @@ -65,8 +65,8 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ @@ -82,8 +82,8 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ @@ -106,8 +106,8 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ @@ -116,12 +116,11 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { chainId, }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); - // let accountId = sha256(i.caller.bytes + amountAssetId + priceAssetId).toBase58String() - const accountId = base58Encode(sha256([ - ...base58Decode(accounts.user1.address), - ...base58Decode(assetId1), - ...base58Decode(assetId2), - ])); + const accountId = [ + accounts.user1.address, + assetId1, + assetId2, + ].join(':'); const accountStatusEmpty = 0; @@ -138,13 +137,13 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { }, { key: `%s%s__${accountId}__amountAssetId`, - type: 'binary', - value: `base64:${base64Encode(base58Decode(assetId1))}`, + type: 'string', + value: assetId1, }, { key: `%s%s__${accountId}__priceAssetId`, - type: 'binary', - value: `base64:${base64Encode(base58Decode(assetId2))}`, + type: 'string', + value: assetId2, }, ]; @@ -157,8 +156,8 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { call: { function: 'request', args: [ - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId1))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(assetId2))}` }, + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, ], }, payment: [ From dce52d54dd4e875c89aef44da74c47e8711e942f Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:16:58 +0500 Subject: [PATCH 37/41] new flow --- ride/grid_trading_account.ride | 4 +- ride/grid_trading_factory.ride | 119 ++++++++++++------ .../grid_trading/account_call.spec.mjs | 20 +-- .../grid_trading/account_init.spec.mjs | 99 ++------------- ...c.mjs => factory_request_account.spec.mjs} | 31 +++-- 5 files changed, 115 insertions(+), 158 deletions(-) rename test/components/grid_trading/{factory_request.spec.mjs => factory_request_account.spec.mjs} (86%) diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index 7f2463fd..43aba6be 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -47,13 +47,13 @@ func transferWaves(recipientBytes: ByteVector, amount: Int) = if (i.mustService()) then ([ScriptTransfer(Address(recipientBytes), amount, unit)], amount) else ([], unit) @Callable(i) -func init(requestId: String, factoryPublicKey: ByteVector, creatorPublicKey: ByteVector) = { +func init(factoryPublicKey: ByteVector, creatorPublicKey: ByteVector) = { strict checkCaller = i.mustThis() # throws if accounts is not ok strict completeRequest = addressFromPublicKey( factoryPublicKey - ).invoke("complete", [requestId, creatorPublicKey], []) + ).invoke("addAccount", [creatorPublicKey], []) ([ BinaryEntry(kFactoryPublicKey, factoryPublicKey) diff --git a/ride/grid_trading_factory.ride b/ride/grid_trading_factory.ride index 3986a84c..baa4d3bb 100644 --- a/ride/grid_trading_factory.ride +++ b/ride/grid_trading_factory.ride @@ -4,6 +4,7 @@ {-# IMPORT common.lib.ride #-} let wavesString = "WAVES" +let queueItemSize = 32 func parseAssetId(input: String) = { if (input == wavesString) then unit else input.fromBase58String() @@ -26,36 +27,41 @@ func rewardAmount() = this.getInteger( kRewardAmount ).valueOrErrorMessage("reward amount is not set") -let ACCOUNT_STATUS_EMPTY = 0 -let ACCOUNT_STATUS_READY = 1 -func kAccountStatus(accountId: String) = { - ["%s%s", accountId, "status"].makeString(separator) -} -func accountStatus(accountId: String) = { - this.getInteger( - kAccountStatus(accountId) - ).valueOrErrorMessage("account is not found") +let REQUEST_STATUS_EMPTY = 0 +let REQUEST_STATUS_READY = 1 +func kRequestStatus(requestId: ByteVector) = { + ["%s%s", requestId.toBase58String(), "status"].makeString(separator) } -func kAccountCreatorPublicKey(accountId: String) = { - ["%s%s", accountId, "creatorPublicKey"].makeString(separator) +func kAccountCreatorPublicKey(accountAddress: Address) = { + ["%s%s", accountAddress.toString(), "creatorPublicKey"].makeString(separator) } -func kAccountOwnerPublicKey(accountId: String) = { - ["%s%s", accountId, "ownerPublicKey"].makeString(separator) +func kRequestOwnerPublicKey(requestId: ByteVector) = { + ["%s%s", requestId.toBase58String(), "ownerPublicKey"].makeString(separator) } -func kAccountAmountAssetId(accountId: String) = { - ["%s%s", accountId, "amountAssetId"].makeString(separator) +func kRequestAmountAssetId(requestId: ByteVector) = { + ["%s%s", requestId.toBase58String(), "amountAssetId"].makeString(separator) } -func kAccountPriceAssetId(accountId: String) = { - ["%s%s", accountId, "priceAssetId"].makeString(separator) +func kRequestPriceAssetId(requestId: ByteVector) = { + ["%s%s", requestId.toBase58String(), "priceAssetId"].makeString(separator) } -func kAccountIdToAccountPublicKey(accountId: String) = { - ["%s%s", accountId, "accountIdToAccountPublicKey"].makeString(separator) +func kRequestIdToAccountPublicKey(requestId: ByteVector) = { + ["%s%s", requestId.toBase58String(), "requestIdToAccountPublicKey"].makeString(separator) } -func kAccountAddressToAccountId(accountAddress: Address) = { +func kAccountAddressToRequestId(accountAddress: Address) = { ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) } +func kRequestsQueue() = { + ["%s", "requestsQueue"].makeString(separator) +} +func requestsQueue() = this.getBinary(kRequestsQueue()).valueOrElse(base58'') + +func kAccountsQueue() = { + ["%s", "accountsQueue"].makeString(separator) +} +func accountsQueue() = this.getBinary(kAccountsQueue()).valueOrElse(base58'') + func kPairAllowed(amountAssetId: ByteVector|Unit, priceAssetId: ByteVector|Unit) = { ["%s%s%s", assetIdToString(amountAssetId), assetIdToString(priceAssetId), "pairAllowed"].makeString(separator) } @@ -89,8 +95,8 @@ func init( # called by user # additional fee in payment @Callable(i) -func request(amountAssetIdStr: String, priceAssetIdStr: String) = { - let accountId = [i.caller.toString(), amountAssetIdStr, priceAssetIdStr].makeString(":") +func requestAccount(amountAssetIdStr: String, priceAssetIdStr: String) = { + let requestId = sha256(i.caller.bytes + amountAssetIdStr.fromBase58String() + priceAssetIdStr.fromBase58String()) let amountAssetId = parseAssetId(amountAssetIdStr) let priceAssetId = parseAssetId(priceAssetIdStr) @@ -99,39 +105,76 @@ func request(amountAssetIdStr: String, priceAssetIdStr: String) = { i.payments[0].assetId == unit || throw("invalid asset"), i.payments[0].amount == rewardAmount() || throw("invalid amount"), pairAllowed(amountAssetId, priceAssetId) || throw("pair is not allowed"), - this.getInteger(kAccountStatus(accountId)) == unit || throw("account already exists") + this.getInteger(kRequestStatus(requestId)) == unit || throw("account already exists") ] - ([ - IntegerEntry(kAccountStatus(accountId), 0), - BinaryEntry(kAccountOwnerPublicKey(accountId), i.callerPublicKey), - StringEntry(kAccountAmountAssetId(accountId), amountAssetIdStr), - StringEntry(kAccountPriceAssetId(accountId), priceAssetIdStr) + # add request to queue or match with account immediately + + let actions = if (accountsQueue().size() == 0) then { # if the accounts queue is empty + # then add request to requests queue + [ + IntegerEntry(kRequestStatus(requestId), REQUEST_STATUS_EMPTY), + BinaryEntry(kRequestsQueue(), requestsQueue() + requestId) + ] + } else { # if the accounts queue is not empty + # then fullfill request + let accountPublicKey = accountsQueue().take(queueItemSize) + let accountAddress = addressFromPublicKey(accountPublicKey) + let creatorAddress = addressFromPublicKey( + this.getBinary( + kAccountCreatorPublicKey(accountAddress) + ).valueOrErrorMessage("invalid creator public key") + ) + [ + BinaryEntry(kAccountsQueue(), accountsQueue().drop(queueItemSize)), + IntegerEntry(kRequestStatus(requestId), REQUEST_STATUS_READY), + BinaryEntry(kRequestIdToAccountPublicKey(requestId), accountPublicKey), + StringEntry(kAccountAddressToRequestId(accountAddress), requestId.toBase58String()), + ScriptTransfer(creatorAddress, rewardAmount(), unit) + ] + } + + (actions ++ [ + BinaryEntry(kRequestOwnerPublicKey(requestId), i.callerPublicKey), + StringEntry(kRequestAmountAssetId(requestId), amountAssetIdStr), + StringEntry(kRequestPriceAssetId(requestId), priceAssetIdStr) ], unit) } # called by account script # additional fee is sent to recipient @Callable(i) -func complete(accountId: String, creatorPublicKey: ByteVector) = { +func addAccount(creatorPublicKey: ByteVector) = { let accountPublicKey = i.callerPublicKey let accountAddress = i.caller + let creatorAddress = addressFromPublicKey(creatorPublicKey) strict checks = [ - accountStatus(accountId) == ACCOUNT_STATUS_EMPTY || throw("account is already exists"), + this.getBinary(kAccountCreatorPublicKey(accountAddress)) == unit || throw("account is already exists"), match scriptHash(accountAddress) { case b: ByteVector => b == blake2b256_32Kb(accountScript()) case _ => false } || throw("invalid script") ] - let creatorAddress = addressFromPublicKey(creatorPublicKey) - - ([ - IntegerEntry(kAccountStatus(accountId), ACCOUNT_STATUS_READY), - BinaryEntry(kAccountCreatorPublicKey(accountId), creatorPublicKey), - BinaryEntry(kAccountIdToAccountPublicKey(accountId), accountPublicKey), - StringEntry(kAccountAddressToAccountId(accountAddress), accountId), - ScriptTransfer(creatorAddress, rewardAmount(), unit) + let actions = if (requestsQueue().size() == 0) then { # if the requests queue is empty + # then add account to accounts queue + [ + BinaryEntry(kAccountsQueue(), accountsQueue() + accountPublicKey) + ] + } else { # if the requests queue is not empty + # then fullfill next request + let requestId = requestsQueue().take(queueItemSize) + [ + BinaryEntry(kRequestsQueue(), requestsQueue().drop(queueItemSize)), + IntegerEntry(kRequestStatus(requestId), REQUEST_STATUS_READY), + BinaryEntry(kRequestIdToAccountPublicKey(requestId), accountPublicKey), + StringEntry(kAccountAddressToRequestId(accountAddress), requestId.toBase58String()), + ScriptTransfer(creatorAddress, rewardAmount(), unit) + ] + } + + (actions ++ [ + BinaryEntry(kAccountCreatorPublicKey(accountAddress), creatorPublicKey) ], unit) } \ No newline at end of file diff --git a/test/components/grid_trading/account_call.spec.mjs b/test/components/grid_trading/account_call.spec.mjs index 58589719..c0a0dc09 100644 --- a/test/components/grid_trading/account_call.spec.mjs +++ b/test/components/grid_trading/account_call.spec.mjs @@ -18,26 +18,12 @@ describe(`[${process.pid}] grid_trading: account call`, () => { let rewardAmount; let assetId1; let assetId2; - let accountId1; - let accountId2; before(async () => { ({ accounts, rewardAmount, assetId1, assetId2, } = await setup()); - accountId1 = [ - accounts.user1.address, - assetId1, - assetId2, - ].join(':'); - - accountId2 = [ - accounts.user2.address, - assetId1, - assetId2, - ].join(':'); - const kAccountScript = '%s__accountScript'; const script = await api.addresses.fetchDataKey( accounts.factory.address, @@ -55,7 +41,7 @@ describe(`[${process.pid}] grid_trading: account call`, () => { broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -70,7 +56,7 @@ describe(`[${process.pid}] grid_trading: account call`, () => { broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -99,7 +85,6 @@ describe(`[${process.pid}] grid_trading: account call`, () => { call: { function: 'init', args: [ - { type: 'string', value: accountId1 }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], @@ -114,7 +99,6 @@ describe(`[${process.pid}] grid_trading: account call`, () => { call: { function: 'init', args: [ - { type: 'string', value: accountId2 }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/account_init.spec.mjs index ed8e7b81..d6df7128 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/account_init.spec.mjs @@ -15,7 +15,6 @@ const { expect } = chai; describe(`[${process.pid}] grid_trading: account init`, () => { let accounts; - let rewardAmount; let assetId1; let assetId2; let accountId; @@ -23,14 +22,14 @@ describe(`[${process.pid}] grid_trading: account init`, () => { before(async () => { ({ - accounts, rewardAmount, assetId1, assetId2, + accounts, assetId1, assetId2, } = await setup()); - accountId = [ - accounts.user1.address, - assetId1, - assetId2, - ].join(':'); + accountId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); const kAccountScript = '%s__accountScript'; validScript = await api.addresses.fetchDataKey( @@ -44,45 +43,14 @@ describe(`[${process.pid}] grid_trading: account init`, () => { ], chainId, }, accounts.factory.seed)).catch(({ message }) => { throw new Error(message); }); - - await broadcastAndWait(invokeScript({ - dApp: accounts.factory.address, - call: { - function: 'request', - args: [ - { type: 'string', value: assetId1 }, - { type: 'string', value: assetId2 }, - ], - }, - payment: [ - { assetId: null, amount: rewardAmount }, - ], - chainId, - }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); - }); - - it('account is not found', async () => { - expect(broadcastAndWait(invokeScript({ - dApp: accounts.factory.address, - call: { - function: 'complete', - args: [ - { type: 'string', value: base58Encode([1, 2, 3]) }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, - ], - }, - payment: [], - chainId, - }, accounts.account1.seed))).to.be.rejectedWith('account is not found'); }); it('no script', async () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'complete', + function: 'addAccount', args: [ - { type: 'string', value: accountId }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], }, @@ -106,7 +74,7 @@ describe(`[${process.pid}] grid_trading: account init`, () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'complete', + function: 'addAccount', args: [ { type: 'string', value: accountId }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, @@ -124,16 +92,11 @@ describe(`[${process.pid}] grid_trading: account init`, () => { chainId, }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); - const creatorBalanceBefore = await api.addresses.fetchBalance( - accounts.creator.address, - ).then(({ balance }) => balance); - await broadcastAndWait(invokeScript({ dApp: accounts.account1.address, call: { function: 'init', args: [ - { type: 'string', value: accountId }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], @@ -152,56 +115,18 @@ describe(`[${process.pid}] grid_trading: account init`, () => { }, ]); - const creatorBalanceAfter = await api.addresses.fetchBalance( - accounts.creator.address, - ).then(({ balance }) => balance); - expect(creatorBalanceAfter - creatorBalanceBefore).to.equal(rewardAmount); - - const accountStatusReady = 1; const factoryState = await api.addresses.data(accounts.factory.address); expect(factoryState).to.deep.include.members([ { - key: `%s%s__${accountId}__status`, - type: 'integer', - value: accountStatusReady, - }, - { - key: `%s%s__${accountId}__creatorPublicKey`, - type: 'binary', - value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}`, - }, - { - key: `%s%s__${accountId}__accountIdToAccountPublicKey`, + key: '%s__accountsQueue', type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.account1.publicKey))}`, }, { - key: `%s%s__${accounts.account1.address}__accountAddressToAccountId`, - type: 'string', - value: accountId, + key: `%s%s__${accounts.account1.address}__creatorPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}`, }, ]); }); - - it('account exists', async () => { - await broadcastAndWait(setScript({ - script: validScript, - chainId, - }, accounts.account2.seed)).catch(({ message }) => { throw new Error(message); }); - - expect(broadcastAndWait(invokeScript({ - dApp: accounts.account2.address, - call: { - function: 'init', - args: [ - { type: 'string', value: accountId }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, - { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, - ], - }, - payment: [], - chainId, - additionalFee: 4e5, - }, accounts.account2.seed))).to.be.rejectedWith('account is already exists'); - }); }); diff --git a/test/components/grid_trading/factory_request.spec.mjs b/test/components/grid_trading/factory_request_account.spec.mjs similarity index 86% rename from test/components/grid_trading/factory_request.spec.mjs rename to test/components/grid_trading/factory_request_account.spec.mjs index 72482667..a41dd796 100644 --- a/test/components/grid_trading/factory_request.spec.mjs +++ b/test/components/grid_trading/factory_request_account.spec.mjs @@ -2,7 +2,7 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { data, invokeScript, transfer } from '@waves/waves-transactions'; import { - base58Decode, base64Encode, + base58Decode, base64Encode, base58Encode, sha256, } from '@waves/ts-lib-crypto'; import { chainId, broadcastAndWait, baseSeed } from '../../utils/api.mjs'; import { setup } from './_setup.mjs'; @@ -10,7 +10,7 @@ import { setup } from './_setup.mjs'; chai.use(chaiAsPromised); const { expect } = chai; -describe(`[${process.pid}] grid_trading: factory request`, () => { +describe(`[${process.pid}] grid_trading: factory request account`, () => { let accounts; let rewardAmount; let assetId1; @@ -26,7 +26,7 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -46,7 +46,7 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -63,7 +63,7 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -80,7 +80,7 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -104,7 +104,7 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { const { stateChanges } = await broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, @@ -116,11 +116,11 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { chainId, }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); - const accountId = [ - accounts.user1.address, - assetId1, - assetId2, - ].join(':'); + const accountId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); const accountStatusEmpty = 0; @@ -130,6 +130,11 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { type: 'integer', value: accountStatusEmpty, }, + { + key: '%s__requestsQueue', + type: 'binary', + value: `base64:${base64Encode(base58Decode(accountId))}`, + }, { key: `%s%s__${accountId}__ownerPublicKey`, type: 'binary', @@ -154,7 +159,7 @@ describe(`[${process.pid}] grid_trading: factory request`, () => { expect(broadcastAndWait(invokeScript({ dApp: accounts.factory.address, call: { - function: 'request', + function: 'requestAccount', args: [ { type: 'string', value: assetId1 }, { type: 'string', value: assetId2 }, From 473e7d95f0fec1c65f46263c75806024112424a7 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Fri, 24 Nov 2023 19:01:02 +0500 Subject: [PATCH 38/41] fix contracts and tests --- ride/grid_trading_account.ride | 6 +- ride/grid_trading_factory.ride | 4 +- ....spec.mjs => factory_add_account.spec.mjs} | 65 ++++++++++++++++++- .../factory_request_account.spec.mjs | 2 +- 4 files changed, 68 insertions(+), 9 deletions(-) rename test/components/grid_trading/{account_init.spec.mjs => factory_add_account.spec.mjs} (68%) diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index 43aba6be..b3e6a696 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -8,8 +8,8 @@ let kServicePublicKey = "%s__servicePublicKey" let kOwnerPublicKey = "%s__ownerPublicKey" let kBotPublicKey = "%s__botPublicKey" -func kAccountAddressToAccountId(accountAddress: Address) = { - ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) +func kAccountAddressToRequestId(accountAddress: Address) = { + ["%s%s", accountAddress.toString(), "accountAddressToRequestId"].makeString(separator) } func kAccountOwner(accountId: String) = { ["%s%s", accountId, "ownerPublicKey"].makeString(separator) @@ -18,7 +18,7 @@ func kAccountOwner(accountId: String) = { let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue(kServicePublicKey)) -let accountId = factoryAddress.getStringValue(kAccountAddressToAccountId(this)) +let accountId = factoryAddress.getStringValue(kAccountAddressToRequestId(this)) let ownerPublicKey = factoryAddress.getBinaryValue(kAccountOwner(accountId)) let ownerAddress = addressFromPublicKey(ownerPublicKey) diff --git a/ride/grid_trading_factory.ride b/ride/grid_trading_factory.ride index baa4d3bb..f15d5187 100644 --- a/ride/grid_trading_factory.ride +++ b/ride/grid_trading_factory.ride @@ -49,7 +49,7 @@ func kRequestIdToAccountPublicKey(requestId: ByteVector) = { ["%s%s", requestId.toBase58String(), "requestIdToAccountPublicKey"].makeString(separator) } func kAccountAddressToRequestId(accountAddress: Address) = { - ["%s%s", accountAddress.toString(), "accountAddressToAccountId"].makeString(separator) + ["%s%s", accountAddress.toString(), "accountAddressToRequestId"].makeString(separator) } func kRequestsQueue() = { @@ -105,7 +105,7 @@ func requestAccount(amountAssetIdStr: String, priceAssetIdStr: String) = { i.payments[0].assetId == unit || throw("invalid asset"), i.payments[0].amount == rewardAmount() || throw("invalid amount"), pairAllowed(amountAssetId, priceAssetId) || throw("pair is not allowed"), - this.getInteger(kRequestStatus(requestId)) == unit || throw("account already exists") + this.getInteger(kRequestStatus(requestId)) == unit || throw("account is already exists") ] # add request to queue or match with account immediately diff --git a/test/components/grid_trading/account_init.spec.mjs b/test/components/grid_trading/factory_add_account.spec.mjs similarity index 68% rename from test/components/grid_trading/account_init.spec.mjs rename to test/components/grid_trading/factory_add_account.spec.mjs index d6df7128..1161cb62 100644 --- a/test/components/grid_trading/account_init.spec.mjs +++ b/test/components/grid_trading/factory_add_account.spec.mjs @@ -13,16 +13,17 @@ import { compileScript } from '../../utils/utils.mjs'; chai.use(chaiAsPromised); const { expect } = chai; -describe(`[${process.pid}] grid_trading: account init`, () => { +describe(`[${process.pid}] grid_trading: add account`, () => { let accounts; let assetId1; let assetId2; let accountId; let validScript; + let rewardAmount; before(async () => { ({ - accounts, assetId1, assetId2, + accounts, assetId1, assetId2, rewardAmount, } = await setup()); accountId = base58Encode(sha256([ @@ -76,7 +77,6 @@ describe(`[${process.pid}] grid_trading: account init`, () => { call: { function: 'addAccount', args: [ - { type: 'string', value: accountId }, { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, ], }, @@ -129,4 +129,63 @@ describe(`[${process.pid}] grid_trading: account init`, () => { }, ]); }); + + it('create request after account adding', async () => { + const { stateChanges } = await broadcastAndWait(invokeScript({ + dApp: accounts.factory.address, + call: { + function: 'requestAccount', + args: [ + { type: 'string', value: assetId1 }, + { type: 'string', value: assetId2 }, + ], + }, + payment: [ + { assetId: null, amount: rewardAmount }, + ], + chainId, + }, accounts.user1.seed)).catch(({ message }) => { throw new Error(message); }); + + const accountStatusReady = 1; + + const expected = [ + { + key: '%s__accountsQueue', + type: 'binary', + value: 'base64:', + }, + { + key: `%s%s__${accountId}__status`, + type: 'integer', + value: accountStatusReady, + }, + { + key: `%s%s__${accountId}__requestIdToAccountPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.account1.publicKey))}`, + }, + { + key: `%s%s__${accounts.account1.address}__accountAddressToRequestId`, + type: 'string', + value: accountId, + }, + { + key: `%s%s__${accountId}__ownerPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.user1.publicKey))}`, + }, + { + key: `%s%s__${accountId}__amountAssetId`, + type: 'string', + value: assetId1, + }, + { + key: `%s%s__${accountId}__priceAssetId`, + type: 'string', + value: assetId2, + }, + ]; + + expect(stateChanges.data).to.deep.equal(expected); + }); }); diff --git a/test/components/grid_trading/factory_request_account.spec.mjs b/test/components/grid_trading/factory_request_account.spec.mjs index a41dd796..30aa1cd4 100644 --- a/test/components/grid_trading/factory_request_account.spec.mjs +++ b/test/components/grid_trading/factory_request_account.spec.mjs @@ -169,6 +169,6 @@ describe(`[${process.pid}] grid_trading: factory request account`, () => { { assetId: null, amount: rewardAmount }, ], chainId, - }, accounts.user1.seed))).to.be.rejectedWith('account already exists'); + }, accounts.user1.seed))).to.be.rejectedWith('account is already exists'); }); }); From 9102a90ceb0527f93c4c9e5474a7766cf39db29b Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Mon, 27 Nov 2023 16:23:50 +0500 Subject: [PATCH 39/41] test: add account after request was created --- .../factory_request_account.spec.mjs | 79 ++++++++++++++++++- 1 file changed, 77 insertions(+), 2 deletions(-) diff --git a/test/components/grid_trading/factory_request_account.spec.mjs b/test/components/grid_trading/factory_request_account.spec.mjs index 30aa1cd4..5864054c 100644 --- a/test/components/grid_trading/factory_request_account.spec.mjs +++ b/test/components/grid_trading/factory_request_account.spec.mjs @@ -1,10 +1,14 @@ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; -import { data, invokeScript, transfer } from '@waves/waves-transactions'; +import { + data, invokeScript, setScript, transfer, +} from '@waves/waves-transactions'; import { base58Decode, base64Encode, base58Encode, sha256, } from '@waves/ts-lib-crypto'; -import { chainId, broadcastAndWait, baseSeed } from '../../utils/api.mjs'; +import { + chainId, broadcastAndWait, baseSeed, api, +} from '../../utils/api.mjs'; import { setup } from './_setup.mjs'; chai.use(chaiAsPromised); @@ -15,11 +19,25 @@ describe(`[${process.pid}] grid_trading: factory request account`, () => { let rewardAmount; let assetId1; let assetId2; + let validScript; + let requestId; before(async () => { ({ accounts, rewardAmount, assetId1, assetId2, } = await setup()); + + requestId = base58Encode(sha256([ + ...base58Decode(accounts.user1.address), + ...base58Decode(assetId1), + ...base58Decode(assetId2), + ])); + + const kAccountScript = '%s__accountScript'; + validScript = await api.addresses.fetchDataKey( + accounts.factory.address, + kAccountScript, + ).then(({ value }) => value); }); it('1 payment is required', async () => { @@ -171,4 +189,61 @@ describe(`[${process.pid}] grid_trading: factory request account`, () => { chainId, }, accounts.user1.seed))).to.be.rejectedWith('account is already exists'); }); + + it('add account after request was created', async () => { + await broadcastAndWait(setScript({ + script: validScript, + chainId, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + + const { stateChanges } = await broadcastAndWait(invokeScript({ + dApp: accounts.account1.address, + call: { + function: 'init', + args: [ + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.factory.publicKey))}` }, + { type: 'binary', value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}` }, + ], + }, + payment: [], + chainId, + additionalFee: 4e5, + }, accounts.account1.seed)).catch(({ message }) => { throw new Error(message); }); + + const accountStatusReady = 1; + expect(stateChanges.invokes[0].stateChanges.data).to.deep.equal([ + { + key: '%s__requestsQueue', + type: 'binary', + value: 'base64:', + }, + { + key: `%s%s__${requestId}__status`, + type: 'integer', + value: accountStatusReady, + }, + { + key: `%s%s__${requestId}__requestIdToAccountPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.account1.publicKey))}`, + }, + { + key: `%s%s__${accounts.account1.address}__accountAddressToRequestId`, + type: 'string', + value: requestId, + }, + { + key: `%s%s__${accounts.account1.address}__creatorPublicKey`, + type: 'binary', + value: `base64:${base64Encode(base58Decode(accounts.creator.publicKey))}`, + }, + ]); + expect(stateChanges.invokes[0].stateChanges.transfers).to.deep.equal([ + { + address: accounts.creator.address, + asset: null, + amount: rewardAmount, + }, + ]); + }); }); From 01f2f1b44fb1cebf13b7182d1b8d3489e5b4c243 Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Mon, 27 Nov 2023 19:23:09 +0500 Subject: [PATCH 40/41] fix --- ride/grid_trading_account.ride | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index b3e6a696..5856433c 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -11,15 +11,15 @@ let kBotPublicKey = "%s__botPublicKey" func kAccountAddressToRequestId(accountAddress: Address) = { ["%s%s", accountAddress.toString(), "accountAddressToRequestId"].makeString(separator) } -func kAccountOwner(accountId: String) = { - ["%s%s", accountId, "ownerPublicKey"].makeString(separator) +func kAccountOwner(requestId: String) = { + ["%s%s", requestId, "ownerPublicKey"].makeString(separator) } let factoryAddress = addressFromPublicKey(this.getBinaryValue(kFactoryPublicKey)) let serviceAddress = addressFromPublicKey(factoryAddress.getBinaryValue(kServicePublicKey)) -let accountId = factoryAddress.getStringValue(kAccountAddressToRequestId(this)) -let ownerPublicKey = factoryAddress.getBinaryValue(kAccountOwner(accountId)) +let requestId = factoryAddress.getStringValue(kAccountAddressToRequestId(this)) +let ownerPublicKey = factoryAddress.getBinaryValue(kAccountOwner(requestId)) let ownerAddress = addressFromPublicKey(ownerPublicKey) func mustService(i: Invocation) = { From c7b6ffa9364ceb9ef0b00e4e302027602a26262a Mon Sep 17 00:00:00 2001 From: Waves Rider <108881461+ridev6@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:21:54 +0500 Subject: [PATCH 41/41] fix removed common.lib.ride --- ride/grid_trading_account.ride | 15 ++++++++++++++- ride/grid_trading_factory.ride | 15 ++++++++++++++- ride/grid_trading_service.ride | 14 +++++++++++++- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/ride/grid_trading_account.ride b/ride/grid_trading_account.ride index 5856433c..1c69e56b 100644 --- a/ride/grid_trading_account.ride +++ b/ride/grid_trading_account.ride @@ -1,7 +1,20 @@ {-# STDLIB_VERSION 7 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} -{-# IMPORT common.lib.ride #-} + +let separator = "__" +let chainId = this.bytes.drop(1).take(1) +let chainIdT = base16'54' +let chainIdW = base16'57' + +func mustAddress(i: Invocation, address: Address) = { + i.caller == address || throw("permission denied") +} + +func mustThis(i: Invocation) = { + mustAddress(i, this) +} + let kFactoryPublicKey = "%s__factoryPublicKey" let kServicePublicKey = "%s__servicePublicKey" diff --git a/ride/grid_trading_factory.ride b/ride/grid_trading_factory.ride index f15d5187..bcb836dc 100644 --- a/ride/grid_trading_factory.ride +++ b/ride/grid_trading_factory.ride @@ -1,7 +1,20 @@ {-# STDLIB_VERSION 7 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} -{-# IMPORT common.lib.ride #-} + +let separator = "__" +let chainId = this.bytes.drop(1).take(1) +let chainIdT = base16'54' +let chainIdW = base16'57' + +func mustAddress(i: Invocation, address: Address) = { + i.caller == address || throw("permission denied") +} + +func mustThis(i: Invocation) = { + mustAddress(i, this) +} + let wavesString = "WAVES" let queueItemSize = 32 diff --git a/ride/grid_trading_service.ride b/ride/grid_trading_service.ride index 138c4104..88b3316e 100644 --- a/ride/grid_trading_service.ride +++ b/ride/grid_trading_service.ride @@ -1,7 +1,19 @@ {-# STDLIB_VERSION 7 #-} {-# CONTENT_TYPE DAPP #-} {-# SCRIPT_TYPE ACCOUNT #-} -{-# IMPORT common.lib.ride #-} + +let separator = "__" +let chainId = this.bytes.drop(1).take(1) +let chainIdT = base16'54' +let chainIdW = base16'57' + +func mustAddress(i: Invocation, address: Address) = { + i.caller == address || throw("permission denied") +} + +func mustThis(i: Invocation) = { + mustAddress(i, this) +} # withdraw from investment account to specified address @Callable(i)