diff --git a/Dockerfile.const b/Dockerfile.const index 61a75c212..c42854bbd 100644 --- a/Dockerfile.const +++ b/Dockerfile.const @@ -48,3 +48,4 @@ FROM scratch AS const-export COPY --from=const-build /scripts/.env.0x ethereum/.env COPY --from=const-build /scripts/.env.hex solana/.env COPY --from=const-build /scripts/.env.hex terra/tools/.env +COPY --from=const-build /scripts/.env.hex algorand/.env diff --git a/Dockerfile.teal b/Dockerfile.teal deleted file mode 100644 index a6df26666..000000000 --- a/Dockerfile.teal +++ /dev/null @@ -1,27 +0,0 @@ -# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 -FROM docker.io/fedora:34 AS teal-build - -# Support additional root CAs -COPY README.md cert.pem* /certs/ -# Fedora -RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/pki/tls/certs/ca-bundle.crt; fi - -RUN dnf -y install python3-pip - -COPY staging/algorand/teal /teal - -# Install pyTEAL dependencies -COPY third_party/algorand/Pipfile.lock Pipfile.lock -COPY third_party/algorand/Pipfile Pipfile - -RUN pip install pipenv -RUN pipenv install - -# Regenerate TEAL assembly -RUN pipenv run python3 /teal/wormhole/pyteal/vaa-processor.py vaa-processor-approval.teal vaa-processor-clear.teal -RUN pipenv run python3 /teal/wormhole/pyteal/vaa-verify.py 0 vaa-verify.teal - -FROM scratch AS teal-export -COPY --from=teal-build /vaa-processor-approval.teal third_party/algorand/teal/ -COPY --from=teal-build /vaa-processor-clear.teal third_party/algorand/teal/ -COPY --from=teal-build /vaa-verify.teal third_party/algorand/teal/ diff --git a/Tiltfile b/Tiltfile index a20e2ea30..69b5ae2e3 100644 --- a/Tiltfile +++ b/Tiltfile @@ -113,17 +113,6 @@ local_resource( trigger_mode = trigger_mode, ) -if algorand: - local_resource( - name = "teal-gen", - deps = ["staging/algorand/teal"], - cmd = "tilt docker build -- --target teal-export -f Dockerfile.teal -o type=local,dest=. .", - env = {"DOCKER_BUILDKIT": "1"}, - labels = ["algorand"], - allow_parallel = True, - trigger_mode = trigger_mode, - ) - # wasm if solana: @@ -443,27 +432,6 @@ if ci_tests: trigger_mode = trigger_mode, ) -# algorand -if algorand: - k8s_yaml_with_ns("devnet/algorand.yaml") - - docker_build( - ref = "algorand", - context = "third_party/algorand", - dockerfile = "third_party/algorand/Dockerfile", - ) - - k8s_resource( - "algorand", - resource_deps = ["teal-gen"], - port_forwards = [ - port_forward(4001, name = "Algorand RPC [:4001]", host = webHost), - port_forward(4002, name = "Algorand KMD [:4002]", host = webHost), - ], - labels = ["algorand"], - trigger_mode = trigger_mode, - ) - # e2e if e2e: k8s_yaml_with_ns("devnet/e2e.yaml") @@ -581,3 +549,38 @@ k8s_resource( labels = ["terra"], trigger_mode = trigger_mode, ) + +if algorand: + k8s_yaml_with_ns("devnet/algorand-devnet.yaml") + + docker_build( + ref = "algorand-algod", + context = "algorand/sandbox-algorand", + dockerfile = "algorand/sandbox-algorand/images/algod/Dockerfile" + ) + + docker_build( + ref = "algorand-indexer", + context = "algorand/sandbox-algorand", + dockerfile = "algorand/sandbox-algorand/images/indexer/Dockerfile" + ) + + docker_build( + ref = "algorand-contracts", + context = "algorand", + dockerfile = "algorand/Dockerfile", + ignore = ["algorand/test/*.*"] + ) + + k8s_resource( + "algorand", + port_forwards = [ + port_forward(4001, name = "Algod [:4001]", host = webHost), + port_forward(4002, name = "KMD [:4002]", host = webHost), + port_forward(8980, name = "Indexer [:8980]", host = webHost), + ], + resource_deps = ["const-gen"], + labels = ["algorand"], + trigger_mode = trigger_mode, + ) + diff --git a/algorand/.gitignore b/algorand/.gitignore new file mode 100644 index 000000000..b8ede2915 --- /dev/null +++ b/algorand/.gitignore @@ -0,0 +1,3 @@ +__pycache__ +_sandbox +genesis.json diff --git a/algorand/Dockerfile b/algorand/Dockerfile new file mode 100644 index 000000000..3a3a9f3a1 --- /dev/null +++ b/algorand/Dockerfile @@ -0,0 +1,23 @@ +# syntax=docker.io/docker/dockerfile:1.3@sha256:42399d4635eddd7a9b8a24be879d2f9a930d0ed040a61324cfdf59ef1357b3b2 +FROM docker.io/python:3.10 + +# Support additional root CAs +COPY README.md cert.pem* /certs/ +# Debian +RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/certs/ca-certificates.crt; fi + +RUN python3 -m pip install virtualenv + +RUN apt-get update +RUN apt-get -y install netcat + +COPY Pipfile.lock Pipfile.lock +COPY Pipfile Pipfile + +RUN python3 -m pip install pipenv +RUN pipenv install +RUN mkdir teal + +COPY *.py . +COPY deploy.sh deploy.sh +COPY .env .env diff --git a/algorand/MEMORY.md b/algorand/MEMORY.md new file mode 100644 index 000000000..105e9d907 --- /dev/null +++ b/algorand/MEMORY.md @@ -0,0 +1,381 @@ +# Algorand memory allocation + +# Table of Contents + +1. [Background](about:blank#orgea5c5c2) +2. [The “allocator” program](about:blank#org85bc975) + 1. [Instantiating template variables](about:blank#orgf176818) + 1. [Instantiation, off-chain](about:blank#org2091dfe) + 2. [Instantiation, on-chain](about:blank#orga6fa146) + 2. [Allocating, client-side](about:blank#org74c4227) + + + +# Background + +The Algorand blockchain has a completely different virtual machine from the other chains Wormhole currently supports. The assembly language of Algorand is called TEAL, which runs on the Algorand VM (AVM). This means that understanding the Algorand contracts will require understanding a whole new set of platform-specific features and constraints. + +The purpose of this post is to investigate the way the Wormhole contracts handle (or rather, implement) memory management on Algorand. This is particularly interesting because of the unique memory constraints on this platform which require a fair amount of creativity to overcome. This code is critical, and highly non-trivial. + +Like EVM bytecode, TEAL is a purpose-designed instruction set, but unlike EVM, there is currently no high-level language (like Solidity) with a compiler targeting TEAL. There is an in-between solution, called pyTEAL. pyTEAL is **not** a compiler from Python to TEAL, instead, it is an embedded domain-specific language for generating TEAL code in Python. This means that each pyTEAL program is a code generator (it’s a heterogeneous two-stage programming language). The thing about multistage programming languages is that you always have to think about when a piece of code will execute - compile time or runtime? We’ll discuss this in detail. + +A pyTEAL program essentially constructs TEAL abstract syntax during its execution. The pyTEAL library provides a function called `compileTeal` which turns this abstract syntax into concrete syntax (not sure how much compilation is happening, but we’ll roll with this name). Finally, the TEAL file has to be compiled to binary before it can be uploaded to the Algorand blockchain. Somewhat frustratingly, this part of the process requires connecting to a running Algorand node. It’s unclear to me why this is the case, as we will see, this compilation step might as well be just called an assembler step. There’s pretty much a 1-to-1 mapping from TEAL to the binary. + +Algorand contracts can only store a fixed amount of state. This is a major limitation for us, as in order to support some of the key wormhole features like replay protection, we need an unbounded amount of storage. + + + +# The “allocator” program + +The main allocator code resides in [/algorand/TmplSig.py](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py). Let’s work backwards in this file: + +```python +if __name__ == '__main__': + core = TmplSig("sig") + + with open("sig.tmpl.teal", "w") as f: + f.write(core.get_sig_tmpl()) +``` +[/algorand/TmplSig.py#L136-L142](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L136-L142) + +If we run this program, it will generate a file called `sig.tmpl.teal` based on whatever `get_sig_tmpl()` returns from the `TmplSig` class. The first few lines of `sig.tmpl.teal` look like this: + +``` +#pragma version 6 +intcblock 1 +pushint TMPL_ADDR_IDX // TMPL_ADDR_IDX +pop +pushbytes TMPL_EMITTER_ID // TMPL_EMITTER_ID +pop +txn TypeEnum +pushint 6 // appl +== +assert +txn OnCompletion +intc_0 // OptIn +== +assert +txn ApplicationID +pushint TMPL_APP_ID // TMPL_APP_ID +== +assert +txn RekeyTo +pushbytes TMPL_APP_ADDRESS // TMPL_APP_ADDRESS +== +assert +txn Fee +pushint 0 // 0 +== +assert +txn CloseRemainderTo +global ZeroAddress +== +assert +txn AssetCloseTo +global ZeroAddress +== +assert +intc_0 // 1 +return +``` + +We’ll examine this file more carefully soon. For now, the key takeaway is that it contains TEAL bytecode, which is a stack-based programming language. What’s curious is that right at the beginning, we push `TMPL_ADDR_IDX` and `TMPL_EMITTER_ID`, only to immediately pop them from the stack, which seems redundant. Indeed, as we will see, these four lines of code are here just for the sake of being here, and we don’t actually expect them to do anything useful. This will make more sense soon. + +Let’s look at the `get_sig_tmpl` function. + +```python + def get_sig_tmpl(self): +``` +[/algorand/TmplSig.py#L111](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L111) + +its return statement is a call to `compileTeal`: + +```python + return compileTeal(sig_tmpl(), mode=Mode.Signature, version=6, assembleConstants=True) +``` +[/algorand/TmplSig.py#L134](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L134) + +From the `mode=Mode.Signature` argument in `compileTeal` we can see that this program is a signature program, also known as a LogicSig. LogicSigs are special programs that belong to an account, and their purpose is to authorise transactions from that account (or more generally, to act as a signing authority for the account). If the LogicSig program executes successfully (without reverting), then the transaction is authorised. Algorand allows running such programs as a way of implementing domain-specific account authorisation, such as for escrow systems, etc. The address of the LogicSig’s account is deterministically derived from the hash of the LogicSig’s bytecode (this will be very important very soon). + +The `sig_tmpl` function returns a sequence of TEAL instructions, the first two of which are + +```python + # Just putting adding this as a tmpl var to make the address unique and deterministic + # We don't actually care what the value is, pop it + Pop(Tmpl.Int("TMPL_ADDR_IDX")), + Pop(Tmpl.Bytes("TMPL_EMITTER_ID")), +``` +[/algorand/TmplSig.py#L117-L120](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L117-L120) + +Here are the two pop statements we looked at in the TEAL code. The pyTEAL compiler knows to generate push instructions for arguments whenever necessary, so we don’t explicitly push `TMPL_ADDR_IDX` and `TMPL_EMITTER_ID`. These variables immediately get popped, because the LogicSig doesn’t actually make use of them, and they’re only there so when replaced with different values in the bytecode, we get an operationally equivalent, yet distinct bytecode. + +`Tmpl.Int("TMPL_ADDR_IDX")` and `Tmpl.Bytes("TMPL_EMITTER_ID")` are *template variables*. Normally, they can be thought of as variables in a TEAL program that get replaced at compile time by the compiler, sort of like CPP macros. In fact, this already hints at how the LogicSig is going to be used: these variables will be programmatically replaced (albeit not just at compile time, but more on that later) with distinct values to generate distinct LogicSigs, with deterministic addresses. The wormhole contract will then be able to use the memory of the associated accounts of these LogicSigs. To see how, we’ll first go through what the LogicSig does in the first place. + +When using a LogicSig to sign a transaction (like in our case), the LogicSig program can query information about the transaction from the Algorand runtime. If the LogicSig doesn't revert, then the transaction will be executed on-chain. It is the LogicSig’s responsibility to decide whether it wants to approve this transaction, so it will perform a number of checks to ensure the transaction does what’s expected. Importantly, anyone can pass in their own transactions and use the LogicSig to sign it, so forgetting a check here could result in hijacking the LogicSig’s associated account. That's because (by default), transactions that are signed (that is, approved) by the LogicSig can acces the LogicSig’s account. In fact, that's what LogicSigs were designed for in the first place: to implement arbitrary logic for deciding who can spend money out of some account. + +The first instruction after the two `Pop`s above is + +```python + Assert(Txn.type_enum() == TxnType.ApplicationCall), +``` +[/algorand/TmplSig.py#L122](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L122) + +Which asserts that the transaction being signed is an application call. +Note that `==` here is an overloaded operator, and it doesn’t compare two python values. Instead, it generates a piece of pyTEAL abstract syntax that represents an equality operation. In TEAL’s concrete syntax, this looks like: + +``` +txn TypeEnum +pushint 6 // appl +== +assert +``` + +The `txn` opcode pushes a transaction field variable to the stack, in this case its type, which is made avaiable by the AVM runtime. +`pushint` pushes an integer to the stack, here the number 6, which corresponds to application call. `==` pops the top two elements from the stack and pushes 1 if they are equal, or 0 if they are not. Finally, `assert` pops the top of the stack, and reverts the transaction if it’s 0 (or if the stack is empty). + +Application calls are one of the built-in transaction types defined by Algorand, another one is Payment. We require that this one is an application call, because of the next check, opting in: + +```python + Assert(Txn.on_completion() == OnComplete.OptIn), + Assert(Txn.application_id() == Tmpl.Int("TMPL_APP_ID")), +``` +[/algorand/TmplSig.py#L123-L124](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L123-L124) + +Opting in means that the current application (which is the `"TMPL_APP_ID"`) can allocate local storage into the _sender_'s account data. When the sender is the LogicSig's associated account, then the transaction opts into the LogicSig's account data. **This is the memory allocation mechanism**. By opting the LogicSig’s associated account into the wormhole contract, wormhole can now use it to store memory. Since these accounts are also limited in size, we need multiple of them, and at deterministic locations. This is why `TMPL_ADDR_IDX` and `TMPL_EMITTER_ID` are used in the program. The wormhole contracts populate these templates with actual values which will allow deriving a deterministic address (the LogicSig’s associated account address) which will be known to be a writeable account by the wormhole contract (since the LogicSig opted into the wormhole contract here). This mechanism is similar to Solana’s Program-Derived Addresses (PDAs). The difference is that in Solana, PDAs are always owned by the program they’re derived from, whereas in Algorand, ownership of an account can be transferred using the `rekey` mechanism. At this point, the LogicSig's account is owned by the LogicSig. Next, we make sure that the transaction transfers ownership of the account to our application: + +```python + Assert(Txn.rekey_to() == Tmpl.Bytes("TMPL_APP_ADDRESS")), +``` +[/algorand/TmplSig.py#L125](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L125) + + +Rekeying is a feature that allows changing an account’s key so that someone else becomes the signing authority for it. Only the current signing authority can authorize rekeying, and in the process it loses authorization. Since this transaction is signed by a LogicSig, the account in question is the LogicSig’s associated account, and the current signing authority is the LogicSig itself. Once it approves a rekey on its associated account, then further transactions from the associated account do not require running the LogicSig logic, and could just use whatever the new key is (in this case, the wormhole application will be able to use this memory freely). + +This means that at this stage, the LogicSig transfers ownership of its associated account to the wormhole program. This has two functions. First, a safety mechanism, because it means that the LogicSig is no longer able to sign any further transactions, the wormhole program owns it now. With this ownership assignment, the LogicSic’s account truly behaves like a Solana PDA: it’s an account at a deterministic address that’s owned (and thus only writeable) by the program. Second, we can allow assets to get created into this account (which gets over the asset limitation issue) but the main wormhole contract can still sign for transactions against it. + + +Finally, 3 more checks: + +```python + Assert(Txn.fee() == Int(0)), + Assert(Txn.close_remainder_to() == Global.zero_address()), + Assert(Txn.asset_close_to() == Global.zero_address()), +``` +[/algorand/TmplSig.py#L127-L129](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L127-L129) + +We check that the transaction fee is 0. `close_remainder_to` could request the account to be closed and the funds to be sent to another account. This has to be zero, otherwise the account would be deleted. Similarly, `asset_close_to` is also the zero address. + +Finally, if all the checks succeeded, the LogicSig succeeds: + +```python +Approve() +``` +[/algorand/TmplSig.py#L152](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L152) + +To summarize, this is how allocation works: a special program opts in to the wormhole contract, thereby allowing wormhole to write memory into the program’s account, then transfers ownership of the account to wormhole. Since the address of this account is derived from the program’s bytecode, the addresses are reconstructable deterministically, and a given account with such an address cannot have been created any other way than by executing that program with the expected arguments. + + + +## Instantiating template variables + +Now we understand how the allocator contract works. In this section, we’ll review how it can be used. The placeholder variables serve as a way to generate multiple distinct programs in a deterministic way. Let’s see how this works. + +The construction of the bytecode has to happen both off-chain and on-chain. It needs to happen off-chain because the client has to deploy these programs (since an on-chain program cannot deploy another program, this must be done via a transaction from an off-chain entity). It also needs to happen on-chain, because the wormhole program needs to be able to derive (and validate) the addresses of thusly allocated accounts, and the address derivation works by hashing the bytecode, so the bytecode needs to be constructed in the smart contract from runtime information. The off-chain element could be done easily: we can just compile the allocator LogicSig with the template variables filled in with the appropriate variables. The TEAL compiler supports template variable substitution in this way. However, the on-chain component is more complicated, because the smart contract has no access to the compiler, so there’s no way to instantiate the template variables using the standard mechanism. + +Instead, we turn to programmatically patching the generated binary. The LogicSig is compiled once and for all with default values standing in for the template variables, and there’s some code (both off-chain and on-chain) that knows where in the bytecode the template variables are, and replaces them with the appropriate values. The off-chain counterpart can just deploy this patched bytecode, while the on-chain code can hash it to derive the address. + +The constructor of the `TmplSig` class starts by initializing the following data structure: + +```python + self.map = {"name":"lsig.teal","version":6,"source":"","bytecode":"BiABAYEASIAASDEQgQYSRDEZIhJEMRiBABJEMSCAABJEMQGBABJEMQkyAxJEMRUyAxJEIg==", + "template_labels":{ + "TMPL_ADDR_IDX":{"source_line":3,"position":5,"bytes":False}, + "TMPL_EMITTER_ID":{"source_line":5,"position":8,"bytes":True}, + "TMPL_APP_ID":{"source_line":16,"position":24,"bytes":False}, + "TMPL_APP_ADDRESS":{"source_line":20,"position":30,"bytes":True} + }, + } +``` +[/algorand/TmplSig.py#L39-L47](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L39-L47) + +`bytecode` is a base64 encoded binary blob, the assembled binary of the `sig.tmpl.teal` program. The `template_labels` then encodes offsets into the binary where occurrences of the template variables are. In addition to `position`, they all store a `bytes` flag too. This stores whether the template variable is a byte array or not. The importance of this will be that byte arrays can be arbitrary length, and they have an additional byte at the beginning that describes the length of the byte array. Ints on the other hand, are encoded as varints, which are variable width integers that do not contain an additional length byte (see [https://www.sqlite.org/src4/doc/trunk/www/varint.wiki](https://www.sqlite.org/src4/doc/trunk/www/varint.wiki)). The code that patches the binary will need to make sure to write an additional length byte for byte arrays, hence the flag. + +To see what the layout looks like, let’s decode the first few bytes of the bytecode by hand. The TEAL opcodes are documented on the Algorand website here: [https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/](https://developer.algorand.org/docs/get-details/dapps/avm/teal/opcodes/). If we decode the bytecode from base64, we get the following (hex): + +``` +06 20 01 01 81 00 48 80 00 48 31 10 81 06 12 44 31 19 22 12 44 31 18 81 00 12 44 +31 20 80 00 12 44 31 01 81 00 12 44 31 09 32 03 12 44 31 15 32 03 12 44 22 +``` + +and the first few lines of the TEAL code as a reminder: + +``` +#pragma version 6 +intcblock 1 +pushint TMPL_ADDR_IDX // TMPL_ADDR_IDX +pop +pushbytes TMPL_EMITTER_ID // TMPL_EMITTER_ID +pop +``` + +The first byte (`0x06`) is the version identifier. This matches `#pragma version 6` in the TEAL file. `0x20` is the `intcblock` instruction. It takes a byte that represents how many ints are stored (1 here) in this section, and then a list of ints (here, it’s just 1). `0x81` is the `pushint` instruction, and here we push `0x0`. This means that that this program was compiled with the template variables filled with zeros. This 0 is at offset 5 in the bytecode, which agrees with the `'position': 5'` field of the above data structure for `TMPL_ADDR_IDX`. The `0x48` opcode next is the pop instruction. Next, `0x80` is a `pushbytes` instruction, which first takes the a varint for the length of the byte array, then the byte array. Here, since the length is 0, there are no bytes following, instead `0x48` pops immediately. This byte array is at position 8, which corresponds to `TMPL_EMITTER_ID` above. + + + +### Instantiation, off-chain + +The python code that constructs the bytecode is defined as + +```python + def populate(self, values: Dict[str, Union[str, int]]) -> LogicSigAccount: + """populate uses the map to fill in the variable of the bytecode and returns a logic sig with the populated bytecode""" + # Get the template source + contract = list(base64.b64decode(self.map["bytecode"])) + + shift = 0 + for k, v in self.sorted.items(): + if k in values: + pos = v["position"] + shift + if v["bytes"]: + val = bytes.fromhex(values[k]) + lbyte = uvarint.encode(len(val)) + # -1 to account for the existing 00 byte for length + shift += (len(lbyte) - 1) + len(val) + # +1 to overwrite the existing 00 byte for length + contract[pos : pos + 1] = lbyte + val + else: + val = uvarint.encode(values[k]) + # -1 to account for existing 00 byte + shift += len(val) - 1 + # +1 to overwrite existing 00 byte + contract[pos : pos + 1] = val + + # Create a new LogicSigAccount given the populated bytecode, + return LogicSigAccount(bytes(contract)) +``` +[/algorand/TmplSig.py#L58-L85](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/TmplSig.py#L58-L85) + +It loops through the template variables, and replaces them with values defined in the `values` dictionary. For byte arrays, it inserts the length byte first. The `shift` variable maintains the number of extra bytes inserted so far, as the subsequent byte offsets all shift by this amount. + + + +### Instantiation, on-chain + +The on-chain program is similar to the above, but it just concatenates the byte chunks together: + +```python + @Subroutine(TealType.bytes) + def get_sig_address(acct_seq_start: Expr, emitter: Expr): + # We could iterate over N items and encode them for a more general interface + # but we inline them directly here + + return Sha512_256( + Concat( + Bytes("Program"), + # ADDR_IDX aka sequence start + tmpl_sig.get_bytecode_chunk(0), + encode_uvarint(acct_seq_start, Bytes("")), + + # EMMITTER_ID + tmpl_sig.get_bytecode_chunk(1), + encode_uvarint(Len(emitter), Bytes("")), + emitter, + + # APP_ID + tmpl_sig.get_bytecode_chunk(2), + encode_uvarint(Global.current_application_id(), Bytes("")), + + # TMPL_APP_ADDRESS + tmpl_sig.get_bytecode_chunk(3), + encode_uvarint(Len(Global.current_application_address()), Bytes("")), + Global.current_application_address(), + + + tmpl_sig.get_bytecode_chunk(4), + ) + ) +``` +[/algorand/wormhole_core.py#L86-L115](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/wormhole_core.py#L86-L115) + +It writes the string “Program” first. That’s because program addresses are derived by hashing the string “Program” appended to the program’s bytecode. The `get_sig_address` function generates exactly this hash. Notice that the arguments it takes are both of type `Expr`. That’s again because `get_sig_address` is a python program that operates on TEAL expressions to construct a TEAL expression. The bytecode chunks are constructed at compile time, but the concatenation happens at runtime (since the template variables are TEAL expressions, whose values are only available at runtime). This works similarly to the off-chain typescript code. + + + +## Allocating, client-side + +Finally, let us look at how the client-side code actually allocates these accounts. The main idea is that it constructs the allocator LogicSig with the appropriate template variables substituted, then constructs the three transactions required by the allocator. + +The function that does this is `optin`: + +```python + def optin(self, client, sender, app_id, idx, emitter, doCreate=True): +``` +[/algorand/admin.py#L485](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L485) + +First, construct the bytecode with the variables filled in + +```python + lsa = self.tsig.populate( + { + "TMPL_APP_ID": app_id, + "TMPL_APP_ADDRESS": aa, + "TMPL_ADDR_IDX": idx, + "TMPL_EMITTER_ID": emitter, + } + ) +``` +[/algorand/admin.py#L488-L495](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L488-L495) + +Then grab the address of the associated account + +```python + sig_addr = lsa.address() +``` +[/algorand/admin.py#L497](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L497) + +Then check if we’ve already allocated this account + +```python + if sig_addr not in self.cache and not self.account_exists(client, app_id, sig_addr): +``` +[/algorand/admin.py#L499](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L499) + +if not, construct the optin transaction which will also rekey the LogicSig's account to our application. +First, we construct a "seed" transaction, which will pay enough money from the user's wallet into the LogicSig's account to cover for the execution cost: + +```python + seed_txn = transaction.PaymentTxn(sender = sender.getAddress(), + sp = sp, + receiver = sig_addr, + amt = self.seed_amt) + seed_txn.fee = seed_txn.fee * 2 +``` +[/algorand/admin.py#L506-L510](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L506-L510) + +Next, the actual opt-in transaction. The sender (the first argument to `ApplicationOptInTxn`) is the `sig_address`, so our application will allocate memory into it via opting in. + +```python + optin_txn = transaction.ApplicationOptInTxn(sig_addr, sp, app_id, rekey_to=get_application_address(app_id)) + optin_txn.fee = 0 +``` +[/algorand/admin.py#L512-L513](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L512-L513) + +remember that this code is not trusted, and the LogicSig will verify this transaction is doing the correct thing. + +Next, sign the transactions: + +```python + signed_seed = seed_txn.sign(sender.getPrivateKey()) + signed_optin = transaction.LogicSigTransaction(optin_txn, lsa) +``` +[/algorand/admin.py#L517-L518](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L517-L518) + +The first one is signed by the user's wallet, as it's only used to send money from the user's account. The transaction is signed by the logic sig (so it has signing authority over the associated account). Next, send the transactions + +```python + client.send_transactions([signed_seed, signed_optin]) + self.waitForTransaction(client, signed_optin.get_txid()) +``` +[/algorand/admin.py#L520-L521](https://github.com/certusone/wormhole/blob/0af600ddde4f507b30ea043de66033d7383f53af/algorand/admin.py#L520-L521) + +With that, an account is allocated. The client can now pass this account to wormhole, which, after validating that the address is right, will be able to use it to read and write values to. diff --git a/algorand/NOTES.md b/algorand/NOTES.md new file mode 100644 index 000000000..5be9bbaa4 --- /dev/null +++ b/algorand/NOTES.md @@ -0,0 +1,283 @@ +current algorand machine size: + + https://howbigisalgorand.com/ + +custom indexes: + + https://github.com/algorand/indexer/blob/develop/docs/PostgresqlIndexes.md + +Installing node: + + https://developer.algorand.org/docs/run-a-node/setup/install/ + + +kubectl exec -it algorand-0 -c algorand-algod -- /bin/bash + +docker exec -it algorand-tilt-indexer /bin/bash + +to switch to sandbox, change devnet/node.yaml + +- - http://algorand:8980 ++ - http://host.minikube.internal:8980 + +put into dev/node.yaml + + - --algorandAppID + - "4" + +Install the algorand requirements + + python3 -m pip install -r requirements.txt + +install docker-compile + +./sandbox down; ./sandbox clean; ./sandbox up dev -v; python3 admin.py --devnet + +bring up the dev sandbox + + ./sandbox down; ./sandbox clean + + +[jsiegel@gusc1a-ossdev-jsl1 ~/.../algorand/_sandbox]{master} git diff +diff --git a/images/indexer/start.sh b/images/indexer/start.sh +index 9e224c2..f1714ea 100755 +--- a/images/indexer/start.sh ++++ b/images/indexer/start.sh +@@ -28,6 +28,7 @@ start_with_algod() { + /tmp/algorand-indexer daemon \ + --dev-mode \ ++ --enable-all-parameters \ + --server ":$PORT" \ + -P "$CONNECTION_STRING" \ + --algod-net "${ALGOD_ADDR}" \ + + ./sandbox up dev + + +docker_compose("./algorand/sandbox-algorand/tilt-compose.yml") + +dc_resource('algo-algod', labels=["algorand"]) +dc_resource('algo-indexer', labels=["algorand"]) +dc_resource('algo-indexer-db', labels=["algorand"]) + + // Solana + "01000000000100c9f4230109e378f7efc0605fb40f0e1869f2d82fda5b1dfad8a5a2dafee85e033d155c18641165a77a2db6a7afbf2745b458616cb59347e89ae0c7aa3e7cc2d400000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e4272696467650100000001c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f", + // Ethereum + "01000000000100e2e1975d14734206e7a23d90db48a6b5b6696df72675443293c6057dcb936bf224b5df67d32967adeb220d4fe3cb28be515be5608c74aab6adb31099a478db5c01000000010000000100010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000546f6b656e42726964676501000000020000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16", + // BSC + "01000000000100719b4ada436f614489dbf87593c38ba9aea35aa7b997387f8ae09f819806f5654c8d45b6b751faa0e809ccbc294794885efa205bd8a046669464c7cbfb03d183010000000100000001000100000000000000000000000000000000000000000000000000000000000000040000000002c8bb0600000000000000000000000000000000000000000000546f6b656e42726964676501000000040000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16", + +('0100000001010001ca2fbf60ac6227d47dda4fe2e7bccc087f27d22170a212b9800da5b4cbf0d64c52deb2f65ce58be2267bf5b366437c267b5c7b795cd6cea1ac2fee8a1db3ad006225f801000000010001000000000000000000000000000000000000000000000000000000000000000400000000000000012000000000000000000000000000000000000000000000000000000000436f72650200000000000001beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe', + {'Meta': 'CoreGovernance', + 'NewGuardianSetIndex': 0, + 'action': 2, + 'chain': 1, + 'chainRaw': b'\x00\x01', + 'consistency': 32, + 'digest': b'b%\xf8\x01\x00\x00\x00\x01\x00\x01\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' + b'\x00\x01 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00C' + b'ore\x02\x00\x00\x00\x00\x00\x00\x01\xbe\xfaB\x9dW\xcd\x18\xb7\xf8' + b'\xa4\xd9\x1a-\xa9\xabJ\xf0]\x0f\xbe', + 'emitter': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04', + 'index': 1, + 'module': '00000000000000000000000000000000000000000000000000000000436f7265', + 'nonce': 1, + 'sequence': 1, + 'siglen': 1, + 'signatures': b"\x00\x01\xca/\xbf`\xacb'\xd4}\xdaO\xe2\xe7\xbc\xcc\x08\x7f'" + b'\xd2!p\xa2\x12\xb9\x80\r\xa5\xb4\xcb\xf0\xd6LR\xde' + b'\xb2\xf6\\\xe5\x8b\xe2&{\xf5\xb3fC|&{\\{y\\\xd6\xce\xa1\xac/' + b'\xee\x8a\x1d\xb3\xad\x00', + 'sigs': ['0001ca2fbf60ac6227d47dda4fe2e7bccc087f27d22170a212b9800da5b4cbf0d64c52deb2f65ce58be2267bf5b366437c267b5c7b795cd6cea1ac2fee8a1db3ad00'], + 'targetChain': 0, + 'timestamp': 1646655489, + 'version': 1}) + + +Registering chain 1 +('01000000020100c2f0b6e546e093630295e5007e8b077b1028d3aa9a72ab4c454b261306eb4f550179638597f25afd6f40a18580bc87fa315552e7294b407bd4616f0995d1cb55016225f5fd0000000300010000000000000000000000000000000000000000000000000000000000000004000000000000000320000000000000000000000000000000000000000000546f6b656e4272696467650100000001ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5', + {'EmitterChainID': 1, + 'Meta': 'TokenBridge RegisterChain', + 'action': 1, + 'chain': 1, + 'chainRaw': b'\x00\x01', + 'consistency': 32, + 'digest': b'b%\xf5\xfd\x00\x00\x00\x03\x00\x01\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' + b'\x00\x03 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00TokenBridge\x01\x00\x00\x00\x01' + b'\xecsr\x99]\\\xc8s#\x97\xfb\n\xd3\\\x01!\xe0\xea\xa9\r&\xf8(\xa5' + b'4\xca\xb5C\x91\xb3\xa4\xf5', + 'emitter': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04', + 'index': 2, + 'module': '000000000000000000000000000000000000000000546f6b656e427269646765', + 'nonce': 3, + 'sequence': 3, + 'siglen': 1, + 'signatures': b'\x00\xc2\xf0\xb6\xe5F\xe0\x93c\x02\x95\xe5\x00~\x8b\x07' + b'{\x10(\xd3\xaa\x9ar\xabLEK&\x13\x06\xebOU\x01yc\x85\x97\xf2Z' + b'\xfdo@\xa1\x85\x80\xbc\x87\xfa1UR\xe7)K@{\xd4ao\t\x95\xd1\xcb' + b'U\x01', + 'sigs': ['00c2f0b6e546e093630295e5007e8b077b1028d3aa9a72ab4c454b261306eb4f550179638597f25afd6f40a18580bc87fa315552e7294b407bd4616f0995d1cb5501'], + 'targetChain': 0, + 'targetEmitter': 'ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5', + 'timestamp': 1646654973, + 'version': 1}) +Sending 3000 algo to cover fees +[1000, 1000, 1000, 1000] +{0: 99997976000} +Registering chain 2 +('010000000201008c7153db06d433e304dcb7dc029b6cb142093adf87eac7a14adff78060f9b80275479d0620612ae656f7281190ab7bbf85f31eb2ace579e77b2e7855af2a4504016225f5fe0000000400010000000000000000000000000000000000000000000000000000000000000004000000000000000420000000000000000000000000000000000000000000546f6b656e42726964676501000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585', + {'EmitterChainID': 2, + 'Meta': 'TokenBridge RegisterChain', + 'action': 1, + 'chain': 1, + 'chainRaw': b'\x00\x01', + 'consistency': 32, + 'digest': b'b%\xf5\xfe\x00\x00\x00\x04\x00\x01\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' + b'\x00\x04 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00TokenBridge\x01\x00\x00\x00\x02' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>\xe1\x8b"' + b'\x14\xaf\xf9p\x00\xd9t\xcfd~|4~\x8f\xa5\x85', + 'emitter': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04', + 'index': 2, + 'module': '000000000000000000000000000000000000000000546f6b656e427269646765', + 'nonce': 4, + 'sequence': 4, + 'siglen': 1, + 'signatures': b'\x00\x8cqS\xdb\x06\xd43\xe3\x04\xdc\xb7\xdc\x02\x9bl\xb1B\t:' + b'\xdf\x87\xea\xc7\xa1J\xdf\xf7\x80`\xf9\xb8\x02uG\x9d\x06 a*' + b'\xe6V\xf7(\x11\x90\xab{\xbf\x85\xf3\x1e\xb2\xac\xe5y\xe7{.x' + b'U\xaf*E\x04\x01', + 'sigs': ['008c7153db06d433e304dcb7dc029b6cb142093adf87eac7a14adff78060f9b80275479d0620612ae656f7281190ab7bbf85f31eb2ace579e77b2e7855af2a450401'], + 'targetChain': 0, + 'targetEmitter': '0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585', + 'timestamp': 1646654974, + 'version': 1}) +Sending 3000 algo to cover fees +[1000, 1000, 1000, 1000] +{0: 99997967000} +Registering chain 3 +('010000000201006896223475308eb13bc6d279b620b167f0e4884afc56942b2199faa81e1d50d83d74f7c0700254aa78a7e8966508608f0d827969df09745ad569575136551bce006225f5ff0000000500010000000000000000000000000000000000000000000000000000000000000004000000000000000520000000000000000000000000000000000000000000546f6b656e42726964676501000000030000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2', + {'EmitterChainID': 3, + 'Meta': 'TokenBridge RegisterChain', + 'action': 1, + 'chain': 1, + 'chainRaw': b'\x00\x01', + 'consistency': 32, + 'digest': b'b%\xf5\xff\x00\x00\x00\x05\x00\x01\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' + b'\x00\x05 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00TokenBridge\x01\x00\x00\x00\x03' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00|\xf7\xb7d' + b'\xe3\x8a\n^\x96yr\xc1\xdfw\xd42Q\x05d\xe2', + 'emitter': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04', + 'index': 2, + 'module': '000000000000000000000000000000000000000000546f6b656e427269646765', + 'nonce': 5, + 'sequence': 5, + 'siglen': 1, + 'signatures': b'\x00h\x96"4u0\x8e\xb1;\xc6\xd2y\xb6 \xb1g\xf0\xe4\x88' + b'J\xfcV\x94+!\x99\xfa\xa8\x1e\x1dP\xd8=t\xf7\xc0p\x02T' + b'\xaax\xa7\xe8\x96e\x08`\x8f\r\x82yi\xdf\ttZ\xd5iWQ6U\x1b' + b'\xce\x00', + 'sigs': ['006896223475308eb13bc6d279b620b167f0e4884afc56942b2199faa81e1d50d83d74f7c0700254aa78a7e8966508608f0d827969df09745ad569575136551bce00'], + 'targetChain': 0, + 'targetEmitter': '0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2', + 'timestamp': 1646654975, + 'version': 1}) +Sending 3000 algo to cover fees +[1000, 1000, 1000, 1000] +{0: 99997958000} +Registering chain 4 +('0100000002010023b80ca2402119348543c14134218cd0e1e54428e54ecdf21acb1a1d6c01be261fcc138023955a04bcd09230a5710340251b68db080a8bbf64d06ab744624d6a016225f5ff0000000600010000000000000000000000000000000000000000000000000000000000000004000000000000000620000000000000000000000000000000000000000000546f6b656e4272696467650100000004000000000000000000000000b6f6d86a8f9879a9c87f643768d9efc38c1da6e7', + {'EmitterChainID': 4, + 'Meta': 'TokenBridge RegisterChain', + 'action': 1, + 'chain': 1, + 'chainRaw': b'\x00\x01', + 'consistency': 32, + 'digest': b'b%\xf5\xff\x00\x00\x00\x06\x00\x01\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' + b'\x00\x06 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00TokenBridge\x01\x00\x00\x00\x04' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xb6\xf6\xd8j' + b'\x8f\x98y\xa9\xc8\x7fd7h\xd9\xef\xc3\x8c\x1d\xa6\xe7', + 'emitter': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04', + 'index': 2, + 'module': '000000000000000000000000000000000000000000546f6b656e427269646765', + 'nonce': 6, + 'sequence': 6, + 'siglen': 1, + 'signatures': b'\x00#\xb8\x0c\xa2@!\x194\x85C\xc1A4!\x8c\xd0\xe1\xe5D' + b'(\xe5N\xcd\xf2\x1a\xcb\x1a\x1dl\x01\xbe&\x1f\xcc\x13' + b'\x80#\x95Z\x04\xbc\xd0\x920\xa5q\x03@%\x1bh\xdb\x08\n\x8b' + b'\xbfd\xd0j\xb7DbMj\x01', + 'sigs': ['0023b80ca2402119348543c14134218cd0e1e54428e54ecdf21acb1a1d6c01be261fcc138023955a04bcd09230a5710340251b68db080a8bbf64d06ab744624d6a01'], + 'targetChain': 0, + 'targetEmitter': '000000000000000000000000b6f6d86a8f9879a9c87f643768d9efc38c1da6e7', + 'timestamp': 1646654975, + 'version': 1}) +Sending 3000 algo to cover fees +[1000, 1000, 1000, 1000] +{0: 99997949000} +Registering chain 5 +('010000000201003a168d6617cc74c3a5e254a6e65441d341cec315dcd5b588e72f781f8dd9c82977ad1234732d097151a54add996a33a6e4da3a2e80c41146de0bc834d8830661006225f6000000000700010000000000000000000000000000000000000000000000000000000000000004000000000000000720000000000000000000000000000000000000000000546f6b656e42726964676501000000050000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde', + {'EmitterChainID': 5, + 'Meta': 'TokenBridge RegisterChain', + 'action': 1, + 'chain': 1, + 'chainRaw': b'\x00\x01', + 'consistency': 32, + 'digest': b'b%\xf6\x00\x00\x00\x00\x07\x00\x01\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' + b'\x00\x07 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00TokenBridge\x01\x00\x00\x00\x05' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ZXPZ' + b'\x96\xd1\xdb\xf8\xdf\x91\xcb!\xb5D\x19\xfc6\xe9?\xde', + 'emitter': b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04', + 'index': 2, + 'module': '000000000000000000000000000000000000000000546f6b656e427269646765', + 'nonce': 7, + 'sequence': 7, + 'siglen': 1, + 'signatures': b'\x00:\x16\x8df\x17\xcct\xc3\xa5\xe2T\xa6\xe6TA\xd3A\xce\xc3' + b'\x15\xdc\xd5\xb5\x88\xe7/x\x1f\x8d\xd9\xc8)w\xad\x124s-\t' + b'qQ\xa5J\xdd\x99j3\xa6\xe4\xda:.\x80\xc4\x11F\xde\x0b\xc8' + b'4\xd8\x83\x06a\x00', + 'sigs': ['003a168d6617cc74c3a5e254a6e65441d341cec315dcd5b588e72f781f8dd9c82977ad1234732d097151a54add996a33a6e4da3a2e80c41146de0bc834d883066100'], + 'targetChain': 0, + 'targetEmitter': '0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde', + 'timestamp': 1646654976, + 'version': 1}) + +./sandbox down; ./sandbox clean; ./sandbox up dev -v; python3 admin.py --devnet + + +[jsiegel@gusc1a-ossdev-jsl1 ~/.../algorand/_sandbox]{master} git diff +diff --git a/images/indexer/start.sh b/images/indexer/start.sh +index 9e224c2..f1714ea 100755 +--- a/images/indexer/start.sh ++++ b/images/indexer/start.sh +@@ -28,6 +28,7 @@ start_with_algod() { + /tmp/algorand-indexer daemon \ + --dev-mode \ ++ --enable-all-parameters \ + --server ":$PORT" \ + -P "$CONNECTION_STRING" \ + --algod-net "${ALGOD_ADDR}" \ diff --git a/algorand/Pipfile b/algorand/Pipfile new file mode 100644 index 000000000..3b2825213 --- /dev/null +++ b/algorand/Pipfile @@ -0,0 +1,37 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +attrs = "==21.4.0" +cffi = "==1.15.0" +colorama = "==0.4.4" +execnet = "==1.9.0" +future-fstrings = "==1.2.0" +iniconfig = "==1.1.1" +msgpack = "==1.0.3" +pluggy = "==1.0.0" +py = "==1.11.0" +pycparser = "==2.21" +pycryptodomex = "==3.12.0" +pydantic = "==1.9.0" +pyparsing = "==3.0.6" +pyteal = "==v0.11.1" +py-algorand-sdk = "==1.10.0b1" +pytest = "==6.2.5" +pytest-depends = "==1.0.1" +pytest-forked = "==1.4.0" +pytest-xdist = "==2.5.0" +toml = "==0.10.2" +typing-extensions = "==4.0.1" +uvarint = "==1.2.0" +eth_abi = "==2.1.1" +coincurve = "==16.0.0" +PyNaCl = "==1.5.0" +PyYAML = "==6.0" + +[dev-packages] + +[requires] +python_version = "3.10" diff --git a/algorand/Pipfile.lock b/algorand/Pipfile.lock new file mode 100644 index 000000000..94dcc74dc --- /dev/null +++ b/algorand/Pipfile.lock @@ -0,0 +1,559 @@ +{ + "_meta": { + "hash": { + "sha256": "d57ff41afd46f1f82ef8cfa680858a40bda1d72482b073dba8666ac42275264f" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.9" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "asn1crypto": { + "hashes": [ + "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c", + "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67" + ], + "version": "==1.5.1" + }, + "attrs": { + "hashes": [ + "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", + "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + ], + "index": "pypi", + "version": "==21.4.0" + }, + "cffi": { + "hashes": [ + "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", + "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", + "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", + "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", + "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", + "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", + "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", + "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", + "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", + "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", + "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", + "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", + "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", + "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", + "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", + "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", + "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", + "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", + "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", + "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", + "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", + "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", + "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", + "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", + "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", + "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", + "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", + "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", + "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", + "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", + "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", + "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", + "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", + "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", + "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", + "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", + "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", + "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", + "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", + "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", + "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", + "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", + "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", + "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", + "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", + "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", + "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", + "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", + "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", + "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" + ], + "index": "pypi", + "version": "==1.15.0" + }, + "coincurve": { + "hashes": [ + "sha256:0a07a80843094c4c1e80a39e3b2525f5fd165804226f556d564b6db513850979", + "sha256:0df23cba832bea28bc0f35176b2aaa7585cc85decce9560b79ec4991d49e0901", + "sha256:1106efb37d8209690a56d3e25acf2bf76adec692fb13cd4574544e2644220f6d", + "sha256:14824fe05f032052f9c028ed820ee542d284f0e056af3258b8fbbd2faa832a47", + "sha256:1621b1fdc5740caa27ce6c670c7134dfb471d0a430c6a62c6891cc40b5479951", + "sha256:166bd6ed3d3f3323f8f2bbada3840fde7a5e21790c33b510e666b81bebcf3b5e", + "sha256:1a8feb5b943fdd2520bcd77fde25101f20a8309a069a5d2e9648fc5156e05e0e", + "sha256:29e4e57996a12cf2a410cf61759917fdb0177a7bcf1a8ab5c8888c9da8d9a26c", + "sha256:3470d6529abc00bb6810ed05e1dd371b32a9679fa0f26d4d2fdd60784a9652cf", + "sha256:400ba504e6ab40ef906b93440866da962a956e3edd17afbc6c493a85a34740bc", + "sha256:43b1e975b83390b9f3e18b9b0ef00465a069328b9c32645201414fd8abb409fb", + "sha256:4d9d1cb54c36dfd22539bb6aeea6a6135ea34e6b84c183272a4dbcd5cf5055d4", + "sha256:4df9498894b6f3a19c5507cfe8bd945a261390bc687b9ed12c1f4671123eb172", + "sha256:5a1448dacd1a79b7c6a5e0fee49268cbf8330c2971b9577b03a0315dd40f278e", + "sha256:5d432ae55989ab4993e8aa5b888958347a947b9d61887fc5072b265329a3648f", + "sha256:5d4ae85e6125a65d38b5c0e1d1e9025ba39b49550703a07eb35efa5c41c18e56", + "sha256:5ed6cc2844e88efd03f30bae00f9114624f813f9460585aa3d57cecad197736a", + "sha256:659b77c9c8e81c35b72c3b1c1759590ed0a7f74674efb2baa9da933f3788e7f6", + "sha256:7eda756fe9e026436eeb98d739b378a739f80c1cc99c77f00d3c91aed0908ff4", + "sha256:7ffc693dde858c30ac295c261799007ddc6bf92f3b2afbfefd61b1dd42e2199f", + "sha256:8618c7b9fdca0f91808db1c5cbe5b8c583b7a1d24504fe9bb50f878e265118ca", + "sha256:8cc73c0b7903b669cc94b0775d588e13ce06df496032cc91bdeb77d79f633e07", + "sha256:8dea0e00245fd9a4f5a83c25a691a6a4651a6d20f4b63e18da5be98d47a96897", + "sha256:9539c1736812fc09cbe6b0471e90f7ffd947688705832360299e97c3dab917ae", + "sha256:9a43b256344398fe27240ff1c740057b1f62b4ccfbdc01580258f54d1f82b5d8", + "sha256:9b87cb82ce8b62f56643696f344d0ca4bf0835b72be2fa874473a889d4a263da", + "sha256:a06789f710541a4370bfca5eb21a8e73b0f1ab2ecf5a0bab0837223f7929d28c", + "sha256:a8edec78e126e106d0e1a0a052c40a77a135225fce46a56110a73f08275ed266", + "sha256:aa427eb103d370175604e628cc3c6dca90a4f3c7801914985f1500c1267b3b52", + "sha256:ae7548e8be34bc595959933ae3f29ad7a63f1d35207d3e11cbc76e6c7484190c", + "sha256:b29aa4b890066b89be2cd8f1a176a872ad79893a649d6a09b34365eae905aba5", + "sha256:b7ad945429c86de2f861e4042bc8996bad80814ecd7984e81fc461258d61c46a", + "sha256:bedf752706ce8b1fa6960d9294db24db76e28343dd0831ba8f435cfac4af973b", + "sha256:c45b3ce930ed4a9ba8690a313494fc9f05e3f313b080bf1d1695f2f7076ca016", + "sha256:c7fa11335c8518eead358c3bcfb9a66f53ce36f1bcfb4393a621207f1bcfda4f", + "sha256:c981c7cf967937c66a537a2f4ae6839189dbc28933a2b737910385788dd4d00c", + "sha256:cae66a1fa69c07cdce05f315830c2ea86528724a96507848b820ada029ac05e9", + "sha256:d0f07d9ab46d7b6178d8ae4ca94ca64ef81abfc3f4042f3b133dbef2acace2a9", + "sha256:d24dc141d15fd3dd75b114572556fe186106a0f5922ed9585cf6ae8323cd1de8", + "sha256:d7969af60e7d2a58cf5280bfc7cac16cdb52a7f7c2e57e94c40807691e96035b", + "sha256:df1888a1f268275c84ce2245d1e6fe73e0135ecc3295ab69c736c1ded0373d8d", + "sha256:e8bfb4091c796085f3d14c946aa34e767a3c947ba5da9bdaa400126ca89c8499", + "sha256:e9fbbd29be70ebc6a9a3acd48a39cbe421ab0f4074654caef6a8ef465252433a", + "sha256:f73e9f08d9da0bdacc0b4b82216ef1db3d9b37d7a69ada9b8a4e6ade665c6ade", + "sha256:fbe60c5e79dd47bbe91e096ad21c5c37e59361f1726913d2dda59680f2f111f0" + ], + "index": "pypi", + "version": "==16.0.0" + }, + "colorama": { + "hashes": [ + "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b", + "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2" + ], + "index": "pypi", + "version": "==0.4.4" + }, + "cytoolz": { + "hashes": [ + "sha256:ea23663153806edddce7e4153d1d407d62357c05120a4e8485bddf1bd5ab22b4" + ], + "markers": "implementation_name == 'cpython'", + "version": "==0.11.2" + }, + "dataclasses": { + "hashes": [ + "sha256:0201d89fa866f68c8ebd9d08ee6ff50c0b255f8ec63a71c16fda7af82bb887bf", + "sha256:8479067f342acf957dc82ec415d355ab5edb7e7646b90dc6e2fd1d96ad084c97" + ], + "markers": "python_version < '3.7'", + "version": "==0.8" + }, + "decorator": { + "hashes": [ + "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760", + "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7" + ], + "version": "==4.4.2" + }, + "eth-abi": { + "hashes": [ + "sha256:4bb1d87bb6605823379b07f6c02c8af45df01a27cc85bd6abb7cf1446ce7d188", + "sha256:78df5d2758247a8f0766a7cfcea4575bcfe568c34a33e6d05a72c328a9040444" + ], + "index": "pypi", + "version": "==2.1.1" + }, + "eth-hash": { + "hashes": [ + "sha256:3f40cecd5ead88184aa9550afc19d057f103728108c5102f592f8415949b5a76", + "sha256:de7385148a8e0237ba1240cddbc06d53f56731140f8593bdb8429306f6b42271" + ], + "markers": "python_version >= '3.5' and python_version < '4'", + "version": "==0.3.2" + }, + "eth-typing": { + "hashes": [ + "sha256:39cce97f401f082739b19258dfa3355101c64390914c73fe2b90012f443e0dc7", + "sha256:b7fa58635c1cb0cbf538b2f5f1e66139575ea4853eac1d6000f0961a4b277422" + ], + "markers": "python_version >= '3.5' and python_version < '4'", + "version": "==2.3.0" + }, + "eth-utils": { + "hashes": [ + "sha256:74240a8c6f652d085ed3c85f5f1654203d2f10ff9062f83b3bad0a12ff321c7a", + "sha256:bf82762a46978714190b0370265a7148c954d3f0adaa31c6f085ea375e4c61af" + ], + "markers": "python_version >= '3.5' and python_version < '4' and python_full_version != '3.5.2'", + "version": "==1.10.0" + }, + "execnet": { + "hashes": [ + "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5", + "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142" + ], + "index": "pypi", + "version": "==1.9.0" + }, + "future-fstrings": { + "hashes": [ + "sha256:6cf41cbe97c398ab5a81168ce0dbb8ad95862d3caf23c21e4430627b90844089", + "sha256:90e49598b553d8746c4dc7d9442e0359d038c3039d802c91c0a55505da318c63" + ], + "index": "pypi", + "version": "==1.2.0" + }, + "importlib-metadata": { + "hashes": [ + "sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e", + "sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668" + ], + "markers": "python_version < '3.8'", + "version": "==4.8.3" + }, + "iniconfig": { + "hashes": [ + "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", + "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" + ], + "index": "pypi", + "version": "==1.1.1" + }, + "msgpack": { + "hashes": [ + "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc", + "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147", + "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3", + "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba", + "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39", + "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85", + "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9", + "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a", + "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec", + "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88", + "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e", + "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a", + "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b", + "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1", + "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3", + "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef", + "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079", + "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52", + "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a", + "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a", + "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4", + "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996", + "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73", + "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a", + "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920", + "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7", + "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d", + "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770", + "sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50", + "sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2", + "sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2", + "sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d", + "sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea", + "sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611" + ], + "index": "pypi", + "version": "==1.0.3" + }, + "networkx": { + "hashes": [ + "sha256:0635858ed7e989f4c574c2328380b452df892ae85084144c73d8cd819f0c4e06", + "sha256:109cd585cac41297f71103c3c42ac6ef7379f29788eb54cb751be5a663bb235a" + ], + "markers": "python_version >= '3.6'", + "version": "==2.5.1" + }, + "packaging": { + "hashes": [ + "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", + "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" + ], + "markers": "python_version >= '3.6'", + "version": "==21.3" + }, + "parsimonious": { + "hashes": [ + "sha256:3add338892d580e0cb3b1a39e4a1b427ff9f687858fdd61097053742391a9f6b" + ], + "version": "==0.8.1" + }, + "pluggy": { + "hashes": [ + "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", + "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" + ], + "index": "pypi", + "version": "==1.0.0" + }, + "py": { + "hashes": [ + "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", + "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" + ], + "index": "pypi", + "version": "==1.11.0" + }, + "py-algorand-sdk": { + "hashes": [ + "sha256:2a029dbd0b20f23ea43c13c1113c224d6fa89d7280db9768520c7973dccb4e9c", + "sha256:59c868b6c7426f356462fcfb063a237382b86a0e5e93fb6274c8723f5a3b6aa1" + ], + "index": "pypi", + "version": "==1.10.0b1" + }, + "pycparser": { + "hashes": [ + "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", + "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" + ], + "index": "pypi", + "version": "==2.21" + }, + "pycryptodomex": { + "hashes": [ + "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", + "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", + "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", + "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", + "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", + "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", + "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", + "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", + "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", + "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", + "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", + "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", + "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", + "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", + "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", + "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", + "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", + "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", + "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", + "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", + "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", + "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", + "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", + "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", + "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", + "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", + "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", + "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", + "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", + "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" + ], + "index": "pypi", + "version": "==3.12.0" + }, + "pydantic": { + "hashes": [ + "sha256:085ca1de245782e9b46cefcf99deecc67d418737a1fd3f6a4f511344b613a5b3", + "sha256:086254884d10d3ba16da0588604ffdc5aab3f7f09557b998373e885c690dd398", + "sha256:0b6037175234850ffd094ca77bf60fb54b08b5b22bc85865331dd3bda7a02fa1", + "sha256:0fe476769acaa7fcddd17cadd172b156b53546ec3614a4d880e5d29ea5fbce65", + "sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4", + "sha256:2cc6a4cb8a118ffec2ca5fcb47afbacb4f16d0ab8b7350ddea5e8ef7bcc53a16", + "sha256:2ee7e3209db1e468341ef41fe263eb655f67f5c5a76c924044314e139a1103a2", + "sha256:3011b975c973819883842c5ab925a4e4298dffccf7782c55ec3580ed17dc464c", + "sha256:3c3b035103bd4e2e4a28da9da7ef2fa47b00ee4a9cf4f1a735214c1bcd05e0f6", + "sha256:4c68c3bc88dbda2a6805e9a142ce84782d3930f8fdd9655430d8576315ad97ce", + "sha256:574936363cd4b9eed8acdd6b80d0143162f2eb654d96cb3a8ee91d3e64bf4cf9", + "sha256:5a79330f8571faf71bf93667d3ee054609816f10a259a109a0738dac983b23c3", + "sha256:5e48ef4a8b8c066c4a31409d91d7ca372a774d0212da2787c0d32f8045b1e034", + "sha256:6c5b77947b9e85a54848343928b597b4f74fc364b70926b3c4441ff52620640c", + "sha256:742645059757a56ecd886faf4ed2441b9c0cd406079c2b4bee51bcc3fbcd510a", + "sha256:7bdfdadb5994b44bd5579cfa7c9b0e1b0e540c952d56f627eb227851cda9db77", + "sha256:815ddebb2792efd4bba5488bc8fde09c29e8ca3227d27cf1c6990fc830fd292b", + "sha256:8b5ac0f1c83d31b324e57a273da59197c83d1bb18171e512908fe5dc7278a1d6", + "sha256:96f240bce182ca7fe045c76bcebfa0b0534a1bf402ed05914a6f1dadff91877f", + "sha256:a733965f1a2b4090a5238d40d983dcd78f3ecea221c7af1497b845a9709c1721", + "sha256:ab624700dc145aa809e6f3ec93fb8e7d0f99d9023b713f6a953637429b437d37", + "sha256:b2571db88c636d862b35090ccf92bf24004393f85c8870a37f42d9f23d13e032", + "sha256:bbbc94d0c94dd80b3340fc4f04fd4d701f4b038ebad72c39693c794fd3bc2d9d", + "sha256:c0727bda6e38144d464daec31dff936a82917f431d9c39c39c60a26567eae3ed", + "sha256:c556695b699f648c58373b542534308922c46a1cda06ea47bc9ca45ef5b39ae6", + "sha256:c86229333cabaaa8c51cf971496f10318c4734cf7b641f08af0a6fbf17ca3054", + "sha256:c8d7da6f1c1049eefb718d43d99ad73100c958a5367d30b9321b092771e96c25", + "sha256:c8e9dcf1ac499679aceedac7e7ca6d8641f0193c591a2d090282aaf8e9445a46", + "sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5", + "sha256:d1e4c28f30e767fd07f2ddc6f74f41f034d1dd6bc526cd59e63a82fe8bb9ef4c", + "sha256:d9c9bdb3af48e242838f9f6e6127de9be7063aad17b32215ccc36a09c5cf1070", + "sha256:dee5ef83a76ac31ab0c78c10bd7d5437bfdb6358c95b91f1ba7ff7b76f9996a1", + "sha256:e0896200b6a40197405af18828da49f067c2fa1f821491bc8f5bde241ef3f7d7", + "sha256:f5a64b64ddf4c99fe201ac2724daada8595ada0d102ab96d019c1555c2d6441d", + "sha256:f947352c3434e8b937e3aa8f96f47bdfe6d92779e44bb3f41e4c213ba6a32145" + ], + "index": "pypi", + "version": "==1.9.0" + }, + "pynacl": { + "hashes": [ + "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", + "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", + "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", + "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", + "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", + "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", + "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", + "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", + "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", + "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543" + ], + "index": "pypi", + "version": "==1.5.0" + }, + "pyparsing": { + "hashes": [ + "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", + "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" + ], + "index": "pypi", + "version": "==3.0.6" + }, + "pyteal": { + "hashes": [ + "sha256:6c140db6ac365f438dc979c7de4153686ef97b762b9c4efe23bba0db4ff699e5", + "sha256:a72d1f0859f2248459bbcdbdfcd8cf09023ea003b121f0dbaf58289b8167d20c" + ], + "index": "pypi", + "version": "==v0.10.0" + }, + "pytest": { + "hashes": [ + "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89", + "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134" + ], + "index": "pypi", + "version": "==6.2.5" + }, + "pytest-depends": { + "hashes": [ + "sha256:90a28e2b87b75b18abd128c94015248544acac20e4392e9921e5a86f93319dfe", + "sha256:a1df072bcc93d77aca3f0946903f5fed8af2d9b0056db1dfc9ed5ac164ab0642" + ], + "index": "pypi", + "version": "==1.0.1" + }, + "pytest-forked": { + "hashes": [ + "sha256:8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e", + "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8" + ], + "index": "pypi", + "version": "==1.4.0" + }, + "pytest-xdist": { + "hashes": [ + "sha256:4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf", + "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65" + ], + "index": "pypi", + "version": "==2.5.0" + }, + "pyyaml": { + "hashes": [ + "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293", + "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b", + "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57", + "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b", + "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4", + "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07", + "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba", + "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9", + "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287", + "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513", + "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0", + "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0", + "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92", + "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f", + "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2", + "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc", + "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c", + "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86", + "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4", + "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c", + "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34", + "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b", + "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c", + "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb", + "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737", + "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3", + "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d", + "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53", + "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78", + "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803", + "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a", + "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174", + "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5" + ], + "index": "pypi", + "version": "==6.0" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.16.0" + }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "index": "pypi", + "version": "==0.10.2" + }, + "toolz": { + "hashes": [ + "sha256:6b312d5e15138552f1bda8a4e66c30e236c831b612b2bf0005f8a1df10a4bc33", + "sha256:a5700ce83414c64514d82d60bcda8aabfde092d1c1a8663f9200c07fdcc6da8f" + ], + "markers": "python_version >= '3.5'", + "version": "==0.11.2" + }, + "typing-extensions": { + "hashes": [ + "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", + "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" + ], + "index": "pypi", + "version": "==4.0.1" + }, + "uvarint": { + "hashes": [ + "sha256:7cc17481c9af8ebe3978f5357412b57ff93ce8b14712236338f782cc8ae9a989", + "sha256:9dcc98ad92b642c57494bed9370c4f93479d2d36223b2c3702823f0aa8b1a9a3" + ], + "index": "pypi", + "version": "==1.2.0" + }, + "zipp": { + "hashes": [ + "sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832", + "sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc" + ], + "markers": "python_version >= '3.6'", + "version": "==3.6.0" + } + }, + "develop": {} +} diff --git a/algorand/README.md b/algorand/README.md new file mode 100644 index 000000000..f1a70a388 --- /dev/null +++ b/algorand/README.md @@ -0,0 +1,108 @@ +Wormhole Support for Algorand +============================= + +This directory contains the components needed to support full Wormhole functionality under the Algorand blockchain platform. + +## Component overview +--------------------- + +This system is comprised of the following main components: + +* **Core contract (`wormhole_core.py`)**: Algorand stateful contract with entrypoints for publishing messages (VAAs), verification of VAA signatures, and triggering of governance chores. This will be referred as _CoreContract_ in this document. + +* **Token bridge contract (`token_bridge.py`)**: Algorand stateful contract supporting cross-chain bridging, exposing entrypoints for exchanging attestations, native tokens and ASAs, and triggering of governance. This will be referred as _TokenBridge_ in this document. + +* **VAA verification stateless program (`vaa_verify.py`)**: Stateless program for verifying the signatures of a Wormhole VAA payload against the set of active guardian public keys. This will be referred as _VaaVerify_ in this document. + +* **Dynamic storage stateless program (`TmplSig.py`)**: A stateless program that is bound to the main core and token bridge contracts to provide dynamic storage spaces addressable as a raw blob of bytes. See `local_blob.py`. This will be referred as _TmplSig_ in this document. + +Helper utilities and code include support PyTEAL code, deployment tools and tests. + +## System Architecture +---------------------- + +### _TmplSig_ details +-------------------- + +This stateless program code is parametrized with several values that give different output address. The stateless code will check for several transaction group parameters accordingly. + +|Text |Replaced by | +|------|------------| +|`TMPL_ADDR_IDX`| Where storage starts interpreting the space as a raw array of bytes | +|`TMPL_EMITTER_ID` | Concatenation of chain Id + emitter Id in VAAs to be processed, or a hardcoded string identifying the type of information stored e.g `guardian` utf8 string stored in hex. | +|`TMPL_SEED_AMT` | The amount that is paid in Gtxn[0] transaction group fee | +|`TMPL_APP_ID` | Application Id of _CoreContract_, _TokenBridge_, etc that is specified in Gtxn[1] for **opt-in** transaction | +|`TMPL_APP_ADDRESS`| Escrow address of the stateful contract specified in `APP_ID`. Used for **rekey transaction** in Gtxn[2]| + + +* Local-state associated with the _Tmplsig_ accounts are used as dynamic storage. The technique is to access this local storage as a plain array of bytes instead of the typical key/value structure. With the current Algorand parameters, we have 127 * 15 ~ 2K of storage to be used random-access-like. +* The contract accounts addresses are generated by compilation of a stateless code parametrized by several parameters. In the system, the following contract accounts are generated: + * Account (`seq_addr`) for storing verified sequence number bits based on chainId,emitter,`int(vaa.sequence / MAX_BITS)` where MAX_BITS = 15240. This allows the system to reject duplicated VAAs for the last 2K sequence numbers. + * Account (`guardian_addr` and `new_guardian_addr`) for storing total guardian count , the guardian public keys and guardian set expiration time. +* Once generated, the accounts are opted-in and rekeyed to the core application. + +Briefly, this is the transaction group when _TmplSig_ is "attached" to a stateful app: + +|Tx#| Semantics | +|-|-| +|0 | Payment Txn of `TMPL_SEED_AMT` ALGOs to fund operation | +|1 | Optin of LogicSig to target stateful contract `TMPL_APP_ID` for the app to use Logicsig account local storage | +|2 | Rekey of LogicSig to escrow address for the smart contract to become the sole "governor" of the Logicsig account address | + + +## Core Contract: Functional Description +---------------------------------------- +### Initialization stage +The initialization call needs a governance VAA to be passed in, typically to setup initial guardian list. The init call will: +* store the _VaaVerify_ hash in the `vphash` global state key +* check for the creator address, set `booted` global state to `1` +* check for duplicate VAA +* handle the governance VAA passed as argument. + +See below on how governance VAAs are processed, and how duplicate detection technique is used. + +### publishMessage + +The `publishMessage` call will retrieve the current sequence number from related _TmplSig_ local store, increment in by 1, store the new sequence number and emit a Log message which can be picked by Wormhole network for subsequently creating a guardian-signed VAA message. + +### hdlGovernance + +Governance messages can carry requests for: + +* Update the active guardian set +* Upgrade contracts: For Algorand, an upgrade-contract governance VAA must contain the hash of the program that is approved as an upgrade (stored in global `validUpdateApproveHash`). The upgrade process itself is triggered with the **update** action, where the clear and approval program hashes are checked against what the governance VAA carried. If they differ, an assertion is thrown and the update call is aborted. A successful call writes an onchain Log with the new hashes and allows the update process to go on. +* Setting the per-message fee +* Retrieving previously paid message fees + +A governance request packed in a VAA must be verified by a `verifyVaa` call in the transaction group. + +### vaaVerify + +The VAA verify call will work by design *only* in a transaction group structured as: + +| TX | args | accounts | sender | +| ---------- | ------------------------------------------------------- | ----------------------- | -------------------- | +| verifySigs | [sigs0..n, keyset0..n, digest] | seq_addr, guardian_addr | vaa_verify_stateless | +| verifySigs | ... | seq_addr, guardian_addr | vaa_verify_stateless +| verifyVAA | vaa | seq_addr, guardian_addr | foundation | + +Keep in mind that depending on the number of signatures to verify there can be one or several _verifySigs_ calls working in tandem with the _VaaVerify_ stateless program. This depends on how many signatures we can verify on a single TX. At time of this writing, considering the opcode budget limitation of AVM 1.1, a total of nine (9) signatures can be verified at once, so for the current 19 guardians three _verifySigs_ calls would be needed for verifying signatures 0..8, 9..17, 18. + +A successful call must: + +* Retrieve the guardian keys from the proper local dynamic storage +* Validate if the VAA passed in Argument #1 has enough guardians to be verified +* Check that it's not expired. +* Verify that each _verifySigs_ TX is validated by the correct stateless _VerifyVaa_ +* Verify that each _verifySigs_ TX is verifying the expected signature subset. +* Verify that each _verifySigs_ TX is verifying against the same guardian keys. +* Verify that each _verifySigs_ TX is verifying the same VAA. + +The vaaVerify call does allow *nop* (dummy) TX in the group to maximize opcode budgets and/or storage capacity. After the `verifyVAA` call, a client can issue more transactions with the fact that the VAA was verified. + +## Appendix: Duplicate verification +------------------------------------ +To detect duplicate VAA sequence numbers the following technique is used: + +* For each key in local state, there is an associated value entry. The total space of value-entries is 127*15, we have 2K of addressable space using the `LocalBlob` class. +* A _TmplSig_ stateless account is generated using the 2K space as a bit field, yielding 15240 bits. So for ~16K consecutive VAA numbers, the contract code sets a bit for identifying already verified VAAs. Based on setting the stateless `TMPL_ADDR_IDX` to formula `vaa_sequence_number / 15240`, we have designated storage for marking VAAs in consecutive 16k-bit blocks. diff --git a/algorand/TmplSig.py b/algorand/TmplSig.py new file mode 100644 index 000000000..f732135ed --- /dev/null +++ b/algorand/TmplSig.py @@ -0,0 +1,143 @@ +from time import time, sleep +from typing import List, Tuple, Dict, Any, Optional, Union +from base64 import b64decode +import base64 +import random +import hashlib +import uuid +import sys +import json +import uvarint +import pprint + +from local_blob import LocalBlob + +from algosdk.v2client.algod import AlgodClient +from algosdk.kmd import KMDClient +from algosdk import account, mnemonic +from algosdk.encoding import decode_address +from algosdk.future import transaction +from pyteal import compileTeal, Mode, Expr +from pyteal import * +from algosdk.logic import get_application_address + +from algosdk.future.transaction import LogicSigAccount + +class TmplSig: + """KeySig class reads in a json map containing assembly details of a template smart signature and allows you to populate it with the variables + In this case we are only interested in a single variable, the key which is a byte string to make the address unique. + In this demo we're using random strings but in practice you can choose something meaningful to your application + """ + + def __init__(self, name): + # Read the source map + +# with open("{}.json".format(name)) as f: +# self.map = json.loads(f.read()) + + + self.map = {"name":"lsig.teal","version":6,"source":"","bytecode":"BiABAYEASIAASDEQgQYSRDEZIhJEMRiBABJEMSCAABJEMQGBABJEMQkyAxJEMRUyAxJEIg==", + "template_labels":{ + "TMPL_ADDR_IDX":{"source_line":3,"position":5,"bytes":False}, + "TMPL_EMITTER_ID":{"source_line":5,"position":8,"bytes":True}, + "TMPL_APP_ID":{"source_line":16,"position":24,"bytes":False}, + "TMPL_APP_ADDRESS":{"source_line":20,"position":30,"bytes":True} + }, + "label_map":{},"line_map":[0,1,4,6,7,9,10,12,14,15,16,18,19,20,21,23,25,26,27,29,31,32,33,35,37,38,39,41,43,44,45,47,49,50,51] + } + + + self.src = base64.b64decode(self.map["bytecode"]) + self.sorted = dict( + sorted( + self.map["template_labels"].items(), + key=lambda item: item[1]["position"], + ) + ) + + def populate(self, values: Dict[str, Union[str, int]]) -> LogicSigAccount: + """populate uses the map to fill in the variable of the bytecode and returns a logic sig with the populated bytecode""" + # Get the template source + contract = list(base64.b64decode(self.map["bytecode"])) + + shift = 0 + for k, v in self.sorted.items(): + if k in values: + pos = v["position"] + shift + if v["bytes"]: + val = bytes.fromhex(values[k]) + lbyte = uvarint.encode(len(val)) + # -1 to account for the existing 00 byte for length + shift += (len(lbyte) - 1) + len(val) + # +1 to overwrite the existing 00 byte for length + contract[pos : pos + 1] = lbyte + val + else: + val = uvarint.encode(values[k]) + # -1 to account for existing 00 byte + shift += len(val) - 1 + # +1 to overwrite existing 00 byte + contract[pos : pos + 1] = val + + # Create a new LogicSigAccount given the populated bytecode, + + #pprint.pprint({"values": values, "contract": bytes(contract).hex()}) + + return LogicSigAccount(bytes(contract)) + + def get_bytecode_chunk(self, idx: int) -> Bytes: + start = 0 + if idx > 0: + start = list(self.sorted.values())[idx - 1]["position"] + 1 + + stop = len(self.src) + if idx < len(self.sorted): + stop = list(self.sorted.values())[idx]["position"] + + chunk = self.src[start:stop] + return Bytes(chunk) + + def get_bytecode_raw(self, idx: int): + start = 0 + if idx > 0: + start = list(self.sorted.values())[idx - 1]["position"] + 1 + + stop = len(self.src) + if idx < len(self.sorted): + stop = list(self.sorted.values())[idx]["position"] + + chunk = self.src[start:stop] + return chunk + + def get_sig_tmpl(self): + def sig_tmpl(): + admin_app_id = ScratchVar() + admin_address= ScratchVar() + + return Seq( + # Just putting adding this as a tmpl var to make the address unique and deterministic + # We don't actually care what the value is, pop it + Pop(Tmpl.Int("TMPL_ADDR_IDX")), + Pop(Tmpl.Bytes("TMPL_EMITTER_ID")), + + Assert(Txn.type_enum() == TxnType.ApplicationCall), + Assert(Txn.on_completion() == OnComplete.OptIn), + Assert(Txn.application_id() == Tmpl.Int("TMPL_APP_ID")), + Assert(Txn.rekey_to() == Tmpl.Bytes("TMPL_APP_ADDRESS")), + + Assert(Txn.fee() == Int(0)), + Assert(Txn.close_remainder_to() == Global.zero_address()), + Assert(Txn.asset_close_to() == Global.zero_address()), + + Approve() + ) + + return compileTeal(sig_tmpl(), mode=Mode.Signature, version=6, assembleConstants=True) + +if __name__ == '__main__': + core = TmplSig("sig") +# client = AlgodClient("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "http://localhost:4001") +# pprint.pprint(client.compile( core.get_sig_tmpl())) + + with open("sig.tmpl.teal", "w") as f: + f.write(core.get_sig_tmpl()) + diff --git a/algorand/admin.py b/algorand/admin.py new file mode 100644 index 000000000..445006d12 --- /dev/null +++ b/algorand/admin.py @@ -0,0 +1,1383 @@ +# python3 -m pip install pycryptodomex uvarint pyteal web3 coincurve + +from os.path import exists +from time import time, sleep +from eth_abi import encode_single, encode_abi +from typing import List, Tuple, Dict, Any, Optional, Union +from base64 import b64decode +import base64 +import random +import time +import hashlib +import uuid +import sys +import json +import uvarint +from local_blob import LocalBlob +from wormhole_core import getCoreContracts +from TmplSig import TmplSig +import argparse +from gentest import GenTest + +from algosdk.v2client.algod import AlgodClient +from algosdk.kmd import KMDClient +from algosdk import account, mnemonic +from algosdk.encoding import decode_address, encode_address +from algosdk.future import transaction +from pyteal import compileTeal, Mode, Expr +from pyteal import * +from algosdk.logic import get_application_address +from vaa_verify import get_vaa_verify + +from Cryptodome.Hash import keccak + +from algosdk.future.transaction import LogicSig + +from token_bridge import get_token_bridge + +from algosdk.v2client import indexer + +import pprint + +max_keys = 15 +max_bytes_per_key = 127 +bits_per_byte = 8 + +bits_per_key = max_bytes_per_key * bits_per_byte +max_bytes = max_bytes_per_key * max_keys +max_bits = bits_per_byte * max_bytes + +class Account: + """Represents a private key and address for an Algorand account""" + + def __init__(self, privateKey: str) -> None: + self.sk = privateKey + self.addr = account.address_from_private_key(privateKey) + print (privateKey) + print (" " + self.getMnemonic()) + print (" " + self.addr) + + def getAddress(self) -> str: + return self.addr + + def getPrivateKey(self) -> str: + return self.sk + + def getMnemonic(self) -> str: + return mnemonic.from_private_key(self.sk) + + @classmethod + def FromMnemonic(cls, m: str) -> "Account": + return cls(mnemonic.to_private_key(m)) + +class PendingTxnResponse: + def __init__(self, response: Dict[str, Any]) -> None: + self.poolError: str = response["pool-error"] + self.txn: Dict[str, Any] = response["txn"] + + self.applicationIndex: Optional[int] = response.get("application-index") + self.assetIndex: Optional[int] = response.get("asset-index") + self.closeRewards: Optional[int] = response.get("close-rewards") + self.closingAmount: Optional[int] = response.get("closing-amount") + self.confirmedRound: Optional[int] = response.get("confirmed-round") + self.globalStateDelta: Optional[Any] = response.get("global-state-delta") + self.localStateDelta: Optional[Any] = response.get("local-state-delta") + self.receiverRewards: Optional[int] = response.get("receiver-rewards") + self.senderRewards: Optional[int] = response.get("sender-rewards") + + self.innerTxns: List[Any] = response.get("inner-txns", []) + self.logs: List[bytes] = [b64decode(l) for l in response.get("logs", [])] + +class PortalCore: + def __init__(self) -> None: + self.gt = None + self.foundation = None + self.devnet = False + + self.ALGOD_ADDRESS = "http://localhost:4001" + self.ALGOD_TOKEN = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + self.FUNDING_AMOUNT = 100_000_000_000 + + self.KMD_ADDRESS = "http://localhost:4002" + self.KMD_TOKEN = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + self.KMD_WALLET_NAME = "unencrypted-default-wallet" + self.KMD_WALLET_PASSWORD = "" + + self.INDEXER_TOKEN = "a" * 64 + self.INDEXER_ADDRESS = 'http://localhost:8980' + self.INDEXER_ROUND = 0 + self.NOTE_PREFIX = 'publishMessage'.encode() + + self.myindexer = None + + self.seed_amt = int(1002000) # The black magic in this number... + self.cache = {} + self.asset_cache = {} + + self.kmdAccounts : Optional[List[Account]] = None + + self.accountList : List[Account] = [] + self.zeroPadBytes = "00"*32 + + self.tsig = TmplSig("sig") + + + def init(self, args) -> None: + self.args = args + self.ALGOD_ADDRESS = args.algod_address + self.ALGOD_TOKEN = args.algod_token + self.KMD_ADDRESS = args.kmd_address + self.KMD_TOKEN = args.kmd_token + self.KMD_WALLET_NAME = args.kmd_name + self.KMD_WALLET_PASSWORD = args.kmd_password + self.TARGET_ACCOUNT = args.mnemonic + self.coreid = args.coreid + self.tokenid = args.tokenid + + if exists(self.args.env): + if self.gt == None: + self.gt = GenTest(False) + + with open(self.args.env, encoding = 'utf-8') as f: + for line in f: + e = line.rstrip('\n').split("=") + if "INIT_SIGNERS_CSV" in e[0]: + self.gt.guardianKeys = e[1].split(",") + if "INIT_SIGNERS_KEYS_CSV" in e[0]: + self.gt.guardianPrivKeys = e[1].split(",") + print("guardianPrivKeys=" + str(self.gt.guardianPrivKeys)) + + def waitForTransaction( + self, client: AlgodClient, txID: str, timeout: int = 10 + ) -> PendingTxnResponse: + lastStatus = client.status() + lastRound = lastStatus["last-round"] + startRound = lastRound + + while lastRound < startRound + timeout: + pending_txn = client.pending_transaction_info(txID) + + if pending_txn.get("confirmed-round", 0) > 0: + return PendingTxnResponse(pending_txn) + + if pending_txn["pool-error"]: + raise Exception("Pool error: {}".format(pending_txn["pool-error"])) + + lastStatus = client.status_after_block(lastRound + 1) + + lastRound += 1 + + raise Exception( + "Transaction {} not confirmed after {} rounds".format(txID, timeout) + ) + + def getKmdClient(self) -> KMDClient: + return KMDClient(self.KMD_TOKEN, self.KMD_ADDRESS) + + def getGenesisAccounts(self) -> List[Account]: + if self.kmdAccounts is None: + kmd = self.getKmdClient() + + wallets = kmd.list_wallets() + walletID = None + for wallet in wallets: + if wallet["name"] == self.KMD_WALLET_NAME: + walletID = wallet["id"] + break + + if walletID is None: + raise Exception("Wallet not found: {}".format(self.KMD_WALLET_NAME)) + + walletHandle = kmd.init_wallet_handle(walletID, self.KMD_WALLET_PASSWORD) + + try: + addresses = kmd.list_keys(walletHandle) + privateKeys = [ + kmd.export_key(walletHandle, self.KMD_WALLET_PASSWORD, addr) + for addr in addresses + ] + self.kmdAccounts = [Account(sk) for sk in privateKeys] + finally: + kmd.release_wallet_handle(walletHandle) + + return self.kmdAccounts + + def getTemporaryAccount(self, client: AlgodClient) -> Account: + if len(self.accountList) == 0: + sks = [account.generate_account()[0] for i in range(3)] + self.accountList = [Account(sk) for sk in sks] + + genesisAccounts = self.getGenesisAccounts() + suggestedParams = client.suggested_params() + + txns: List[transaction.Transaction] = [] + for i, a in enumerate(self.accountList): + fundingAccount = genesisAccounts[i % len(genesisAccounts)] + txns.append( + transaction.PaymentTxn( + sender=fundingAccount.getAddress(), + receiver=a.getAddress(), + amt=self.FUNDING_AMOUNT, + sp=suggestedParams, + ) + ) + + txns = transaction.assign_group_id(txns) + signedTxns = [ + txn.sign(genesisAccounts[i % len(genesisAccounts)].getPrivateKey()) + for i, txn in enumerate(txns) + ] + + client.send_transactions(signedTxns) + + self.waitForTransaction(client, signedTxns[0].get_txid()) + + return self.accountList.pop() + + def getAlgodClient(self) -> AlgodClient: + return AlgodClient(self.ALGOD_TOKEN, self.ALGOD_ADDRESS) + + def getBalances(self, client: AlgodClient, account: str) -> Dict[int, int]: + balances: Dict[int, int] = dict() + + accountInfo = client.account_info(account) + + # set key 0 to Algo balance + balances[0] = accountInfo["amount"] + + assets: List[Dict[str, Any]] = accountInfo.get("assets", []) + for assetHolding in assets: + assetID = assetHolding["asset-id"] + amount = assetHolding["amount"] + balances[assetID] = amount + + return balances + + def fullyCompileContract(self, client: AlgodClient, contract: Expr) -> bytes: + teal = compileTeal(contract, mode=Mode.Application, version=6) + response = client.compile(teal) + return response + + # helper function that formats global state for printing + def format_state(self, state): + formatted = {} + for item in state: + key = item['key'] + value = item['value'] + formatted_key = base64.b64decode(key).decode('utf-8') + if value['type'] == 1: + # byte string + if formatted_key == 'voted': + formatted_value = base64.b64decode(value['bytes']).decode('utf-8') + else: + formatted_value = value['bytes'] + formatted[formatted_key] = formatted_value + else: + # integer + formatted[formatted_key] = value['uint'] + return formatted + + # helper function to read app global state + def read_global_state(self, client, addr, app_id): + results = client.account_info(addr) + apps_created = results['created-apps'] + for app in apps_created: + if app['id'] == app_id and 'global-state' in app['params']: + return self.format_state(app['params']['global-state']) + return {} + + def read_state(self, client, addr, app_id): + results = client.account_info(addr) + apps_created = results['created-apps'] + for app in apps_created: + if app['id'] == app_id: + return app + return {} + + def encoder(self, type, val): + if type == 'uint8': + return encode_single(type, val).hex()[62:64] + if type == 'uint16': + return encode_single(type, val).hex()[60:64] + if type == 'uint32': + return encode_single(type, val).hex()[56:64] + if type == 'uint64': + return encode_single(type, val).hex()[64-(16):64] + if type == 'uint128': + return encode_single(type, val).hex()[64-(32):64] + if type == 'uint256' or type == 'bytes32': + return encode_single(type, val).hex()[64-(64):64] + raise Exception("you suck") + + def devnetUpgradeVAA(self): + v = self.genUpgradePayload() + print("core payload: " + str(v[0])) + print("token payload: " + str(v[1])) + + if self.gt == None: + self.gt = GenTest(False) + + emitter = bytes.fromhex(self.zeroPadBytes[0:(31*2)] + "04") + + guardianSet = self.getGovSet() + + print("guardianSet: " + str(guardianSet)) + + nonce = int(random.random() * 20000) + ret = [ + self.gt.createSignedVAA(guardianSet, self.gt.guardianPrivKeys, int(time.time()), nonce, 1, emitter, int(random.random() * 20000), 32, 8, v[0]), + self.gt.createSignedVAA(guardianSet, self.gt.guardianPrivKeys, int(time.time()), nonce, 1, emitter, int(random.random() * 20000), 32, 8, v[1]), + ] + +# pprint.pprint(self.parseVAA(bytes.fromhex(ret[0]))) +# pprint.pprint(self.parseVAA(bytes.fromhex(ret[1]))) + + return ret + + def getMessageFee(self): + s = self.client.application_info(self.coreid)["params"]["global-state"] + k = base64.b64encode(b"MessageFee").decode('utf-8') + for x in s: + if x["key"] == k: + return x["value"]["uint"] + return -1 + + def getGovSet(self): + s = self.client.application_info(self.coreid)["params"]["global-state"] + k = base64.b64encode(b"currentGuardianSetIndex").decode('utf-8') + for x in s: + if x["key"] == k: + return x["value"]["uint"] + return -1 + + def genUpgradePayload(self): + approval, clear = getCoreContracts(False, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + + b = self.zeroPadBytes[0:(28*2)] + b += self.encoder("uint8", ord("C")) + b += self.encoder("uint8", ord("o")) + b += self.encoder("uint8", ord("r")) + b += self.encoder("uint8", ord("e")) + b += self.encoder("uint8", 1) + b += self.encoder("uint16", 8) + + b += decode_address(approval["hash"]).hex() + + ret = [b] + + approval, clear = get_token_bridge(False, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + + + b = self.zeroPadBytes[0:((32 -11)*2)] + b += self.encoder("uint8", ord("T")) + b += self.encoder("uint8", ord("o")) + b += self.encoder("uint8", ord("k")) + b += self.encoder("uint8", ord("e")) + b += self.encoder("uint8", ord("n")) + b += self.encoder("uint8", ord("B")) + b += self.encoder("uint8", ord("r")) + b += self.encoder("uint8", ord("i")) + b += self.encoder("uint8", ord("d")) + b += self.encoder("uint8", ord("g")) + b += self.encoder("uint8", ord("e")) + + b += self.encoder("uint8", 2) # action + b += self.encoder("uint16", 8) # target chain + b += decode_address(approval["hash"]).hex() + print(decode_address(approval["hash"]).hex()) + + ret.append(b) + return ret + + def createPortalCoreApp( + self, + client: AlgodClient, + sender: Account, + ) -> int: + approval, clear = getCoreContracts(False, self.args.core_approve, self.args.core_clear, client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + + globalSchema = transaction.StateSchema(num_uints=8, num_byte_slices=40) + localSchema = transaction.StateSchema(num_uints=0, num_byte_slices=16) + + app_args = [ ] + + txn = transaction.ApplicationCreateTxn( + sender=sender.getAddress(), + on_complete=transaction.OnComplete.NoOpOC, + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + global_schema=globalSchema, + local_schema=localSchema, + extra_pages = 1, + app_args=app_args, + sp=client.suggested_params(), + ) + + signedTxn = txn.sign(sender.getPrivateKey()) + + client.send_transaction(signedTxn) + + response = self.waitForTransaction(client, signedTxn.get_txid()) + assert response.applicationIndex is not None and response.applicationIndex > 0 + + # Lets give it a bit of money so that it is not a "ghost" account + txn = transaction.PaymentTxn(sender = sender.getAddress(), sp = client.suggested_params(), receiver = get_application_address(response.applicationIndex), amt = 100000) + signedTxn = txn.sign(sender.getPrivateKey()) + client.send_transaction(signedTxn) + + return response.applicationIndex + + def createTokenBridgeApp( + self, + client: AlgodClient, + sender: Account, + ) -> int: + approval, clear = get_token_bridge(False, self.args.token_approve, self.args.token_clear, client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + + if len(b64decode(approval["result"])) > 4060: + print("token bridge contract is too large... This might prevent updates later") + + globalSchema = transaction.StateSchema(num_uints=4, num_byte_slices=30) + localSchema = transaction.StateSchema(num_uints=0, num_byte_slices=16) + + app_args = [self.coreid, decode_address(get_application_address(self.coreid))] + + txn = transaction.ApplicationCreateTxn( + sender=sender.getAddress(), + on_complete=transaction.OnComplete.NoOpOC, + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + global_schema=globalSchema, + local_schema=localSchema, + app_args=app_args, + extra_pages = 2, + sp=client.suggested_params(), + ) + + signedTxn = txn.sign(sender.getPrivateKey()) + + client.send_transaction(signedTxn) + + response = self.waitForTransaction(client, signedTxn.get_txid()) + #pprint.pprint(response.__dict__) + assert response.applicationIndex is not None and response.applicationIndex > 0 + + # Lets give it a bit of money so that it is not a "ghost" account + txn = transaction.PaymentTxn(sender = sender.getAddress(), sp = client.suggested_params(), receiver = get_application_address(response.applicationIndex), amt = 100000) + signedTxn = txn.sign(sender.getPrivateKey()) + client.send_transaction(signedTxn) + + return response.applicationIndex + + def account_exists(self, client, app_id, addr): + try: + ai = client.account_info(addr) + if "apps-local-state" not in ai: + return False + + for app in ai["apps-local-state"]: + if app["id"] == app_id: + return True + except: + print("Failed to find account {}".format(addr)) + return False + + def optin(self, client, sender, app_id, idx, emitter, doCreate=True): + aa = decode_address(get_application_address(app_id)).hex() + + lsa = self.tsig.populate( + { + "TMPL_APP_ID": app_id, + "TMPL_APP_ADDRESS": aa, + "TMPL_ADDR_IDX": idx, + "TMPL_EMITTER_ID": emitter, + } + ) + + sig_addr = lsa.address() + + if sig_addr not in self.cache and not self.account_exists(client, app_id, sig_addr): + if doCreate: +# pprint.pprint(("Creating", app_id, idx, emitter, sig_addr)) + + # Create it + sp = client.suggested_params() + + seed_txn = transaction.PaymentTxn(sender = sender.getAddress(), + sp = sp, + receiver = sig_addr, + amt = self.seed_amt) + seed_txn.fee = seed_txn.fee * 2 + + optin_txn = transaction.ApplicationOptInTxn(sig_addr, sp, app_id, rekey_to=get_application_address(app_id)) + optin_txn.fee = 0 + + transaction.assign_group_id([seed_txn, optin_txn]) + + signed_seed = seed_txn.sign(sender.getPrivateKey()) + signed_optin = transaction.LogicSigTransaction(optin_txn, lsa) + + client.send_transactions([signed_seed, signed_optin]) + self.waitForTransaction(client, signed_optin.get_txid()) + + self.cache[sig_addr] = True + + return sig_addr + + def parseSeqFromLog(self, txn): + return int.from_bytes(b64decode(txn.innerTxns[0]["logs"][0]), "big") + + def getCreator(self, client, sender, asset_id): + return client.asset_info(asset_id)["params"]["creator"] + + def sendTxn(self, client, sender, txns, doWait): + transaction.assign_group_id(txns) + + grp = [] + pk = sender.getPrivateKey() + for t in txns: + grp.append(t.sign(pk)) + + client.send_transactions(grp) + if doWait: + return self.waitForTransaction(client, grp[-1].get_txid()) + else: + return grp[-1].get_txid() + + def bootGuardians(self, vaa, client, sender, coreid): + p = self.parseVAA(vaa) + if "NewGuardianSetIndex" not in p: + raise Exception("invalid guardian VAA") + + seq_addr = self.optin(client, sender, coreid, int(p["sequence"] / max_bits), p["chainRaw"].hex() + p["emitter"].hex()) + guardian_addr = self.optin(client, sender, coreid, p["index"], b"guardian".hex()) + newguardian_addr = self.optin(client, sender, coreid, p["NewGuardianSetIndex"], b"guardian".hex()) + + # wormhole is not a cheap protocol... we need to buy ourselves + # some extra CPU cycles by having an early txn do nothing. + # This leaves cycles over for later txn's in the same group + + sp = client.suggested_params() + + txns = [ + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop", b"0"], + sp=sp + ), + + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop", b"1"], + sp=sp + ), + + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"init", vaa, decode_address(self.vaa_verify["hash"])], + accounts=[seq_addr, guardian_addr, newguardian_addr], + sp=sp + ), + + transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=self.vaa_verify["hash"], + amt=100000, + sp=sp + ) + ] + + self.sendTxn(client, sender, txns, True) + + def decodeLocalState(self, client, sender, appid, addr): + app_state = None + ai = client.account_info(addr) + for app in ai["apps-local-state"]: + if app["id"] == appid: + app_state = app["key-value"] + + ret = b'' + if None != app_state: + vals = {} + e = bytes.fromhex("00"*127) + for kv in app_state: + k = base64.b64decode(kv["key"]) + if k == "meta": + continue + key = int.from_bytes(k, "big") + v = base64.b64decode(kv["value"]["bytes"]) + if v != e: + vals[key] = v + for k in sorted(vals.keys()): + ret = ret + vals[k] + return ret + + # There is no client side duplicate suppression, error checking, or validity + # checking. We need to be able to detect all failure cases in + # the contract itself and we want to use this to drive the failure test + # cases + + def simpleVAA(self, vaa, client, sender, appid): + p = {"version": int.from_bytes(vaa[0:1], "big"), "index": int.from_bytes(vaa[1:5], "big"), "siglen": int.from_bytes(vaa[5:6], "big")} + ret["signatures"] = vaa[6:(ret["siglen"] * 66) + 6] + ret["sigs"] = [] + for i in range(ret["siglen"]): + ret["sigs"].append(vaa[(6 + (i * 66)):(6 + (i * 66)) + 66].hex()) + off = (ret["siglen"] * 66) + 6 + ret["digest"] = vaa[off:] # This is what is actually signed... + ret["timestamp"] = int.from_bytes(vaa[off:(off + 4)], "big") + off += 4 + ret["nonce"] = int.from_bytes(vaa[off:(off + 4)], "big") + off += 4 + ret["chainRaw"] = vaa[off:(off + 2)] + ret["chain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["emitter"] = vaa[off:(off + 32)] + off += 32 + ret["sequence"] = int.from_bytes(vaa[off:(off + 8)], "big") + off += 8 + ret["consistency"] = int.from_bytes(vaa[off:(off + 1)], "big") + off += 1 + + seq_addr = self.optin(client, sender, appid, int(p["sequence"] / max_bits), p["chainRaw"].hex() + p["emitter"].hex()) + # And then the signatures to help us verify the vaa_s + guardian_addr = self.optin(client, sender, self.coreid, p["index"], b"guardian".hex()) + + accts = [seq_addr, guardian_addr] + + keys = self.decodeLocalState(client, sender, self.coreid, guardian_addr) + + sp = client.suggested_params() + + txns = [] + + # Right now there is not really a good way to estimate the fees, + # in production, on a conjested network, how much verifying + # the signatures is going to cost. + + # So, what we do instead + # is we top off the verifier back up to 2A so effectively we + # are paying for the previous persons overrage which on a + # unconjested network should be zero + + pmt = 3000 + bal = self.getBalances(client, self.vaa_verify["hash"]) + if ((200000 - bal[0]) >= pmt): + pmt = 200000 - bal[0] + + #print("Sending %d algo to cover fees" % (pmt)) + txns.append( + transaction.PaymentTxn( + sender = sender.getAddress(), + sp = sp, + receiver = self.vaa_verify["hash"], + amt = pmt + ) + ) + + # How many signatures can we process in a single txn... we can do 9! + bsize = (9*66) + blocks = int(len(p["signatures"]) / bsize) + 1 + + # We don't pass the entire payload in but instead just pass it pre digested. This gets around size + # limitations with lsigs AND reduces the cost of the entire operation on a conjested network by reducing the + # bytes passed into the transaction + digest = keccak.new(digest_bits=256).update(keccak.new(digest_bits=256).update(p["digest"]).digest()).digest() + + for i in range(blocks): + # Which signatures will we be verifying in this block + sigs = p["signatures"][(i * bsize):] + if (len(sigs) > bsize): + sigs = sigs[:bsize] + # keys + kset = b'' + # Grab the key associated the signature + for q in range(int(len(sigs) / 66)): + # Which guardian is this signature associated with + g = sigs[q * 66] + key = keys[((g * 20) + 1) : (((g + 1) * 20) + 1)] + kset = kset + key + + txns.append(transaction.ApplicationCallTxn( + sender=self.vaa_verify["hash"], + index=self.coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"verifySigs", sigs, kset, digest], + accounts=accts, + sp=sp + )) + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"verifyVAA", vaa], + accounts=accts, + sp=sp + )) + + return txns + + def signVAA(self, client, sender, txns): + transaction.assign_group_id(txns) + + grp = [] + pk = sender.getPrivateKey() + for t in txns: + if ("app_args" in t.__dict__ and len(t.app_args) > 0 and t.app_args[0] == b"verifySigs"): + grp.append(transaction.LogicSigTransaction(t, self.vaa_verify["lsig"])) + else: + grp.append(t.sign(pk)) + + client.send_transactions(grp) + ret = [] + for x in grp: + response = self.waitForTransaction(client, x.get_txid()) + if "logs" in response.__dict__ and len(response.__dict__["logs"]) > 0: + ret.append(response.__dict__["logs"]) + return ret + + def check_bits_set(self, client, app_id, addr, seq): + bits_set = {} + + app_state = None + ai = client.account_info(addr) + for app in ai["apps-local-state"]: + if app["id"] == app_id: + app_state = app["key-value"] + if app_state == None: + return False + + start = int(seq / max_bits) * max_bits + s = int((seq - start) / bits_per_key) + b = int(((seq - start) - (s * bits_per_key)) / 8) + + k = base64.b64encode(s.to_bytes(1, "big")).decode('utf-8') + for kv in app_state: + if kv["key"] != k: + continue + v = base64.b64decode(kv["value"]["bytes"]) + bt = 1 << (seq%8) + return ((v[b] & bt) != 0) + + return False + + def submitVAA(self, vaa, client, sender, appid): + # A lot of our logic here depends on parseVAA and knowing what the payload is.. + p = self.parseVAA(vaa) + + #pprint.pprint(p) + + seq_addr = self.optin(client, sender, appid, int(p["sequence"] / max_bits), p["chainRaw"].hex() + p["emitter"].hex()) + + assert self.check_bits_set(client, appid, seq_addr, p["sequence"]) == False + # And then the signatures to help us verify the vaa_s + guardian_addr = self.optin(client, sender, self.coreid, p["index"], b"guardian".hex()) + + accts = [seq_addr, guardian_addr] + + # If this happens to be setting up a new guardian set, we probably need it as well... + if p["Meta"] == "CoreGovernance" and p["action"] == 2: + newguardian_addr = self.optin(client, sender, self.coreid, p["NewGuardianSetIndex"], b"guardian".hex()) + accts.append(newguardian_addr) + + # When we attest for a new token, we need some place to store the info... later we will need to + # mirror the other way as well + if p["Meta"] == "TokenBridge Attest" or p["Meta"] == "TokenBridge Transfer" or p["Meta"] == "TokenBridge Transfer With Payload": + if p["FromChain"] != 8: + chain_addr = self.optin(client, sender, self.tokenid, p["FromChain"], p["Contract"]) + else: + asset_id = int.from_bytes(bytes.fromhex(p["Contract"]), "big") + chain_addr = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + accts.append(chain_addr) + + keys = self.decodeLocalState(client, sender, self.coreid, guardian_addr) + print("keys: " + keys.hex()) + + sp = client.suggested_params() + + txns = [] + + # How many signatures can we process in a single txn... we can do 9! + bsize = (9*66) + blocks = int(len(p["signatures"]) / bsize) + 1 + + # We don't pass the entire payload in but instead just pass it pre digested. This gets around size + # limitations with lsigs AND reduces the cost of the entire operation on a conjested network by reducing the + # bytes passed into the transaction + digest = keccak.new(digest_bits=256).update(keccak.new(digest_bits=256).update(p["digest"]).digest()).digest() + + for i in range(blocks): + # Which signatures will we be verifying in this block + sigs = p["signatures"][(i * bsize):] + if (len(sigs) > bsize): + sigs = sigs[:bsize] + # keys + kset = b'' + # Grab the key associated the signature + for q in range(int(len(sigs) / 66)): + # Which guardian is this signature associated with + g = sigs[q * 66] + key = keys[((g * 20) + 1) : (((g + 1) * 20) + 1)] + kset = kset + key + + txns.append(transaction.ApplicationCallTxn( + sender=self.vaa_verify["hash"], + index=self.coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"verifySigs", sigs, kset, digest], + accounts=accts, + sp=sp + )) + txns[-1].fee = 0 + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"verifyVAA", vaa], + accounts=accts, + sp=sp + )) + txns[-1].fee = txns[-1].fee * (1 + blocks) + + if p["Meta"] == "CoreGovernance": + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"governance", vaa], + accounts=accts, + sp=sp + )) + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.coreid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop", 5], + sp=sp + )) + + if p["Meta"] == "TokenBridge RegisterChain" or p["Meta"] == "TokenBridge UpgradeContract": + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"governance", vaa], + accounts=accts, + foreign_apps = [self.coreid], + sp=sp + )) + + if p["Meta"] == "TokenBridge Attest": + # if we DO decode it, we can do a sanity check... of + # course, the hacker might NOT decode it so we have to + # handle both cases... + + asset = (self.decodeLocalState(client, sender, self.tokenid, chain_addr)) + foreign_assets = [] + if (len(asset) > 8): + foreign_assets.append(int.from_bytes(asset[0:8], "big")) + + txns.append( + transaction.PaymentTxn( + sender = sender.getAddress(), + sp = sp, + receiver = chain_addr, + amt = 100000 + ) + ) + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop", 1], + sp=sp + )) + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop", 2], + sp=sp + )) + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"receiveAttest", vaa], + accounts=accts, + foreign_assets = foreign_assets, + sp=sp + )) + txns[-1].fee = txns[-1].fee * 2 + + if p["Meta"] == "TokenBridge Transfer" or p["Meta"] == "TokenBridge Transfer With Payload": + foreign_assets = [] + a = 0 + if p["FromChain"] != 8: + asset = (self.decodeLocalState(client, sender, self.tokenid, chain_addr)) + if (len(asset) > 8): + a = int.from_bytes(asset[0:8], "big") + else: + a = int.from_bytes(bytes.fromhex(p["Contract"]), "big") + + # The receiver needs to be optin in to receive the coins... Yeah, the relayer pays for this + + addr = encode_address(bytes.fromhex(p["ToAddress"])) + + if a != 0: + foreign_assets.append(a) + self.asset_optin(client, sender, foreign_assets[0], addr) + # And this is how the relayer gets paid... + if p["Fee"] != self.zeroPadBytes: + self.asset_optin(client, sender, foreign_assets[0], sender.getAddress()) + + accts.append(addr) + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"completeTransfer", vaa], + accounts=accts, + foreign_assets = foreign_assets, + sp=sp + )) + + if "appid" in p: + txns[-1].foreign_apps = [p["appid"]] + + # We need to cover the inner transactions + if p["Fee"] != self.zeroPadBytes: + txns[-1].fee = txns[-1].fee * 3 + else: + txns[-1].fee = txns[-1].fee * 2 + + if p["Meta"] == "TokenBridge Transfer With Payload": + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=p["appid"], + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"completeTransfer", vaa], + foreign_assets = foreign_assets, + sp=sp + )) + + transaction.assign_group_id(txns) + + grp = [] + pk = sender.getPrivateKey() + for t in txns: + if ("app_args" in t.__dict__ and len(t.app_args) > 0 and t.app_args[0] == b"verifySigs"): + grp.append(transaction.LogicSigTransaction(t, self.vaa_verify["lsig"])) + else: + grp.append(t.sign(pk)) + + client.send_transactions(grp) + ret = [] + for x in grp: + response = self.waitForTransaction(client, x.get_txid()) + if "logs" in response.__dict__ and len(response.__dict__["logs"]) > 0: + ret.append(response.__dict__["logs"]) + + assert self.check_bits_set(client, appid, seq_addr, p["sequence"]) == True + + return ret + + def parseVAA(self, vaa): +# print (vaa.hex()) + ret = {"version": int.from_bytes(vaa[0:1], "big"), "index": int.from_bytes(vaa[1:5], "big"), "siglen": int.from_bytes(vaa[5:6], "big")} + ret["signatures"] = vaa[6:(ret["siglen"] * 66) + 6] + ret["sigs"] = [] + for i in range(ret["siglen"]): + ret["sigs"].append(vaa[(6 + (i * 66)):(6 + (i * 66)) + 66].hex()) + off = (ret["siglen"] * 66) + 6 + ret["digest"] = vaa[off:] # This is what is actually signed... + ret["timestamp"] = int.from_bytes(vaa[off:(off + 4)], "big") + off += 4 + ret["nonce"] = int.from_bytes(vaa[off:(off + 4)], "big") + off += 4 + ret["chainRaw"] = vaa[off:(off + 2)] + ret["chain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["emitter"] = vaa[off:(off + 32)] + off += 32 + ret["sequence"] = int.from_bytes(vaa[off:(off + 8)], "big") + off += 8 + ret["consistency"] = int.from_bytes(vaa[off:(off + 1)], "big") + off += 1 + + ret["Meta"] = "Unknown" + + if vaa[off:(off + 32)].hex() == "000000000000000000000000000000000000000000546f6b656e427269646765": + ret["Meta"] = "TokenBridge" + ret["module"] = vaa[off:(off + 32)].hex() + off += 32 + ret["action"] = int.from_bytes(vaa[off:(off + 1)], "big") + off += 1 + if ret["action"] == 1: + ret["Meta"] = "TokenBridge RegisterChain" + ret["targetChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["EmitterChainID"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["targetEmitter"] = vaa[off:(off + 32)].hex() + off += 32 + if ret["action"] == 2: + ret["Meta"] = "TokenBridge UpgradeContract" + ret["targetChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["newContract"] = vaa[off:(off + 32)].hex() + off += 32 + pprint.pprint((vaa[off:(off + 32)].hex(), "00000000000000000000000000000000000000000000000000000000436f7265")) + if vaa[off:(off + 32)].hex() == "00000000000000000000000000000000000000000000000000000000436f7265": + ret["Meta"] = "CoreGovernance" + ret["module"] = vaa[off:(off + 32)].hex() + off += 32 + ret["action"] = int.from_bytes(vaa[off:(off + 1)], "big") + off += 1 + ret["targetChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + if ret["action"] == 2: + ret["NewGuardianSetIndex"] = int.from_bytes(vaa[off:(off + 4)], "big") + else: + ret["Contract"] = vaa[off:(off + 32)].hex() + + if ((len(vaa[off:])) == 100) and int.from_bytes((vaa[off:off+1]), "big") == 2: + ret["Meta"] = "TokenBridge Attest" + ret["Type"] = int.from_bytes((vaa[off:off+1]), "big") + off += 1 + ret["Contract"] = vaa[off:(off + 32)].hex() + off += 32 + ret["FromChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["Decimals"] = int.from_bytes((vaa[off:off+1]), "big") + off += 1 + ret["Symbol"] = vaa[off:(off + 32)].hex() + off += 32 + ret["Name"] = vaa[off:(off + 32)].hex() + + if ((len(vaa[off:])) == 133) and int.from_bytes((vaa[off:off+1]), "big") == 1: + ret["Meta"] = "TokenBridge Transfer" + ret["Type"] = int.from_bytes((vaa[off:off+1]), "big") + off += 1 + ret["Amount"] = vaa[off:(off + 32)].hex() + off += 32 + ret["Contract"] = vaa[off:(off + 32)].hex() + off += 32 + ret["FromChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["ToAddress"] = vaa[off:(off + 32)].hex() + off += 32 + ret["ToChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["Fee"] = vaa[off:(off + 32)].hex() + + if int.from_bytes((vaa[off:off+1]), "big") == 3: + ret["Meta"] = "TokenBridge Transfer With Payload" + ret["Type"] = int.from_bytes((vaa[off:off+1]), "big") + off += 1 + ret["Amount"] = vaa[off:(off + 32)].hex() + off += 32 + ret["Contract"] = vaa[off:(off + 32)].hex() + off += 32 + ret["FromChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["ToAddress"] = vaa[off:(off + 32)].hex() + off += 32 + ret["ToChain"] = int.from_bytes(vaa[off:(off + 2)], "big") + off += 2 + ret["Fee"] = vaa[off:(off + 32)].hex() + off += 32 + ret["Payload"] = vaa[off:].hex() + ret["appid"] = int.from_bytes(vaa[off:(off + 8)], "big") + ret["body"] = vaa[off + 8:].hex() + + return ret + + def boot(self): + print("") + + print("Creating the PortalCore app") + self.coreid = self.createPortalCoreApp(client=self.client, sender=self.foundation) + pprint.pprint({"wormhole core": str(self.coreid), "address": get_application_address(self.coreid), "emitterAddress": decode_address(get_application_address(self.coreid)).hex()}) + + print("Create the token bridge") + self.tokenid = self.createTokenBridgeApp(self.client, self.foundation) + pprint.pprint({"token bridge": str(self.tokenid), "address": get_application_address(self.tokenid), "emitterAddress": decode_address(get_application_address(self.tokenid)).hex()}) + + if self.devnet or self.args.testnet: + if self.devnet: + suggestedParams = self.client.suggested_params() + fundingAccount = self.getGenesisAccounts()[0] + + txns: List[transaction.Transaction] = [] + wallet = "castle sing ice patrol mixture artist violin someone what access slow wrestle clap hero sausage oyster boost tone receive rapid bike announce pepper absent involve" + a = Account.FromMnemonic(wallet) + txns.append( + transaction.PaymentTxn( + sender=fundingAccount.getAddress(), + receiver=a.getAddress(), + amt=self.FUNDING_AMOUNT, + sp=suggestedParams, + ) + ) + txns = transaction.assign_group_id(txns) + signedTxns = [ + txn.sign(fundingAccount.getPrivateKey()) for i, txn in enumerate(txns) + ] + + self.client.send_transactions(signedTxns) + print("Sent some ALGO to: " + wallet) + + if exists(self.args.env): + if self.gt == None: + self.gt = GenTest(False) + + with open(self.args.env, encoding = 'utf-8') as f: + for line in f: + e = line.rstrip('\n').split("=") + print(e) + if "TOKEN_BRIDGE" in e[0]: + v = bytes.fromhex(e[1]) + self.submitVAA(v, self.client, self.foundation, self.tokenid) + if "INIT_SIGNERS_CSV" in e[0]: + self.gt.guardianKeys = e[1].split(",") + if "INIT_SIGNERS_KEYS_CSV" in e[0]: + print("bootstrapping the guardian set...") + self.gt.guardianPrivKeys = e[1].split(",") + seq = int(random.random() * (2**31)) + bootVAA = self.gt.genGuardianSetUpgrade(self.gt.guardianPrivKeys, self.args.guardianSet, self.args.guardianSet, seq, seq) + self.bootGuardians(bytes.fromhex(bootVAA), self.client, self.foundation, self.coreid) + seq = int(random.random() * (2**31)) + regChain = self.gt.genRegisterChain(self.gt.guardianPrivKeys, self.args.guardianSet, seq, seq, 8, decode_address(get_application_address(self.tokenid)).hex()) + print("ALGO_TOKEN_BRIDGE_VAA=" + regChain) +# if self.args.env != ".env": +# v = bytes.fromhex(regChain) +# self.submitVAA(v, self.client, self.foundation, self.tokenid) +# print("We submitted it!") + + def updateCore(self) -> None: + print("Updating the core contracts") + approval, clear = getCoreContracts(False, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + +# print(decode_address(clear["hash"]).hex()) +# sys.exit(0) + + txn = transaction.ApplicationUpdateTxn( + index=self.coreid, + sender=self.foundation.getAddress(), + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + app_args=[ ], + sp=self.client.suggested_params(), + ) + + signedTxn = txn.sign(self.foundation.getPrivateKey()) + print("sending transaction") + self.client.send_transaction(signedTxn) + resp = self.waitForTransaction(self.client, signedTxn.get_txid()) + for x in resp.__dict__["logs"]: + print(x.hex()) + print("complete") + + def updateToken(self) -> None: + approval, clear = get_token_bridge(False, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + print("Updating the token contracts: " + str(len(b64decode(approval["result"])))) + + txn = transaction.ApplicationUpdateTxn( + index=self.tokenid, + sender=self.foundation.getAddress(), + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + app_args=[ ], + sp=self.client.suggested_params(), + ) + + signedTxn = txn.sign(self.foundation.getPrivateKey()) + print("sending transaction") + self.client.send_transaction(signedTxn) + resp = self.waitForTransaction(self.client, signedTxn.get_txid()) + for x in resp.__dict__["logs"]: + print(x.hex()) + print("complete") + + def genTeal(self) -> None: + print((True, self.args.core_approve, self.args.core_clear, self.client, self.seed_amt, self.tsig, self.devnet or self.args.testnet)) + approval, clear = getCoreContracts(True, self.args.core_approve, self.args.core_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + print("Generating the teal for the core contracts") + approval, clear = get_token_bridge(True, self.args.token_approve, self.args.token_clear, self.client, seed_amt=self.seed_amt, tmpl_sig=self.tsig, devMode = self.devnet or self.args.testnet) + print("Generating the teal for the token contracts: " + str(len(b64decode(approval["result"])))) + + def testnet(self): + self.ALGOD_ADDRESS = self.args.algod_address = "https://testnet-api.algonode.cloud" + self.INDEXER_ADDRESS = self.args.algod_address = "https://testnet-idx.algonode.cloud" + self.coreid = self.args.coreid + self.tokenid = self.args.tokenid + + def mainnet(self): + self.ALGOD_ADDRESS = self.args.algod_address = "https://mainnet-api.algonode.cloud" + self.INDEXER_ADDRESS = self.args.algod_address = "https://mainnet-idx.algonode.cloud" + self.coreid = self.args.coreid + self.tokenid = self.args.tokenid + + def setup_args(self) -> None: + parser = argparse.ArgumentParser(description='algorand setup') + + parser.add_argument('--algod_address', type=str, help='algod address (default: http://localhost:4001)', + default="http://localhost:4001") + parser.add_argument('--algod_token', type=str, help='algod access token', + default="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + parser.add_argument('--kmd_address', type=str, help='kmd wallet address (default: http://localhost:4002)', + default="http://localhost:4002") + parser.add_argument('--kmd_token', type=str, help='kmd wallet access token', + default="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + parser.add_argument('--kmd_name', type=str, help='kmd wallet name', + default="unencrypted-default-wallet") + parser.add_argument('--kmd_password', type=str, help='kmd wallet password', default="") + + parser.add_argument('--mnemonic', type=str, help='account mnemonic', default="") + + parser.add_argument('--core_approve', type=str, help='core approve teal', default="teal/core_approve.teal") + parser.add_argument('--core_clear', type=str, help='core clear teal', default="teal/core_clear.teal") + + parser.add_argument('--token_approve', type=str, help='token approve teal', default="teal/token_approve.teal") + parser.add_argument('--token_clear', type=str, help='token clear teal', default="teal/token_clear.teal") + + parser.add_argument('--coreid', type=int, help='core contract', default=4) + parser.add_argument('--tokenid', type=int, help='token bridge contract', default=6) + parser.add_argument('--devnet', action='store_true', help='setup devnet') + parser.add_argument('--boot', action='store_true', help='bootstrap') + parser.add_argument('--upgradePayload', action='store_true', help='gen the upgrade payload for the guardians to sign') + parser.add_argument('--vaa', type=str, help='Submit the supplied VAA', default="") + parser.add_argument('--env', type=str, help='deploying using the supplied .env file', default=".env") + parser.add_argument('--guardianSet', type=int, help='What guardianSet should I syntheticly create if needed', default=0) + parser.add_argument('--appid', type=str, help='The appid that the vaa submit is applied to', default="") + parser.add_argument('--submit', action='store_true', help='submit the synthetic vaas') + parser.add_argument('--updateCore', action='store_true', help='update the Core contracts') + parser.add_argument('--updateToken', action='store_true', help='update the Token contracts') + parser.add_argument('--upgradeVAA', action='store_true', help='generate a upgrade vaa for devnet') + parser.add_argument('--print', action='store_true', help='print') + parser.add_argument('--genParts', action='store_true', help='Get tssig parts') + parser.add_argument('--genTeal', action='store_true', help='Generate all the teal from the pyteal') + parser.add_argument('--fund', action='store_true', help='Generate some accounts and fund them') + parser.add_argument('--testnet', action='store_true', help='Connect to testnet') + parser.add_argument('--mainnet', action='store_true', help='Connect to mainnet') + + args = parser.parse_args() + self.init(args) + + self.devnet = args.devnet + + def main(self) -> None: + self.setup_args() + + args = self.args + + if args.testnet: + self.testnet() + + if args.mainnet: + self.mainnet() + + self.client = self.getAlgodClient() + if self.devnet or self.args.testnet: + self.vaa_verify = self.client.compile(get_vaa_verify()) + else: + c = AlgodClient("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "https://testnet-api.algonode.cloud") + self.vaa_verify = c.compile(get_vaa_verify()) + + self.vaa_verify["lsig"] = LogicSig(base64.b64decode(self.vaa_verify["result"])) + + if args.genTeal or args.boot: + self.genTeal() + + # Generate the upgrade payload we need the guardians to sign + if args.upgradePayload: + print(self.genUpgradePayload()) + sys.exit(0) + + # This breaks the tsig up into the various parts so that we + # can embed it into the Typescript code for reassembly + if args.genParts: + print("this.ALGO_VERIFY_HASH = \"%s\""%self.vaa_verify["hash"]); + print("this.ALGO_VERIFY = new Uint8Array([", end='') + for x in b64decode(self.vaa_verify["result"]): + print("%d, "%(x), end='') + print("])") + + parts = [ + self.tsig.get_bytecode_raw(0).hex(), + self.tsig.get_bytecode_raw(1).hex(), + self.tsig.get_bytecode_raw(2).hex(), + self.tsig.get_bytecode_raw(3).hex(), + self.tsig.get_bytecode_raw(4).hex() + ] + + pprint.pprint(parts) + sys.exit(0) + + if args.mnemonic: + self.foundation = Account.FromMnemonic(args.mnemonic) + + if args.devnet and self.foundation == None: + print("Generating the foundation account...") + self.foundation = self.getTemporaryAccount(self.client) + + if self.args.fund: + sys.exit(0) + + if self.foundation == None: + print("We dont have a account? Here is a random one I just made up...") + pk = account.generate_account()[0] + print(" pk: " + pk) + print(" address: " + account.address_from_private_key(pk)) + print(" mnemonic: " + mnemonic.from_private_key(pk)) + if args.testnet: + print("go to https://bank.testnet.algorand.network/ to fill it up (You will probably want to send at least 2 loads to the wallet)") + sys.exit(0) + + bal = self.getBalances(self.client, self.foundation.addr) + print("foundation address " + self.foundation.addr + " (" + str(float(bal[0]) / 1000000.0) + " ALGO)") + if bal[0] < 10000000: + print("you need at least 10 ALGO to do darn near anything...") + sys.exit(0) + + if args.upgradeVAA: + ret = self.devnetUpgradeVAA() + pprint.pprint(ret) + if (args.submit) : + print("submitting vaa to upgrade core") + self.submitVAA(bytes.fromhex(ret[0]), self.client, self.foundation, self.coreid) + print("submitting vaa to upgrade token") + self.submitVAA(bytes.fromhex(ret[1]), self.client, self.foundation, self.tokenid) + + if args.boot: + self.boot() + + if args.updateCore: + self.updateCore() + + if args.updateToken: + self.updateToken() + + if args.vaa: + if self.args.appid == "": + raise Exception("You need to specifiy the appid when you are submitting vaas") + vaa = bytes.fromhex(args.vaa) + pprint.pprint(self.parseVAA(vaa)) + self.submitVAA(vaa, self.client, self.foundation, int(self.args.appid)) + +if __name__ == "__main__": + core = PortalCore() + core.main() diff --git a/algorand/deploy.sh b/algorand/deploy.sh new file mode 100755 index 000000000..e27c70993 --- /dev/null +++ b/algorand/deploy.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# need netcat + +# Wait for node to start +while ! netcat -z localhost 4001; do + sleep 1 +done + +while ! wget http://localhost:4001/genesis -O genesis.json ; do + sleep 15 +done + +if [ ! -f genesis.json ]; then + echo "Failed to create genesis file!" + exit 1 +fi + +sleep 2 + +pipenv run python3 admin.py --devnet --boot diff --git a/algorand/gentest.py b/algorand/gentest.py new file mode 100644 index 000000000..8301d8926 --- /dev/null +++ b/algorand/gentest.py @@ -0,0 +1,237 @@ +from eth_abi import encode_single, encode_abi +import sys +import pprint +import time +from Cryptodome.Hash import keccak +import coincurve +import base64 +from random import random +from algosdk.encoding import decode_address + +class GenTest: + def __init__(self, bigSet) -> None: + if bigSet: + self.guardianKeys = [ + "52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2", + "389A74E8FFa224aeAD0778c786163a7A2150768C", + "B4459EA6482D4aE574305B239B4f2264239e7599", + "072491bd66F63356090C11Aae8114F5372aBf12B", + "51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfF", + "fa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CB", + "e42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A", + "4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087e", + "c8306B84235D7b0478c61783C50F990bfC44cFc0", + "C8C1035110a13fe788259A4148F871b52bAbcb1B", + "58A2508A20A7198E131503ce26bBE119aA8c62b2", + "8390820f04ddA22AFe03be1c3bb10f4ba6CF94A0", + "1FD6e97387C34a1F36DE0f8341E9D409E06ec45b", + "255a41fC2792209CB998A8287204D40996df9E54", + "bA663B12DD23fbF4FbAC618Be140727986B3BBd0", + "79040E577aC50486d0F6930e160A5C75FD1203C6", + "3580D2F00309A9A85efFAf02564Fc183C0183A96", + "3869795913D3B6dBF3B24a1C7654672c69A23c35", + "1c0Cc52D7673c52DE99785741344662F5b2308a0", + ] + + self.guardianPrivKeys = [ + "563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757", + "8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f", + "9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b", + "5a02c4cd110d20a83a7ce8d1a2b2ae5df252b4e5f6781c7855db5cc28ed2d1b4", + "93d4e3b443bf11f99a00901222c032bd5f63cf73fc1bcfa40829824d121be9b2", + "ea40e40c63c6ff155230da64a2c44fcd1f1c9e50cacb752c230f77771ce1d856", + "87eaabe9c27a82198e618bca20f48f9679c0f239948dbd094005e262da33fe6a", + "61ffed2bff38648a6d36d6ed560b741b1ca53d45391441124f27e1e48ca04770", + "bd12a242c6da318fef8f98002efb98efbf434218a78730a197d981bebaee826e", + "20d3597bb16525b6d09e5fb56feb91b053d961ab156f4807e37d980f50e71aff", + "344b313ffbc0199ff6ca08cacdaf5dc1d85221e2f2dc156a84245bd49b981673", + "848b93264edd3f1a521274ca4da4632989eb5303fd15b14e5ec6bcaa91172b05", + "c6f2046c1e6c172497fc23bd362104e2f4460d0f61984938fa16ef43f27d93f6", + "693b256b1ee6b6fb353ba23274280e7166ab3be8c23c203cc76d716ba4bc32bf", + "13c41508c0da03018d61427910b9922345ced25e2bbce50652e939ee6e5ea56d", + "460ee0ee403be7a4f1eb1c63dd1edaa815fbaa6cf0cf2344dcba4a8acf9aca74", + "b25148579b99b18c8994b0b86e4dd586975a78fa6e7ad6ec89478d7fbafd2683", + "90d7ac6a82166c908b8cf1b352f3c9340a8d1f2907d7146fb7cd6354a5436cca", + "b71d23908e4cf5d6cd973394f3a4b6b164eb1065785feee612efdfd8d30005ed", + ] + + else: + self.guardianKeys = [ + "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe" + ] + + self.guardianPrivKeys = [ + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0" + ] + + self.zeroPadBytes = "00"*64 + + def encoder(self, type, val): + if type == 'uint8': + return encode_single(type, val).hex()[62:64] + if type == 'uint16': + return encode_single(type, val).hex()[60:64] + if type == 'uint32': + return encode_single(type, val).hex()[56:64] + if type == 'uint64': + return encode_single(type, val).hex()[64-(16):64] + if type == 'uint128': + return encode_single(type, val).hex()[64-(32):64] + if type == 'uint256' or type == 'bytes32': + return encode_single(type, val).hex()[64-(64):64] + raise Exception("you suck") + + def createSignedVAA(self, guardianSetIndex, signers, ts, nonce, emitterChainId, emitterAddress, sequence, consistencyLevel, target, payload): + print("createSignedVAA: " + str(signers)) + b = "" + + b += self.encoder("uint32", ts) + b += self.encoder("uint32", nonce) + b += self.encoder("uint16", emitterChainId) + b += self.encoder("bytes32", emitterAddress) + b += self.encoder("uint64", sequence) + b += self.encoder("uint8", consistencyLevel) + b += payload + + hash = keccak.new(digest_bits=256).update(keccak.new(digest_bits=256).update(bytes.fromhex(b)).digest()).digest() + + signatures = "" + + for i in range(len(signers)): + signatures += self.encoder("uint8", i) + + key = coincurve.PrivateKey(bytes.fromhex(signers[i])) + signature = key.sign_recoverable(hash, hasher=None) + signatures += signature.hex() + + ret = self.encoder("uint8", 1) + ret += self.encoder("uint32", guardianSetIndex) + ret += self.encoder("uint8", len(signers)) + ret += signatures + ret += b + + return ret + + def genGuardianSetUpgrade(self, signers, guardianSet, targetSet, nonce, seq): + b = self.zeroPadBytes[0:(28*2)] + b += self.encoder("uint8", ord("C")) + b += self.encoder("uint8", ord("o")) + b += self.encoder("uint8", ord("r")) + b += self.encoder("uint8", ord("e")) + b += self.encoder("uint8", 2) + b += self.encoder("uint16", 0) + b += self.encoder("uint32", targetSet) + b += self.encoder("uint8", len(self.guardianKeys)) + + for i in self.guardianKeys: + b += i + + emitter = bytes.fromhex(self.zeroPadBytes[0:(31*2)] + "04") + return self.createSignedVAA(guardianSet, signers, int(time.time()), nonce, 1, emitter, seq, 32, 0, b) + + def genGSetFee(self, signers, guardianSet, nonce, seq, amt): + b = self.zeroPadBytes[0:(28*2)] + b += self.encoder("uint8", ord("C")) + b += self.encoder("uint8", ord("o")) + b += self.encoder("uint8", ord("r")) + b += self.encoder("uint8", ord("e")) + b += self.encoder("uint8", 3) + b += self.encoder("uint16", 8) + b += self.encoder("uint256", int(amt)) # a whole algo! + + emitter = bytes.fromhex(self.zeroPadBytes[0:(31*2)] + "04") + return self.createSignedVAA(guardianSet, signers, int(time.time()), nonce, 1, emitter, seq, 32, 0, b) + + def genGFeePayout(self, signers, guardianSet, targetSet, nonce, seq, amt, dest): + b = self.zeroPadBytes[0:(28*2)] + b += self.encoder("uint8", ord("C")) + b += self.encoder("uint8", ord("o")) + b += self.encoder("uint8", ord("r")) + b += self.encoder("uint8", ord("e")) + b += self.encoder("uint8", 4) + b += self.encoder("uint16", 8) + b += self.encoder("uint256", int(amt * 1000000)) + b += decode_address(dest).hex() + + emitter = bytes.fromhex(self.zeroPadBytes[0:(31*2)] + "04") + return self.createSignedVAA(guardianSet, signers, int(time.time()), nonce, 1, emitter, seq, 32, 0, b) + + def getEmitter(self, chain): + if chain == 1: + return "ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5" + if chain == 2: + return "0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585" + if chain == 3: + return "0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2" + if chain == 4: + return "000000000000000000000000b6f6d86a8f9879a9c87f643768d9efc38c1da6e7" + if chain == 5: + return "0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde" + raise Exception("you suck") + + def genRegisterChain(self, signers, guardianSet, nonce, seq, chain, addr = None): + b = self.zeroPadBytes[0:((32 -11)*2)] + b += self.encoder("uint8", ord("T")) + b += self.encoder("uint8", ord("o")) + b += self.encoder("uint8", ord("k")) + b += self.encoder("uint8", ord("e")) + b += self.encoder("uint8", ord("n")) + b += self.encoder("uint8", ord("B")) + b += self.encoder("uint8", ord("r")) + b += self.encoder("uint8", ord("i")) + b += self.encoder("uint8", ord("d")) + b += self.encoder("uint8", ord("g")) + b += self.encoder("uint8", ord("e")) + + b += self.encoder("uint8", 1) # action + b += self.encoder("uint16", 0) # target chain + b += self.encoder("uint16", chain) + if addr == None: + b += self.getEmitter(chain) + else: + b += addr + emitter = bytes.fromhex(self.zeroPadBytes[0:(31*2)] + "04") + return self.createSignedVAA(guardianSet, signers, int(time.time()), nonce, 1, emitter, seq, 32, 0, b) + + def genAssetMeta(self, signers, guardianSet, nonce, seq, tokenAddress, chain, decimals, symbol, name): + b = self.encoder("uint8", 2) + b += self.zeroPadBytes[0:((32-len(tokenAddress))*2)] + b += tokenAddress.hex() + b += self.encoder("uint16", chain) + b += self.encoder("uint8", decimals) + b += symbol.hex() + b += self.zeroPadBytes[0:((32-len(symbol))*2)] + b += name.hex() + b += self.zeroPadBytes[0:((32-len(name))*2)] + emitter = bytes.fromhex(self.getEmitter(chain)) + return self.createSignedVAA(guardianSet, signers, int(time.time()), nonce, 1, emitter, seq, 32, 0, b) + + def genTransfer(self, signers, guardianSet, nonce, seq, amount, tokenAddress, tokenChain, toAddress, toChain, fee): + b = self.encoder("uint8", 1) + b += self.encoder("uint256", int(amount * 100000000)) + + b += self.zeroPadBytes[0:((32-len(tokenAddress))*2)] + b += tokenAddress.hex() + + b += self.encoder("uint16", tokenChain) + + b += self.zeroPadBytes[0:((32-len(toAddress))*2)] + b += toAddress.hex() + + b += self.encoder("uint16", toChain) + + b += self.encoder("uint256", int(fee * 100000000)) + + emitter = bytes.fromhex(self.getEmitter(tokenChain)) + return self.createSignedVAA(guardianSet, signers, int(time.time()), nonce, 1, emitter, seq, 32, 0, b) + + def genVaa(self, emitter, seq, payload): + nonce = int(random() * 4000000.0) + return self.createSignedVAA(1, self.guardianPrivKeys, int(time.time()), nonce, 8, emitter, seq, 32, 0, payload.hex()) + + def test(self): + print(self.genTransfer(self.guardianPrivKeys, 1, 1, 1, 1, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, decode_address("ROOKEPZMHHBAEH75Y44OCNXQAGTXZWG3PY7IYQQCMXO7IG7DJMVHU32YVI"), 8, 0)) + +if __name__ == '__main__': + core = GenTest(True) + core.test() diff --git a/staging/algorand/teal/wormhole/pyteal/globals.py b/algorand/globals.py similarity index 100% rename from staging/algorand/teal/wormhole/pyteal/globals.py rename to algorand/globals.py diff --git a/staging/algorand/teal/wormhole/pyteal/inlineasm.py b/algorand/inlineasm.py similarity index 100% rename from staging/algorand/teal/wormhole/pyteal/inlineasm.py rename to algorand/inlineasm.py diff --git a/algorand/local_blob.py b/algorand/local_blob.py new file mode 100644 index 000000000..ceb1dda88 --- /dev/null +++ b/algorand/local_blob.py @@ -0,0 +1,212 @@ +from typing import Tuple + +from pyteal import ( + And, + App, + Assert, + Bytes, + BytesZero, + Concat, + Expr, + Extract, + For, + GetByte, + If, + Int, + Itob, + Len, + Or, + ScratchVar, + Seq, + SetByte, + Subroutine, + Substring, + TealType, +) + +_max_keys = 15 +_page_size = 128 - 1 # need 1 byte for key +_max_bytes = _max_keys * _page_size +_max_bits = _max_bytes * 8 + +max_keys = Int(_max_keys) +page_size = Int(_page_size) +max_bytes = Int(_max_bytes) + + +def _key_and_offset(idx: Int) -> Tuple[Int, Int]: + return idx / page_size, idx % page_size + + +@Subroutine(TealType.bytes) +def intkey(i: Expr) -> Expr: + return Extract(Itob(i), Int(7), Int(1)) + + +# TODO: Add Keyspace range? +class LocalBlob: + """ + Blob is a class holding static methods to work with the local storage of an account as a binary large object + + The `zero` method must be called on an account on opt in and the schema of the local storage should be 16 bytes + """ + + @staticmethod + @Subroutine(TealType.none) + def zero(acct: Expr) -> Expr: + """ + initializes local state of an account to all zero bytes + + This allows us to be lazy later and _assume_ all the strings are the same size + + """ + i = ScratchVar() + init = i.store(Int(0)) + cond = i.load() < max_keys + iter = i.store(i.load() + Int(1)) + return For(init, cond, iter).Do( + App.localPut(acct, intkey(i.load()), BytesZero(page_size)) + ) + + @staticmethod + @Subroutine(TealType.uint64) + def get_byte(acct: Expr, idx: Expr): + """ + Get a single byte from local storage of an account by index + """ + key, offset = _key_and_offset(idx) + return GetByte(App.localGet(acct, intkey(key)), offset) + + @staticmethod + @Subroutine(TealType.none) + def set_byte(acct: Expr, idx: Expr, byte: Expr): + """ + Set a single byte from local storage of an account by index + """ + key, offset = _key_and_offset(idx) + return App.localPut( + acct, intkey(key), SetByte(App.localGet(acct, intkey(key)), offset, byte) + ) + + @staticmethod + @Subroutine(TealType.bytes) + def read( + acct: Expr, bstart: Expr, bend: Expr + ) -> Expr: + """ + read bytes between bstart and bend from local storage of an account by index + """ + + start_key, start_offset = _key_and_offset(bstart) + stop_key, stop_offset = _key_and_offset(bend) + + key = ScratchVar() + buff = ScratchVar() + + start = ScratchVar() + stop = ScratchVar() + + init = key.store(start_key) + cond = key.load() <= stop_key + incr = key.store(key.load() + Int(1)) + + return Seq( + buff.store(Bytes("")), + For(init, cond, incr).Do( + Seq( + start.store(If(key.load() == start_key, start_offset, Int(0))), + stop.store(If(key.load() == stop_key, stop_offset, page_size)), + buff.store( + Concat( + buff.load(), + Substring( + App.localGet(acct, intkey(key.load())), + start.load(), + stop.load(), + ), + ) + ), + ) + ), + buff.load(), + ) + + @staticmethod + @Subroutine(TealType.none) + def meta( + acct: Expr, val: Expr + ): + return Seq( + App.localPut(acct, Bytes("meta"), val) + ) + + @staticmethod + @Subroutine(TealType.none) + def checkMeta(acct: Expr, val: Expr): + return Seq(Assert(And(App.localGet(acct, Bytes("meta")) == val, Int(145)))) + + @staticmethod + @Subroutine(TealType.uint64) + def write( + acct: Expr, bstart: Expr, buff: Expr + ) -> Expr: + """ + write bytes between bstart and len(buff) to local storage of an account + """ + + start_key, start_offset = _key_and_offset(bstart) + stop_key, stop_offset = _key_and_offset(bstart + Len(buff)) + + key = ScratchVar() + start = ScratchVar() + stop = ScratchVar() + written = ScratchVar() + + init = key.store(start_key) + cond = key.load() <= stop_key + incr = key.store(key.load() + Int(1)) + + delta = ScratchVar() + + return Seq( + written.store(Int(0)), + For(init, cond, incr).Do( + Seq( + start.store(If(key.load() == start_key, start_offset, Int(0))), + stop.store(If(key.load() == stop_key, stop_offset, page_size)), + App.localPut( + acct, + intkey(key.load()), + If( + Or(stop.load() != page_size, start.load() != Int(0)) + ) # Its a partial write + .Then( + Seq( + delta.store(stop.load() - start.load()), + Concat( + Substring( + App.localGet(acct, intkey(key.load())), + Int(0), + start.load(), + ), + Extract(buff, written.load(), delta.load()), + Substring( + App.localGet(acct, intkey(key.load())), + stop.load(), + page_size, + ), + ), + ) + ) + .Else( + Seq( + delta.store(page_size), + Extract(buff, written.load(), page_size), + ) + ), + ), + written.store(written.load() + delta.load()), + ) + ), + written.load(), + ) diff --git a/algorand/package-lock.json b/algorand/package-lock.json new file mode 100644 index 000000000..06a0ddb71 --- /dev/null +++ b/algorand/package-lock.json @@ -0,0 +1,2532 @@ +{ + "name": "algorand", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "@certusone/wormhole-sdk": "file:../sdk/js", + "algosdk": "^1.14.0", + "ts-node": "^10.7.0", + "typescript": "^4.6.2", + "varint": "^6.0.0", + "web3-eth-abi": "^1.7.1" + }, + "devDependencies": { + "@types/node": "^17.0.23" + } + }, + "../sdk/js": { + "version": "0.2.4", + "license": "Apache-2.0", + "dependencies": { + "@improbable-eng/grpc-web": "^0.14.0", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.24.0", + "@terra-money/terra.js": "^3.0.7", + "algosdk": "^1.14.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "js-base64": "^3.6.1", + "protobufjs": "^6.11.2", + "rxjs": "^7.3.0" + }, + "devDependencies": { + "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", + "@openzeppelin/contracts": "^4.2.0", + "@typechain/ethers-v5": "^7.0.1", + "@types/jest": "^27.0.2", + "@types/long": "^4.0.1", + "@types/node": "^16.6.1", + "@types/react": "^17.0.19", + "copy-dir": "^1.3.0", + "ethers": "^5.4.4", + "jest": "^27.3.1", + "prettier": "^2.3.2", + "ts-jest": "^27.0.7", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^4.3.5", + "web3": "^1.6.1" + } + }, + "node_modules/@certusone/wormhole-sdk": { + "resolved": "../sdk/js", + "link": true + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "dependencies": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", + "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", + "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", + "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", + "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", + "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^4.11.9" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.0.tgz", + "integrity": "sha512-3hJPlYemb9V4VLfJF5BfN0+55vltPZSHU3QKUyP9M3Y2TcajbiRrz65UG+xVHOzBereB1b9mn7r12o177xgN7w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", + "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.6.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", + "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", + "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.0.tgz", + "integrity": "sha512-DaVzgyThzHgSDLuURhvkp4oviGoGe9iTZW4jMEORHDRCgSZ9K9THGFKqL+qGXqPAYLEgZTf5z2w56mRrPR1MjQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", + "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", + "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", + "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", + "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", + "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", + "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, + "node_modules/@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/algosdk": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.14.0.tgz", + "integrity": "sha512-IaaomouKmuCnK+xLuz27X8DQro0ZjVyw4zHvV8HJap9PPDOQKbvpm+UIIsEf0CmC0xWPXIxfFbmlJ0y5CeGlqQ==", + "dependencies": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.2", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "superagent": "^6.1.0", + "tweetnacl": "^1.0.3", + "url-parse": "^1.5.1" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==", + "engines": { + "node": "*" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "dependencies": { + "js-sha3": "^0.8.0" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", + "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node_modules/node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + }, + "node_modules/object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/rlp/node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "hasInstallScript": true, + "dependencies": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", + "dependencies": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 7.0.0" + } + }, + "node_modules/ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "node_modules/typescript": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" + }, + "node_modules/varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "node_modules/web3-eth-abi": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", + "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "dependencies": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.1.tgz", + "integrity": "sha512-fef0EsqMGJUgiHPdX+KN9okVWshbIumyJPmR+btnD1HgvoXijKEkuKBv0OmUqjbeqmLKP2/N9EiXKJel5+E1Dw==", + "dependencies": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@certusone/wormhole-sdk": { + "version": "file:../sdk/js", + "requires": { + "@improbable-eng/grpc-web": "^0.14.0", + "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", + "@openzeppelin/contracts": "^4.2.0", + "@solana/spl-token": "^0.1.8", + "@solana/web3.js": "^1.24.0", + "@terra-money/terra.js": "^3.0.7", + "@typechain/ethers-v5": "^7.0.1", + "@types/jest": "^27.0.2", + "@types/long": "^4.0.1", + "@types/node": "^16.6.1", + "@types/react": "^17.0.19", + "algosdk": "^1.14.0", + "axios": "^0.24.0", + "bech32": "^2.0.0", + "copy-dir": "^1.3.0", + "ethers": "^5.4.4", + "jest": "^27.3.1", + "js-base64": "^3.6.1", + "prettier": "^2.3.2", + "protobufjs": "^6.11.2", + "rxjs": "^7.3.0", + "ts-jest": "^27.0.7", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^4.3.5", + "web3": "^1.6.1" + } + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==" + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@ethersproject/abi": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", + "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", + "requires": { + "@ethersproject/address": "^5.0.4", + "@ethersproject/bignumber": "^5.0.7", + "@ethersproject/bytes": "^5.0.4", + "@ethersproject/constants": "^5.0.4", + "@ethersproject/hash": "^5.0.4", + "@ethersproject/keccak256": "^5.0.3", + "@ethersproject/logger": "^5.0.5", + "@ethersproject/properties": "^5.0.3", + "@ethersproject/strings": "^5.0.4" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.6.0.tgz", + "integrity": "sha512-oPMFlKLN+g+y7a79cLK3WiLcjWFnZQtXWgnLAbHZcN3s7L4v90UHpTOrLk+m3yr0gt+/h9STTM6zrr7PM8uoRw==", + "requires": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/networks": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/transactions": "^5.6.0", + "@ethersproject/web": "^5.6.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.6.0.tgz", + "integrity": "sha512-WOqnG0NJKtI8n0wWZPReHtaLkDByPL67tn4nBaDAhmVq8sjHTPbCdz4DRhVu/cfTOvfy9w3iq5QZ7BX7zw56BQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0" + } + }, + "@ethersproject/address": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.6.0.tgz", + "integrity": "sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==", + "requires": { + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/rlp": "^5.6.0" + } + }, + "@ethersproject/base64": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.6.0.tgz", + "integrity": "sha512-2Neq8wxJ9xHxCF9TUgmKeSh9BXJ6OAxWfeGWvbauPh8FuHEjamgHilllx8KkSd5ErxyHIX7Xv3Fkcud2kY9ezw==", + "requires": { + "@ethersproject/bytes": "^5.6.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.6.0.tgz", + "integrity": "sha512-VziMaXIUHQlHJmkv1dlcd6GY2PmT0khtAqaMctCIDogxkrarMzA9L94KN1NeXqqOfFD6r0sJT3vCTOFSmZ07DA==", + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "bn.js": "^4.11.9" + } + }, + "@ethersproject/bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.6.0.tgz", + "integrity": "sha512-3hJPlYemb9V4VLfJF5BfN0+55vltPZSHU3QKUyP9M3Y2TcajbiRrz65UG+xVHOzBereB1b9mn7r12o177xgN7w==", + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/constants": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.6.0.tgz", + "integrity": "sha512-SrdaJx2bK0WQl23nSpV/b1aq293Lh0sUaZT/yYKPDKn4tlAbkH96SPJwIhwSwTsoQQZxuh1jnqsKwyymoiBdWA==", + "requires": { + "@ethersproject/bignumber": "^5.6.0" + } + }, + "@ethersproject/hash": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.6.0.tgz", + "integrity": "sha512-fFd+k9gtczqlr0/BruWLAu7UAOas1uRRJvOR84uDf4lNZ+bTkGl366qvniUZHKtlqxBRU65MkOobkmvmpHU+jA==", + "requires": { + "@ethersproject/abstract-signer": "^5.6.0", + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@ethersproject/keccak256": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.6.0.tgz", + "integrity": "sha512-tk56BJ96mdj/ksi7HWZVWGjCq0WVl/QvfhFQNeL8fxhBlGoP+L80uDCiQcpJPd+2XxkivS3lwRm3E0CXTfol0w==", + "requires": { + "@ethersproject/bytes": "^5.6.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.6.0.tgz", + "integrity": "sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==" + }, + "@ethersproject/networks": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.6.0.tgz", + "integrity": "sha512-DaVzgyThzHgSDLuURhvkp4oviGoGe9iTZW4jMEORHDRCgSZ9K9THGFKqL+qGXqPAYLEgZTf5z2w56mRrPR1MjQ==", + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/properties": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.6.0.tgz", + "integrity": "sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==", + "requires": { + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/rlp": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.6.0.tgz", + "integrity": "sha512-dz9WR1xpcTL+9DtOT/aDO+YyxSSdO8YIS0jyZwHHSlAmnxA6cKU3TrTd4Xc/bHayctxTgGLYNuVVoiXE4tTq1g==", + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/signing-key": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.6.0.tgz", + "integrity": "sha512-S+njkhowmLeUu/r7ir8n78OUKx63kBdMCPssePS89So1TH4hZqnWFsThEd/GiXYp9qMxVrydf7KdM9MTGPFukA==", + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "bn.js": "^4.11.9", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/strings": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.6.0.tgz", + "integrity": "sha512-uv10vTtLTZqrJuqBZR862ZQjTIa724wGPWQqZrofaPI/kUsf53TBG0I0D+hQ1qyNtllbNzaW+PDPHHUI6/65Mg==", + "requires": { + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/logger": "^5.6.0" + } + }, + "@ethersproject/transactions": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.6.0.tgz", + "integrity": "sha512-4HX+VOhNjXHZyGzER6E/LVI2i6lf9ejYeWD6l4g50AdmimyuStKc39kvKf1bXWQMg7QNVh+uC7dYwtaZ02IXeg==", + "requires": { + "@ethersproject/address": "^5.6.0", + "@ethersproject/bignumber": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/constants": "^5.6.0", + "@ethersproject/keccak256": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/rlp": "^5.6.0", + "@ethersproject/signing-key": "^5.6.0" + } + }, + "@ethersproject/web": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.6.0.tgz", + "integrity": "sha512-G/XHj0hV1FxI2teHRfCGvfBUHFmU+YOSbCxlAMqJklxSa7QMiHFQfAxvwY2PFqgvdkxEKwRNr/eCjfAPEm2Ctg==", + "requires": { + "@ethersproject/base64": "^5.6.0", + "@ethersproject/bytes": "^5.6.0", + "@ethersproject/logger": "^5.6.0", + "@ethersproject/properties": "^5.6.0", + "@ethersproject/strings": "^5.6.0" + } + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, + "@types/bn.js": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", + "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" + }, + "@types/pbkdf2": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", + "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==" + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" + }, + "algo-msgpack-with-bigint": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", + "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==" + }, + "algosdk": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.14.0.tgz", + "integrity": "sha512-IaaomouKmuCnK+xLuz27X8DQro0ZjVyw4zHvV8HJap9PPDOQKbvpm+UIIsEf0CmC0xWPXIxfFbmlJ0y5CeGlqQ==", + "requires": { + "algo-msgpack-with-bigint": "^2.1.1", + "buffer": "^6.0.2", + "hi-base32": "^0.5.1", + "js-sha256": "^0.9.0", + "js-sha3": "^0.8.0", + "js-sha512": "^0.8.0", + "json-bigint": "^1.0.0", + "superagent": "^6.1.0", + "tweetnacl": "^1.0.3", + "url-parse": "^1.5.1" + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "base-x": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", + "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bignumber.js": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz", + "integrity": "sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==" + }, + "blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ethereum-bloom-filters": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", + "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", + "requires": { + "js-sha3": "^0.8.0" + } + }, + "ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "ethereumjs-util": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.4.tgz", + "integrity": "sha512-p6KmuPCX4mZIqsQzXfmSx9Y0l2hqf+VkAiwSisW3UKUFdk8ZkAt+AYaor83z2nSi6CU2zSsXMlD80hAbNEGM0A==", + "requires": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + } + } + }, + "ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", + "requires": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" + }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" + }, + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "requires": { + "bignumber.js": "^9.0.0" + } + }, + "keccak": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", + "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", + "requires": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "requires": { + "mime-db": "1.52.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-gyp-build": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", + "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" + }, + "number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", + "requires": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" + } + } + }, + "object-inspect": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", + "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "requires": { + "side-channel": "^1.0.4" + } + }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "requires": { + "bn.js": "^5.2.0" + }, + "dependencies": { + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" + } + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "secp256k1": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", + "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "requires": { + "is-hex-prefixed": "1.0.0" + } + }, + "superagent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", + "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", + "requires": { + "component-emitter": "^1.3.0", + "cookiejar": "^2.1.2", + "debug": "^4.1.1", + "fast-safe-stringify": "^2.0.7", + "form-data": "^3.0.0", + "formidable": "^1.2.2", + "methods": "^1.1.2", + "mime": "^2.4.6", + "qs": "^6.9.4", + "readable-stream": "^3.6.0", + "semver": "^7.3.2" + } + }, + "ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + } + }, + "tweetnacl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", + "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" + }, + "typescript": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==" + }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==" + }, + "varint": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", + "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==" + }, + "web3-eth-abi": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.7.1.tgz", + "integrity": "sha512-8BVBOoFX1oheXk+t+uERBibDaVZ5dxdcefpbFTWcBs7cdm0tP8CD1ZTCLi5Xo+1bolVHNH2dMSf/nEAssq5pUA==", + "requires": { + "@ethersproject/abi": "5.0.7", + "web3-utils": "1.7.1" + } + }, + "web3-utils": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.7.1.tgz", + "integrity": "sha512-fef0EsqMGJUgiHPdX+KN9okVWshbIumyJPmR+btnD1HgvoXijKEkuKBv0OmUqjbeqmLKP2/N9EiXKJel5+E1Dw==", + "requires": { + "bn.js": "^4.11.9", + "ethereum-bloom-filters": "^1.0.6", + "ethereumjs-util": "^7.1.0", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } +} diff --git a/algorand/package.json b/algorand/package.json new file mode 100644 index 000000000..d9420a6c9 --- /dev/null +++ b/algorand/package.json @@ -0,0 +1,16 @@ +{ + "dependencies": { + "@certusone/wormhole-sdk": "file:../sdk/js", + "algosdk": "^1.14.0", + "ts-node": "^10.7.0", + "typescript": "^4.6.2", + "varint": "^6.0.0", + "web3-eth-abi": "^1.7.1" + }, + "devDependencies": { + "@types/node": "^17.0.23" + }, + "scripts": { + "test": "npm run --prefix=../sdk/js build-lib && ts-node test/test.ts" + } +} diff --git a/algorand/requirements.txt b/algorand/requirements.txt new file mode 100644 index 000000000..097672fa2 --- /dev/null +++ b/algorand/requirements.txt @@ -0,0 +1,27 @@ +attrs==21.4.0 +cffi==1.15.0 +colorama==0.4.4 +execnet==1.9.0 +future-fstrings==1.2.0 +iniconfig==1.1.1 +msgpack==1.0.3 +packaging==21.3 +pluggy==1.0.0 +py==1.11.0 +pycparser==2.21 +pycryptodomex==3.12.0 +pydantic==1.9.0 +PyNaCl==1.5.0 +pyparsing==3.0.6 +pyteal==v0.11.1 +py-algorand-sdk==1.10.0b1 +pytest==6.2.5 +pytest-depends==1.0.1 +pytest-forked==1.4.0 +pytest-xdist==2.5.0 +PyYAML==6.0 +toml==0.10.2 +typing-extensions==4.0.1 +uvarint==1.2.0 +eth_abi==2.1.1 +coincurve==16.0.0 diff --git a/algorand/sandbox b/algorand/sandbox new file mode 100755 index 000000000..b62a92901 --- /dev/null +++ b/algorand/sandbox @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e + +# ./sandbox down; ./sandbox clean; ./sandbox up dev; python3 admin.py --devnet --boot + +# ./sandbox reset -v; python3 admin.py --devnet --boot + +# python3 admin.py --devnet --genTeal + +# (cd ../sdk/js; npm run test -- token_bridge) + +PARENT_DIR=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) +SANDBOX_DIR=$PARENT_DIR/_sandbox +if [ ! -d "$SANDBOX_DIR" ]; then + echo "Pulling sandbox..." + git clone https://github.com/algorand/sandbox.git $SANDBOX_DIR +fi + +$SANDBOX_DIR/sandbox "$@" diff --git a/algorand/sandbox-algorand/config.dev b/algorand/sandbox-algorand/config.dev new file mode 100644 index 000000000..aaa8f104f --- /dev/null +++ b/algorand/sandbox-algorand/config.dev @@ -0,0 +1,12 @@ +export ALGOD_CHANNEL="" +export ALGOD_URL="https://github.com/algorand/go-algorand" +export ALGOD_BRANCH="master" +export ALGOD_SHA="" +export NETWORK="" +export NETWORK_TEMPLATE="images/algod/DevModeNetwork.json" +export NETWORK_BOOTSTRAP_URL="" +export NETWORK_GENESIS_FILE="" +export INDEXER_URL="https://github.com/algorand/indexer" +export INDEXER_BRANCH="develop" +export INDEXER_SHA="" +export INDEXER_DISABLED="" diff --git a/algorand/sandbox-algorand/config/beta.config.json b/algorand/sandbox-algorand/config/beta.config.json new file mode 100644 index 000000000..ebba3d4dd --- /dev/null +++ b/algorand/sandbox-algorand/config/beta.config.json @@ -0,0 +1,4 @@ +{ + "EndpointAddress": ":4001", + "DNSBootstrapID": ".algodev.network" +} diff --git a/algorand/sandbox-algorand/config/config.json b/algorand/sandbox-algorand/config/config.json new file mode 100644 index 000000000..919eba11f --- /dev/null +++ b/algorand/sandbox-algorand/config/config.json @@ -0,0 +1,3 @@ +{ + "EndpointAddress": ":4001" +} diff --git a/algorand/sandbox-algorand/config/kmd_config.json b/algorand/sandbox-algorand/config/kmd_config.json new file mode 100644 index 000000000..4d8e0d7a3 --- /dev/null +++ b/algorand/sandbox-algorand/config/kmd_config.json @@ -0,0 +1,4 @@ +{ + "address":"0.0.0.0:4002", + "allowed_origins":["*"] +} diff --git a/algorand/sandbox-algorand/config/start.sh b/algorand/sandbox-algorand/config/start.sh new file mode 100755 index 000000000..5dc047daf --- /dev/null +++ b/algorand/sandbox-algorand/config/start.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +chmod 700 /opt/algorand/node/data/kmd-v0.5 + +/opt/algorand/node/goal kmd start -d /opt/algorand/node/data +/opt/algorand/node/algod -d /opt/algorand/node/data diff --git a/third_party/algorand/token b/algorand/sandbox-algorand/config/token similarity index 100% rename from third_party/algorand/token rename to algorand/sandbox-algorand/config/token diff --git a/algorand/sandbox-algorand/images/Dockerfile b/algorand/sandbox-algorand/images/Dockerfile new file mode 100644 index 000000000..ac2eba577 --- /dev/null +++ b/algorand/sandbox-algorand/images/Dockerfile @@ -0,0 +1,34 @@ +FROM ubuntu:18.04 +ARG channel + +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update && apt-get install -y ca-certificates curl + +# Use a non-privilidged user with a random UID / GID for security reasons +RUN groupadd -g 10353 algorand && \ + useradd -m -u 10353 -g algorand algorand && \ + chown -R algorand:algorand /opt && \ + ls -lha /opt + +USER algorand + +COPY --chown=algorand:algorand ./config/update.sh /tmp + +RUN \ + set -eux; \ + mkdir /opt/installer ; \ + cd /opt/installer ; \ + mv /tmp/update.sh . ; \ + ./update.sh -i -c $channel -p /opt/algorand/node -d /opt/algorand/node/data.tmp -n ; \ + rm -rf /opt/algorand/node/data.tmp ; \ + mkdir /opt/algorand/node/data + +COPY ./config/start.sh /opt/algorand + +VOLUME /opt/algorand/node/data + +# Set up environment variable to make life easier +ENV PATH="/opt/algorand/node:${PATH}" +ENV ALGORAND_DATA="/opt/algorand/node/data" + +ENTRYPOINT [ "/opt/algorand/start.sh" ] diff --git a/algorand/sandbox-algorand/images/algod/DevModeNetwork.json b/algorand/sandbox-algorand/images/algod/DevModeNetwork.json new file mode 100644 index 000000000..afe63e2a4 --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/DevModeNetwork.json @@ -0,0 +1,44 @@ +{ + "Genesis": { + "ConsensusProtocol": "future", + "NetworkName": "devmodenet", + "Wallets": [ + { + "Name": "Wallet1", + "Stake": 40, + "Online": true + }, + { + "Name": "Wallet2", + "Stake": 40, + "Online": true + }, + { + "Name": "Wallet3", + "Stake": 20, + "Online": true + } + ], + "DevMode": true + }, + "Nodes": [ + { + "Name": "Node", + "IsRelay": false, + "Wallets": [ + { + "Name": "Wallet1", + "ParticipationOnly": false + }, + { + "Name": "Wallet2", + "ParticipationOnly": false + }, + { + "Name": "Wallet3", + "ParticipationOnly": false + } + ] + } + ] +} diff --git a/algorand/sandbox-algorand/images/algod/Dockerfile b/algorand/sandbox-algorand/images/algod/Dockerfile new file mode 100644 index 000000000..098bdf3eb --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/Dockerfile @@ -0,0 +1,63 @@ +ARG GO_VERSION=1.17.5 +FROM golang:$GO_VERSION as algorand-algod + +# Support additional root CAs +COPY config.dev cert.pem* /certs/ +# Debian +RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/certs/ca-certificates.crt; fi +# git +RUN if [ -e /certs/cert.pem ]; then git config --global http.sslCAInfo /certs/cert.pem; fi + +ARG CHANNEL=master +ARG URL="https://github.com/algorand/go-algorand" +ARG BRANCH=master +ARG SHA= + +# When these are set attempt to connect to a network. +ARG GENESIS_FILE="" +ARG BOOTSTRAP_URL="" + +# Options for algod config +ARG ALGOD_PORT="4001" +ARG KMD_PORT="4002" +ARG TOKEN="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +ARG TEMPLATE="images/algod/DevModeNetwork.json" + +RUN echo "Installing from source. ${URL} -- ${BRANCH}" +ENV BIN_DIR="$HOME/node" +ENV ALGORAND_DATA="/opt/data" + +# Basic dependencies. +ENV HOME /opt +ENV DEBIAN_FRONTEND noninteractive +RUN apt-get update && apt-get install -y apt-utils curl git git-core bsdmainutils python3 + +# Copy lots of things into the container. The gitignore indicates which directories. +COPY . /tmp + +# Install algod binaries. +RUN /tmp/images/algod/install.sh \ + -d "${BIN_DIR}" \ + -u "https://github.com/algorand/go-algorand" \ + -b "master" \ + -s "" + +# Configure network +RUN /tmp/images/algod/setup.py \ + --bin-dir "$BIN_DIR" \ + --data-dir "/opt/data" \ + --start-script "/opt/start_algod.sh" \ + --network-dir "/opt/testnetwork" \ + --network-template "//tmp/images/algod/DevModeNetwork.json" \ + --network-token "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \ + --algod-port "4001" \ + --kmd-port "4002" \ + --bootstrap-url "${BOOTSTRAP_URL}" \ + --genesis-file "/tmp/${GENESIS_FILE}" + + +ENV PATH="$BIN_DIR:${PATH}" +WORKDIR /opt/data + +# Start algod +CMD ["/opt/start_algod.sh"] diff --git a/algorand/sandbox-algorand/images/algod/future_template.json b/algorand/sandbox-algorand/images/algod/future_template.json new file mode 100644 index 000000000..ca1ed40f6 --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/future_template.json @@ -0,0 +1,57 @@ +{ + "Genesis": { + "ConsensusProtocol": "future", + "NetworkName": "", + "Wallets": [ + { + "Name": "Wallet1", + "Stake": 10, + "Online": true + }, + { + "Name": "Wallet2", + "Stake": 40, + "Online": true + }, + { + "Name": "Wallet3", + "Stake": 40, + "Online": false + }, + { + "Name": "Wallet4", + "Stake": 10, + "Online": false + } + ] + }, + "Nodes": [ + { + "Name": "Primary", + "IsRelay": true, + "Wallets": [ + { + "Name": "Wallet1", + "ParticipationOnly": false + } + ] + }, + { + "Name": "Node", + "Wallets": [ + { + "Name": "Wallet2", + "ParticipationOnly": false + }, + { + "Name": "Wallet3", + "ParticipationOnly": false + }, + { + "Name": "Wallet4", + "ParticipationOnly": false + } + ] + } + ] +} diff --git a/algorand/sandbox-algorand/images/algod/install.sh b/algorand/sandbox-algorand/images/algod/install.sh new file mode 100755 index 000000000..165c1feec --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/install.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +# Script to install algod in all sorts of different ways. +# +# Parameters: +# -d : Location where binaries will be installed. +# -c : Channel to install. Mutually exclusive with source options. +# -u : Git repository URL. Mutually exclusive with -c. +# -b : Git branch. Mutually exclusive with -c. +# -s : (optional) Git Commit SHA hash. Mutually exclusive with -c. + +set -e + +rootdir=`dirname $0` +pushd $rootdir + +BINDIR="" +CHANNEL="" +URL="" +BRANCH="" +SHA="" + +while getopts "d:c:u:b:s:" opt; do + case "$opt" in + d) BINDIR=$OPTARG; ;; + c) CHANNEL=$OPTARG; ;; + u) URL=$OPTARG; ;; + b) BRANCH=$OPTARG; ;; + s) SHA=$OPTARG; ;; + esac +done + +if [ -z BINDIR ]; then + echo "-d is required." + exit 1 +fi + +if [ ! -z $CHANNEL ] && [ ! -z $BRANCH ]; then + echo "Set only one of -c or -b " + exit 1 +fi + +if [ ! -z $BRANCH ] && [ -z $URL ]; then + echo "If using -b , must also set -u " + exit 1 +fi + +echo "Installing algod with options:" +echo " BINDIR = ${BINDIR}" +echo " CHANNEL = ${CHANNEL}" +echo " URL = ${URL}" +echo " BRANCH = ${BRANCH}" +echo " SHA = ${SHA}" + +if [ ! -z $CHANNEL ]; then + ./update.sh -i -c $CHANNEL -p $BINDIR -d $BINDIR/data -n + exit 0 +fi + +if [ ! -z $BRANCH ]; then + git clone --single-branch --branch "${BRANCH}" "${URL}" + cd go-algorand + if [ "${SHA}" != "" ]; then + echo "Checking out ${SHA}" + git checkout "${SHA}" + fi + + git log -n 5 + + ./scripts/configure_dev.sh + make build + ./scripts/dev_install.sh -p $BINDIR +fi + +$BINDIR/algod -v diff --git a/algorand/sandbox-algorand/images/algod/setup.py b/algorand/sandbox-algorand/images/algod/setup.py new file mode 100755 index 000000000..723668242 --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/setup.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 + +# Script to help configure and run different algorand configurations. +# Notably this script can configure an algorand installation to run as a +# private network, or as a node connected to a long-running network. +# +# For parameter information run with './setup.py -h' +# +# Parameter error handling is not great with this script. It wont complain +# if you provide arguments unused parameters. + +import argparse +import os +import pprint +import shutil +import subprocess +import tarfile +import time +import json +import urllib.request +from os.path import expanduser, join + +from typing import List + +parser = argparse.ArgumentParser(description='''\ + Configure private network for SDK and prepare it to run. A start script and + symlink to data directory will be generated to make it easier to use.''') +parser.add_argument('--bin-dir', required=True, help='Location to install algod binaries.') +parser.add_argument('--data-dir', required=True, help='Location to place a symlink to the data directory.') +parser.add_argument('--start-script', required=True, help='Path to start script, including the script name.') +parser.add_argument('--network-template', required=True, help='Path to private network template file.') +parser.add_argument('--network-token', required=True, help='Valid token to use for algod/kmd.') +parser.add_argument('--algod-port', required=True, help='Port to use for algod.') +parser.add_argument('--kmd-port', required=True, help='Port to use for kmd.') +parser.add_argument('--network-dir', required=True, help='Path to create network.') +parser.add_argument('--bootstrap-url', required=True, help='DNS Bootstrap URL, empty for private networks.') +parser.add_argument('--genesis-file', required=True, help='Genesis file used by the network.') + +pp = pprint.PrettyPrinter(indent=4) + + +def algod_directories(network_dir): + """ + Compute data/kmd directories. + """ + data_dir=join(network_dir, 'Node') + + kmd_dir = None + options = [filename for filename in os.listdir(data_dir) if filename.startswith('kmd')] + + # When setting up the real network the kmd dir doesn't exist yet because algod hasn't been started. + if len(options) == 0: + kmd_dir=join(data_dir, 'kmd-v0.5') + os.mkdir(kmd_dir) + else: + kmd_dir=join(data_dir, options[0]) + + return data_dir, kmd_dir + + +def create_real_network(bin_dir, network_dir, template, genesis_file) -> List[str]: + data_dir_src=join(bin_dir, 'data') + target=join(network_dir, 'Node') + + # Reset in case it exists + if os.path.exists(target): + shutil.rmtree(target) + os.makedirs(target, exist_ok=True) + + # Copy in the genesis file... + shutil.copy(genesis_file, target) + + data_dir, kmd_dir = algod_directories(network_dir) + + return ['%s/goal node start -d %s' % (bin_dir, data_dir), + '%s/kmd start -t 0 -d %s' % (bin_dir, kmd_dir)] + + +def create_private_network(bin_dir, network_dir, template) -> List[str]: + """ + Create a private network. + """ + # Reset network dir before creating a new one. + if os.path.exists(args.network_dir): + shutil.rmtree(args.network_dir) + + # Use goal to create the private network. + subprocess.check_call(['%s/goal network create -n sandnet -r %s -t %s' % (bin_dir, network_dir, template)], shell=True) + + data_dir, kmd_dir = algod_directories(network_dir) + return ['%s/goal network start -r %s' % (bin_dir, network_dir), + '%s/kmd start -t 0 -d %s' % (bin_dir, kmd_dir)] + + +def configure_data_dir(network_dir, token, algod_port, kmd_port, bootstrap_url): + node_dir, kmd_dir = algod_directories(network_dir) + + # Set tokens + with open(join(node_dir, 'algod.token'), 'w') as f: + f.write(token) + with open(join(kmd_dir, 'kmd.token'), 'w') as f: + f.write(token) + + # Setup config, inject port + with open(join(node_dir, 'config.json'), 'w') as f: + f.write('{ "Version": 12, "GossipFanout": 1, "EndpointAddress": "0.0.0.0:%s", "DNSBootstrapID": "%s", "IncomingConnectionsLimit": 0, "Archival":false, "isIndexerActive":false, "EnableDeveloperAPI":true}' % (algod_port, bootstrap_url)) + with open(join(kmd_dir, 'kmd_config.json'), 'w') as f: + f.write('{ "address":"0.0.0.0:%s", "allowed_origins":["*"]}' % kmd_port) + + +if __name__ == '__main__': + args = parser.parse_args() + + print('Configuring network with the following arguments:') + pp.pprint(vars(args)) + + + # Setup network + privateNetworkMode = args.genesis_file == None or args.genesis_file == '' or os.path.isdir(args.genesis_file) + if privateNetworkMode: + print('Creating a private network.') + startCommands = create_private_network(args.bin_dir, args.network_dir, args.network_template) + else: + print('Setting up real retwork.') + startCommands = create_real_network(args.bin_dir, args.network_dir, args.network_template, args.genesis_file) + + # Write start script + print(f'Start commands for {args.start_script}:') + pp.pprint(startCommands) + with open(args.start_script, 'w') as f: + f.write('#!/usr/bin/env bash\n') + for line in startCommands: + f.write(f'{line}\n') + f.write('sleep infinity\n') + os.chmod(args.start_script, 0o755) + + # Create symlink + data_dir, _ = algod_directories(args.network_dir) + print(f'Creating symlink {args.data_dir} -> {data_dir}') + os.symlink(data_dir, args.data_dir) + + # Configure network + configure_data_dir(args.network_dir, args.network_token, args.algod_port, args.kmd_port, args.bootstrap_url) + diff --git a/algorand/sandbox-algorand/images/algod/template.json b/algorand/sandbox-algorand/images/algod/template.json new file mode 100644 index 000000000..090b275cd --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/template.json @@ -0,0 +1,56 @@ +{ + "Genesis": { + "NetworkName": "", + "Wallets": [ + { + "Name": "Wallet1", + "Stake": 10, + "Online": true + }, + { + "Name": "Wallet2", + "Stake": 40, + "Online": true + }, + { + "Name": "Wallet3", + "Stake": 40, + "Online": false + }, + { + "Name": "Wallet4", + "Stake": 10, + "Online": false + } + ] + }, + "Nodes": [ + { + "Name": "Primary", + "IsRelay": true, + "Wallets": [ + { + "Name": "Wallet1", + "ParticipationOnly": false + } + ] + }, + { + "Name": "Node", + "Wallets": [ + { + "Name": "Wallet2", + "ParticipationOnly": false + }, + { + "Name": "Wallet3", + "ParticipationOnly": false + }, + { + "Name": "Wallet4", + "ParticipationOnly": false + } + ] + } + ] +} diff --git a/algorand/sandbox-algorand/images/algod/update.sh b/algorand/sandbox-algorand/images/algod/update.sh new file mode 100755 index 000000000..b4d0c1e0f --- /dev/null +++ b/algorand/sandbox-algorand/images/algod/update.sh @@ -0,0 +1,676 @@ +#!/bin/bash + +# This is a copy of the standalone update script. +# The latest version is available on github: +# +# https://github.com/algorand/go-algorand/blob/97fb6a0fd3f74bcdb3fa0ac8ee49028cecba6e4f/cmd/updater/update.sh + +FILENAME=$(basename -- "$0") +SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" +UPDATETYPE="update" +INSTALLOPT="-u" +RESUME_INSTALL=0 +BINDIR="" +CHANNEL="" +DATADIRS=() +NOSTART="" +BINDIRSPEC="-p ${SCRIPTPATH}" +DATADIRSPEC="" +TESTROLLBACK="" +UNKNOWNARGS=() +HOSTEDFLAG="" +HOSTEDSPEC="" +BUCKET="" +GENESIS_NETWORK_DIR="" +GENESIS_NETWORK_DIR_SPEC="" +SKIP_UPDATE=0 +TOOLS_OUTPUT_DIR="" + +set -o pipefail + +# If someone set the environment variable asking us to cleanup +# when we're done, install a trap to do so +# We use an environment variable instead of an arg because +# older scripts won't recognize it and will fail (an issue with tests) +if [ "${CLEANUP_UPDATE_TEMP_DIR}" != "" ]; then + trap "rm -rf ${CLEANUP_UPDATE_TEMP_DIR}" 0 +fi + +while [ "$1" != "" ]; do + case "$1" in + -i) + UPDATETYPE="install" + INSTALLOPT="-i" + ;; + -u) + UPDATETYPE="update" + INSTALLOPT="-u" + ;; + -m) + UPDATETYPE="migrate" + INSTALLOPT="-m" + ;; + -r) + RESUME_INSTALL=1 + ;; + -c) + shift + CHANNEL="$1" + ;; + -d) + shift + THISDIR=$1 + mkdir -p ${THISDIR} >/dev/null + pushd ${THISDIR} >/dev/null + THISDIR=$(pwd -P) + popd >/dev/null + DATADIRS+=(${THISDIR}) + DATADIRSPEC+="-d ${THISDIR} " + ;; + -p) + shift + BINDIR="$1" + BINDIRSPEC="-p $1" + ;; + -n) + NOSTART="-n" + ;; + -testrollback) + TESTROLLBACK=1 + ;; + -hosted) + HOSTEDFLAG="-H" + HOSTEDSPEC="-hosted" + ;; + -g) + shift + GENESIS_NETWORK_DIR=$1 + GENESIS_NETWORK_DIR_SPEC="-g $1" + ;; + -b) + shift + BUCKET="-b $1" + ;; + -s) + SKIP_UPDATE=1 + ;; + -gettools) + shift + TOOLS_OUTPUT_DIR=$1 + ;; + *) + echo "Unknown option" "$1" + UNKNOWNARGS+=("$1") + ;; + esac + shift +done + +# If this is an update, we'll validate that before doing anything else. +# If this is an install, we'll create it. +if [ ${RESUME_INSTALL} -eq 0 ]; then + if [ "${BINDIR}" = "" ]; then + BINDIR="${SCRIPTPATH}" + fi +fi + +# If -d not specified, don't default any more +if [ "${#DATADIRS[@]}" -eq 0 ]; then + echo "You must specify at least one data directory with `-d`" + exit 1 +fi + +CURRENTVER=0 + +ROLLBACK=0 +ROLLBACKBIN=0 +ROLLBACKDATA=() +NEW_LEDGER=0 +RESTART_NODE=0 + +function check_install_valid() { + # Check for key files that indicate a valid install that can be updated + if [ ! -f "${BINDIR}/algod" ]; then + echo "Missing ${BINDIR}/algod" + return 1 + fi + return 0 +} + +function validate_channel_specified() { + if [ "${CHANNEL}" = "" ]; then + CHANNEL="$((${BINDIR}/algod -c) | head -n 1)" + if [ "${CHANNEL}" = "" ]; then + echo "Unable to determine release channel - please run again with -c " + return 1 + fi + fi +} + +function determine_current_version() { + CURRENTVER="$(( ${BINDIR}/algod -v 2>/dev/null || echo 0 ) | head -n 1)" + echo Current Version = ${CURRENTVER} +} + +function get_updater_url() { + local UNAME + local OS + local ARCH + UNAME=$(uname) + if [[ "${UNAME}" = "Darwin" ]]; then + OS="darwin" + UNAME=$(uname -m) + if [[ "${UNAME}" = "x86_64" ]]; then + ARCH="amd64" + else + echo "This platform ${UNAME} is not supported by updater." + exit 1 + fi + elif [[ "${UNAME}" = "Linux" ]]; then + OS="linux" + UNAME=$(uname -m) + if [[ "${UNAME}" = "x86_64" ]]; then + ARCH="amd64" + elif [[ "${UNAME}" = "armv6l" ]]; then + ARCH="arm" + elif [[ "${UNAME}" = "armv7l" ]]; then + ARCH="arm" + elif [[ "${UNAME}" = "aarch64" ]]; then + ARCH="arm64" + else + echo "This platform ${UNAME} is not supported by updater." + exit 1 + fi + else + echo "This operation system ${UNAME} is not supported by updater." + exit 1 + fi + UPDATER_FILENAME="install_master_${OS}-${ARCH}.tar.gz" + UPDATER_URL="https://github.com/algorand/go-algorand-doc/raw/master/downloads/installers/${OS}_${ARCH}/${UPDATER_FILENAME}" +} + +# check to see if the binary updater exists. if not, it will automatically the correct updater binary for the current platform +function check_for_updater() { + # check if the updater binary exist. + if [ -f "${SCRIPTPATH}/updater" ]; then + return 0 + fi + get_updater_url + + # check the curl is available. + CURL_VER=$(curl -V 2>/dev/null || true) + if [ "${CURL_VER}" = "" ]; then + # no curl is installed. + echo "updater binary is missing and cannot be downloaded since curl is missing." + if [[ "$(uname)" = "Linux" ]]; then + echo "To install curl, run the following command:" + echo "apt-get update; apt-get install -y curl" + fi + exit 1 + fi + + CURL_OUT=$(curl -LJO --silent ${UPDATER_URL}) + if [ "$?" != "0" ]; then + echo "failed to download updater binary from ${UPDATER_URL} using curl." + echo "${CURL_OUT}" + exit 1 + fi + + if [ ! -f "${SCRIPTPATH}/${UPDATER_FILENAME}" ]; then + echo "downloaded file ${SCRIPTPATH}/${UPDATER_FILENAME} is missing." + exit + fi + + tar -zxvf "${SCRIPTPATH}/${UPDATER_FILENAME}" updater + if [ "$?" != "0" ]; then + echo "failed to extract updater binary from ${SCRIPTPATH}/${UPDATER_FILENAME}" + exit 1 + fi + + rm -f "${SCRIPTPATH}/${UPDATER_FILENAME}" + echo "updater binary was downloaded" +} + +function check_for_update() { + determine_current_version + check_for_updater + LATEST="$(${SCRIPTPATH}/updater ver check -c ${CHANNEL} ${BUCKET} | sed -n '2 p')" + if [ $? -ne 0 ]; then + echo "No remote updates found" + return 1 + fi + + echo Latest Version = ${LATEST} + + if [ ${CURRENTVER} -ge ${LATEST} ]; then + if [ "${UPDATETYPE}" = "install" ]; then + echo No new version found - forcing install anyway + else + echo No new version found + return 1 + fi + fi + + echo New version found + return 0 +} + +function download_tools_update() { + local TOOLS_SPECIFIC_VERSION=$1 + echo "downloading tools update ${TOOLS_SPECIFIC_VERSION}" + TOOLS_TEMPDIR=$(mktemp -d 2>/dev/null || mktemp -d -t "tmp") + export TOOLS_CLEANUP_UPDATE_TEMP_DIR=${TOOLS_TEMPDIR} + trap "rm -rf ${TOOLS_CLEANUP_UPDATE_TEMP_DIR}" 0 + + TOOLS_TARFILE=${TOOLS_TEMPDIR}/${LATEST}.tar.gz + + if ( ! "${SCRIPTPATH}"/updater gettools -c "${CHANNEL}" -o "${TOOLS_TARFILE}" "${BUCKET}" "${TOOLS_SPECIFIC_VERSION}" ) ; then + echo "Error downloading tools tarfile" + exit 1 + fi + echo "Tools tarfile downloaded to ${TOOLS_TARFILE}" + + mkdir -p "${TOOLS_OUTPUT_DIR}" + if ( ! tar -xf "${TOOLS_TARFILE}" -C "${TOOLS_OUTPUT_DIR}" ) ; then + echo "Error extracting the tools update file ${TOOLS_TARFILE}" + exit 1 + fi + echo "Tools extracted to ${TOOLS_OUTPUT_DIR}" +} + +TEMPDIR="" +TARFILE="" +UPDATESRCDIR="" + +function download_update() { + SPECIFIC_VERSION=$1 + + if [ -n "${TOOLS_OUTPUT_DIR}" ]; then + download_tools_update "${SPECIFIC_VERSION}" + fi + + TEMPDIR=$(mktemp -d 2>/dev/null || mktemp -d -t "tmp") + export CLEANUP_UPDATE_TEMP_DIR=${TEMPDIR} + trap "rm -rf ${CLEANUP_UPDATE_TEMP_DIR}" 0 + + TARFILE=${TEMPDIR}/${LATEST}.tar.gz + UPDATESRCDIR=${TEMPDIR}/a + mkdir ${UPDATESRCDIR} + + ${SCRIPTPATH}/updater ver get -c ${CHANNEL} -o ${TARFILE} ${BUCKET} ${SPECIFIC_VERSION} + + if [ $? -ne 0 ]; then + echo Error downloading update file + exit 1 + fi + echo Update Downloaded to ${TARFILE} +} + +function check_and_download_update() { + check_for_update + if [ $? -ne 0 ]; then return 1; fi + + download_update +} + +function download_update_for_current_version() { + determine_current_version + echo "Downloading update package for current version ${CURRENTVER}..." + download_update "-v ${CURRENTVER}" +} + +function expand_update() { + echo Expanding update... + + tar -zxof ${TARFILE} -C ${UPDATESRCDIR} + if [ $? -ne 0 ]; then return 1; fi + + validate_update +} + +function validate_update() { + echo Validating update... + # We should consider including a version.info file + # that we can compare against the expected version + return 0 +} + +function shutdown_node() { + echo Stopping node... + if [ "$(pgrep -x algod)" != "" ] || [ "$(pgrep -x kmd)" != "" ] ; then + if [ -f ${BINDIR}/goal ]; then + for DD in ${DATADIRS[@]}; do + if [ -f ${DD}/algod.pid ] || [ -f ${DD}/**/kmd.pid ] ; then + echo Stopping node and waiting... + sudo -n systemctl stop algorand@$(systemd-escape ${DD}) + ${BINDIR}/goal node stop -d ${DD} + sleep 5 + else + echo "Node is running but not in ${DD} - not stopping" + # Clean up zombie (algod|kmd).net files + rm -f ${DD}/algod.net ${DD}/**/kmd.net + fi + done + fi + else + echo ... node not running + fi + + RESTART_NODE=1 +} + +function backup_binaries() { + echo Backing up current binary files... + mkdir -p ${BINDIR}/backup + BACKUPFILES="algod kmd carpenter doberman goal update.sh updater diagcfg" + # add node_exporter to the files list we're going to backup, but only we if had it previously deployed. + [ -f ${BINDIR}/node_exporter ] && BACKUPFILES="${BACKUPFILES} node_exporter" + tar -zcf ${BINDIR}/backup/bin-v${CURRENTVER}.tar.gz -C ${BINDIR} ${BACKUPFILES} >/dev/null 2>&1 +} + +function backup_data() { + CURDATADIR=$1 + BACKUPDIR="${CURDATADIR}/backup" + + echo "Backing up current data files from ${CURDATADIR}..." + mkdir -p ${BACKUPDIR} + BACKUPFILES="genesis.json wallet-genesis.id" + tar --no-recursion --exclude='*.log' --exclude='*.log.archive' --exclude='*.tar.gz' -zcf ${BACKUPDIR}/data-v${CURRENTVER}.tar.gz -C ${CURDATADIR} ${BACKUPFILES} >/dev/null 2>&1 +} + +function backup_current_version() { + backup_binaries + for DD in ${DATADIRS[@]}; do + backup_data ${DD} + done +} + +function rollback_binaries() { + echo "Rolling back binary files..." + tar -zxof ${BINDIR}/backup/bin-v${CURRENTVER}.tar.gz -C ${BINDIR} +} + +function rollback_data() { + CURDATADIR=$1 + BACKUPDIR="${CURDATADIR}/backup" + + echo "Rolling back data files in ${CURDATADIR}..." + rm ${CURDATADIR}/wallet-genesis.id + tar -zxof ${BACKUPDIR}/data-v${CURRENTVER}.tar.gz -C ${CURDATADIR} +} + +function install_new_binaries() { + if [ ! -d ${UPDATESRCDIR}/bin ]; then + return 0 + else + echo Installing new binary files... + ROLLBACKBIN=1 + rm -rf ${BINDIR}/new + mkdir ${BINDIR}/new + cp ${UPDATESRCDIR}/bin/* ${BINDIR}/new + mv ${BINDIR}/new/* ${BINDIR} + rm -rf ${BINDIR}/new + fi +} + +function reset_wallets_for_new_ledger() { + CURDATADIR=$1 + + echo "New Ledger - restoring genesis accounts in ${CURDATADIR}" + pushd ${CURDATADIR} >/dev/null + mkdir -p "${NEW_VER}" + for file in *.partkey *.rootkey; do + if [ -e "${file}" ]; then + cp "${file}" "${NEW_VER}/${file}" + echo 'Installed genesis account file: ' "${file}" + fi + done + popd >/dev/null +} + +function import_rootkeys() { + CURDATADIR=$1 + + echo "New Ledger - importing rootkeys for genesis accounts" + ${BINDIR}/goal account importrootkey -u -d ${CURDATADIR} +} + +function install_new_data() { + if [ ! -d ${UPDATESRCDIR}/data ]; then + return 0 + else + CURDATADIR=$1 + echo "Installing new data files into ${CURDATADIR}..." + ROLLBACKDATA+=(${CURDATADIR}) + cp ${UPDATESRCDIR}/data/* ${CURDATADIR} + fi +} + +function copy_genesis_files() { + echo "Copying genesis files locally" + cp -rf ${UPDATESRCDIR}/genesis/ ${BINDIR}/genesisfiles/ +} + +function check_for_new_ledger() { + CURDATADIR=$1 + echo "Checking for new ledger in ${CURDATADIR}" + EXISTING_VER=$(${UPDATESRCDIR}/bin/algod -d ${CURDATADIR} -g ${CURDATADIR}/genesis.json -G) + + if [ -z $EXISTING_VER ]; then + if [ -z ${GENESIS_NETWORK_DIR} ]; then + echo "Updating genesis files for default network" + else + echo "Installing genesis files for network ${GENESIS_NETWORK_DIR}" + fi + else + GENESIS_SPLIT=(${EXISTING_VER//-/ }) + GENESIS_NETWORK_DIR=${GENESIS_SPLIT[0]} + echo "Updating genesis files for network ${GENESIS_NETWORK_DIR}" + + # If that genesis dir doesn't exist, use the default file - this is likely a custom network build + if [ ! -d ${UPDATESRCDIR}/genesis/${GENESIS_NETWORK_DIR} ]; then + GENESIS_NETWORK_DIR="" + fi + fi + + NEW_VER=$(${UPDATESRCDIR}/bin/algod -d ${CURDATADIR} -g ${UPDATESRCDIR}/genesis/${GENESIS_NETWORK_DIR}/genesis.json -G) + if [ $? -ne 0 ]; then + echo "Cannot determine new genesis ID. Not updating. This may be a problem!" + return 1 + fi + + # Copy new genesis.json even if version didn't change; we might have + # changed the file itself in a compatible way. + cp ${UPDATESRCDIR}/genesis/${GENESIS_NETWORK_DIR}/genesis.json ${CURDATADIR} + + echo ${NEW_VER} > ${CURDATADIR}/wallet-genesis.id + if [ "${NEW_VER}" != "${EXISTING_VER}" ]; then + echo "New genesis ID, resetting wallets" + NEW_LEDGER=1 + reset_wallets_for_new_ledger ${CURDATADIR} + + import_rootkeys ${CURDATADIR} + fi +} + +# Delete all logs. +function clean_legacy_logs() { + CURDATADIR=$1 + + echo "Deleting existing log files in ${CURDATADIR}" + rm -f ${CURDATADIR}/node-*.log + rm -f ${CURDATADIR}/node-*.log.archive + return 0 +} + +function startup_node() { + if [ "${NOSTART}" != "" ]; then + echo Auto-start node disabled - not starting + return + fi + + CURDATADIR=$1 + echo Starting node in ${CURDATADIR}... + + check_install_valid + if [ $? -ne 0 ]; then + fail_and_exit "Installation does not appear to be valid" + fi + + sudo -n systemctl start algorand@$(systemd-escape ${CURDATADIR}) + if [ $? -ne 0 ]; then + ${BINDIR}/goal node start -d ${CURDATADIR} ${HOSTEDFLAG} + fi +} + +function startup_nodes() { + for DD in ${DATADIRS[@]}; do + startup_node ${DD} + done +} + +function rollback() { + echo Rolling back from failed update... + if [ ${ROLLBACKBIN} -ne 0 ]; then + rollback_binaries + fi + for ROLLBACKDIR in ${ROLLBACKDATA[@]}; do + rollback_data ${ROLLBACKDIR} + done +} + +function fail_and_exit() { + echo "*** UPDATE FAILED: $1 ***" + if [ ${ROLLBACK} -ne 0 ]; then + ROLLBACK=0 + rollback + check_install_valid + if [ ${RESTART_NODE} -ne 0 ]; then + startup_nodes + fi + exit 0 + fi + exit 1 +} + +function apply_fixups() { + echo "Applying migration fixups..." + + # Delete obsolete algorand binary - renamed to 'goal' + rm ${BINDIR}/algorand >/dev/null 2>&1 + + for DD in ${DATADIRS[@]}; do + clean_legacy_logs ${DD} + + # Purge obsolete cadaver files (now agreement.cdv[.archive]) + rm -f ${DD}/service*.cadaver + done +} + +#-------------------------------------------- +# Main Update Driver + +# Need to verify the bindir was specified (with -p) +# and that it's a valid directory. +# Unless it's an install +if [ ! -d "${BINDIR}" ]; then + if [ "${UPDATETYPE}" = "install" ]; then + mkdir -p ${BINDIR} + else + fail_and_exit "Missing or invalid binaries path specified '${BINDIR}'" + fi +fi + +if [ "${UPDATETYPE}" != "install" ]; then + check_install_valid + if [ $? -ne 0 ]; then + echo "Unable to perform an update - installation does not appear valid" + exit 1 + fi +fi + +# If we're initiating an update/install, check for an update and if we have a new one, +# expand it and invoke the new update.sh script. +if [ ${RESUME_INSTALL} -eq 0 ]; then + validate_channel_specified + + if [ "${UPDATETYPE}" = "migrate" ]; then + download_update_for_current_version + else + check_and_download_update + fi + + if [ $? -ne 0 ]; then + # No update - stop here + exit $? + fi + + expand_update + if [ $? -ne 0 ]; then + fail_and_exit "Error expanding update" + fi + + # Spawn the new update script and exit - this allows us to push update.sh changes that take effect immediately + # Note that the SCRIPTPATH we're passing in should be our binaries directory, which is what we expect to be + # passed as the last argument (if any) + echo "Starting the new update script to complete the installation..." + exec "${UPDATESRCDIR}/bin/${FILENAME}" ${INSTALLOPT} -r -c ${CHANNEL} ${DATADIRSPEC} ${NOSTART} ${BINDIRSPEC} ${HOSTEDSPEC} ${GENESIS_NETWORK_DIR_SPEC} "${UNKNOWNARGS[@]}" + + # If we're still here, exec failed. + fail_and_exit "Error executing the new update script - unable to continue" +else + # We're running the script from our expanded update, which is located in the last script's ${TEMPDIR}/a/bin + # We need to define our TEMPDIR and UPDATESRCDIR to match those values; we do so by making them relative + # to where our resuming script lives. + TEMPDIR=${SCRIPTPATH}/../.. + UPDATESRCDIR=${SCRIPTPATH}/.. + echo "... Resuming installation from the latest update script" + + determine_current_version +fi + +# Shutdown node before backing up so data is consistent and files aren't locked / in-use. +shutdown_node + +if [ ${SKIP_UPDATE} -eq 0 ]; then + backup_current_version +fi + +# We don't care about return code - doesn't matter if we failed to archive + +ROLLBACK=1 + +install_new_binaries +if [ $? -ne 0 ]; then + fail_and_exit "Error installing new files" +fi + +for DD in ${DATADIRS[@]}; do + install_new_data ${DD} + if [ $? -ne 0 ]; then + fail_and_exit "Error installing data files into ${DD}" + fi +done + +copy_genesis_files + +for DD in ${DATADIRS[@]}; do + check_for_new_ledger ${DD} + if [ $? -ne 0 ]; then + fail_and_exit "Error updating ledger in ${DD}" + fi +done + +if [ "${TESTROLLBACK}" != "" ]; then + fail_and_exit "Simulating update failure - rolling back" +fi + +apply_fixups + +if [ "${NOSTART}" != "" ]; then + echo "Install complete - restart node manually" +else + startup_nodes +fi + +exit 0 diff --git a/algorand/sandbox-algorand/images/indexer/Dockerfile b/algorand/sandbox-algorand/images/indexer/Dockerfile new file mode 100644 index 000000000..c3f7b28cb --- /dev/null +++ b/algorand/sandbox-algorand/images/indexer/Dockerfile @@ -0,0 +1,34 @@ +ARG GO_VERSION=1.17.5 +FROM golang:$GO_VERSION-alpine + +# Support additional root CAs +COPY config.dev cert.pem* /certs/ +# Debian (for top Go priority) +RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/certs/ca-certificates.crt; fi +# Alpine +RUN if [ -e /certs/cert.pem ]; then cp /certs/cert.pem /etc/ssl/cert.pem; fi + +# Environment variables used by install.sh +ARG URL=https://github.com/algorand/indexer +ARG BRANCH=master +ARG SHA="" + +ENV HOME /opt/indexer +WORKDIR /opt/indexer + +ENV DEBIAN_FRONTEND noninteractive +RUN apk add --no-cache git bzip2 make bash libtool boost-dev autoconf automake g++ postgresql + +# Support additional root CAs +# git +RUN if [ -e /certs/cert.pem ]; then git config --global http.sslCAInfo /certs/cert.pem; fi + +# Copy files to container. +COPY images/indexer/disabled.go /tmp/disabled.go +COPY images/indexer/start.sh /tmp/start.sh +COPY images/indexer/install.sh /tmp/install.sh + +# Install indexer binaries. +RUN /tmp/install.sh + +CMD ["/tmp/start.sh"] diff --git a/algorand/sandbox-algorand/images/indexer/disabled.go b/algorand/sandbox-algorand/images/indexer/disabled.go new file mode 100644 index 000000000..7a9e033ba --- /dev/null +++ b/algorand/sandbox-algorand/images/indexer/disabled.go @@ -0,0 +1,32 @@ +package main + +import ( + "flag" + "fmt" + "net/http" + "os" +) + + +func main() { + var port int + var code int + var message string + + flag.IntVar(&port, "port", 8980, "port to start the server on.") + flag.IntVar(&code, "code", 400, "response code to use.") + flag.StringVar(&message, "message", "this is all that happens", "response message to display.") + + flag.Parse() + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request){ + w.WriteHeader(code) + fmt.Fprintf(w, "%s\n", message) + }) + + + fmt.Printf("Starting server at port %d\nResponse code (%d)\nmessage (%s)\n", port, code, message) + if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + } +} diff --git a/algorand/sandbox-algorand/images/indexer/install.sh b/algorand/sandbox-algorand/images/indexer/install.sh new file mode 100755 index 000000000..6f06ff148 --- /dev/null +++ b/algorand/sandbox-algorand/images/indexer/install.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Build indexer and put binary in /tmp. +# +# Configured with environment variables: +# URL - Git repository URL. +# BRANCH - Git branch to clone. +# SHA - (optional) Specific commit hash to checkout. +set -e + +# Sometimes indexer is disabled, detect the missing build config. +if [ -z "${BRANCH}" ] || [ -z "${URL}" ]; then + echo "Missing BRANCH or URL environment variable. Skipping install." + exit 0 +fi + +git clone --single-branch --branch "${BRANCH}" "${URL}" indexer-git +if [ "${SHA}" != "" ]; then + echo "Checking out ${SHA}" + git checkout "${SHA}"; +fi +cd indexer-git +make +cp cmd/algorand-indexer/algorand-indexer /tmp diff --git a/algorand/sandbox-algorand/images/indexer/start.sh b/algorand/sandbox-algorand/images/indexer/start.sh new file mode 100755 index 000000000..82c68a466 --- /dev/null +++ b/algorand/sandbox-algorand/images/indexer/start.sh @@ -0,0 +1,87 @@ +#!/bin/bash + +# Start indexer daemon. There are various configurations controlled by +# environment variables. +# +# Configuration: +# DISABLED - If set start a server that returns an error instead of indexer. +# CONNECTION_STRING - the postgres connection string to use. +# SNAPSHOT - snapshot to import, if set don't connect to algod. +# PORT - port to start indexer on. +# ALGOD_ADDR - host:port to connect to for algod. +# ALGOD_TOKEN - token to use when connecting to algod. + + +export PORT="8980" +export CONNECTION_STRING="host=localhost port=5432 user=algorand password=algorand dbname=indexer_db sslmode=disable" +export ALGOD_ADDR="localhost:4001" +export ALGOD_TOKEN="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + +set -e +set -x +start_with_algod() { + echo "Starting indexer against algod." + + for i in 1 2 3 4 5; do + wget "${ALGOD_ADDR}"/genesis -O genesis.json && break + echo "Algod not responding... waiting." + sleep 15 + done + + if [ ! -f genesis.json ]; then + echo "Failed to create genesis file!" + exit 1 + fi + +# PGPASSWORD=algorand psql --host=algo-indexer-db --port=5432 --username=algorand --dbname=indexer_db -c "DROP DATABASE IF EXISTS postgres" +# PGPASSWORD=algorand psql --host=algo-indexer-db --port=5432 --username=algorand --dbname=indexer_db -c "DROP DATABASE IF EXISTS template0" +# PGPASSWORD=algorand psql --host=algo-indexer-db --port=5432 --username=algorand --dbname=indexer_db -c "DROP DATABASE IF EXISTS template1" +# PGPASSWORD=algorand psql --host=algo-indexer-db --port=5432 --username=algorand -c "DROP DATABASE IF EXISTS indexer_db" +# PGPASSWORD=algorand psql --host=algo-indexer-db --port=5432 --username=algorand -c "CREATE DATABASE indexer_db" + + /tmp/algorand-indexer daemon \ + --dev-mode \ + --server ":$PORT" \ + --enable-all-parameters \ + -P "$CONNECTION_STRING" \ + --algod-net "${ALGOD_ADDR}" \ + --algod-token "${ALGOD_TOKEN}" \ + --genesis "genesis.json" \ + --logfile "/dev/stdout" >> /tmp/command.txt +} + +import_and_start_readonly() { + echo "Starting indexer with DB." + + # Extract the correct dataset + ls -lh /tmp + mkdir -p /tmp/indexer-snapshot + echo "Extracting ${SNAPSHOT}" + tar -xf "${SNAPSHOT}" -C /tmp/indexer-snapshot + + /tmp/algorand-indexer import \ + -P "$CONNECTION_STRING" \ + --genesis "/tmp/indexer-snapshot/algod/genesis.json" \ + /tmp/indexer-snapshot/blocktars/* \ + --logfile "/tmp/indexer-log.txt" >> /tmp/command.txt + + /tmp/algorand-indexer daemon \ + --dev-mode \ + --server ":$PORT" \ + -P "$CONNECTION_STRING" \ + --logfile "/tmp/indexer-log.txt" >> /tmp/command.txt +} + +disabled() { + go run /tmp/disabled.go -port "$PORT" -code 400 -message "Indexer disabled for this configuration." +} + +if [ ! -z "$DISABLED" ]; then + disabled +elif [ -z "${SNAPSHOT}" ]; then + start_with_algod +else + import_and_start_readonly +fi + +sleep infinity diff --git a/algorand/sandbox-algorand/tilt-compose.yml b/algorand/sandbox-algorand/tilt-compose.yml new file mode 100644 index 000000000..9e7e20cf8 --- /dev/null +++ b/algorand/sandbox-algorand/tilt-compose.yml @@ -0,0 +1,58 @@ +version: '3' + +services: + algo-algod: + container_name: "algorand-tilt-algod" + build: + context: . + dockerfile: ./images/algod/Dockerfile + args: + CHANNEL: "" + URL: "https://github.com/algorand/go-algorand" + BRANCH: "master" + SHA: "" + BOOTSTRAP_URL: "" + GENESIS_FILE: "" + TEMPLATE: "images/algod/DevModeNetwork.json" + TOKEN: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ALGOD_PORT: "4001" + KMD_PORT: "4002" + CDT_PORT: "9392" + ports: + - 4001:4001 + - 4002:4002 + - 9392:9392 + + algo-indexer: + container_name: "algorand-tilt-indexer" + build: + context: . + dockerfile: ./images/indexer/Dockerfile + args: + URL: "https://github.com/algorand/indexer" + BRANCH: "develop" + SHA: "" + ports: + - 8980:8980 + restart: unless-stopped + environment: + DISABLED: "" + PORT: "8980" + SNAPSHOT: "" + CONNECTION_STRING: "host=algo-indexer-db port=5432 user=algorand password=algorand dbname=indexer_db sslmode=disable" + ALGOD_ADDR: "algo-algod:4001" + ALGOD_TOKEN: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + depends_on: + - algo-indexer-db + - algo-algod + + algo-indexer-db: + image: "postgres:13-alpine" + container_name: "algorand-tilt-postgres" + ports: + - 5433:5432 + user: postgres + environment: + POSTGRES_USER: algorand + POSTGRES_PASSWORD: algorand + POSTGRES_DB: indexer_db diff --git a/algorand/teal/README b/algorand/teal/README new file mode 100644 index 000000000..d0e549899 --- /dev/null +++ b/algorand/teal/README @@ -0,0 +1,8 @@ + +While these are generated files, due to the non-deterministic behavior +of the pyteal compiler based on what has been done before, we cannot +reliably recreate the exact same teal file from the exact same pyteal +source. + +As a result, we need to check the generated files in so that we can +verify the hash of the compiled code while generating upgrade vaa's diff --git a/algorand/teal/core_approve.teal b/algorand/teal/core_approve.teal new file mode 100644 index 000000000..fded6b82a --- /dev/null +++ b/algorand/teal/core_approve.teal @@ -0,0 +1,1562 @@ +#pragma version 6 +intcblock 1 0 127 2 1000 202 204 208 213 274 267 237 253 19200 241 242 196 128 255 +bytecblock 0x 0x0008 0x677561726469616e 0x63757272656e74477561726469616e536574496e646578 0x6e6f70 0x76657269667953696773 0x4d657373616765466565 0x766572696679564141 0x76616c6964557064617465417070726f766548617368 0x767068617368 0x7075626c6973684d657373616765 0x0001 0x0000000000000000000000000000000000000000000000000000000000000004 0x00000000000000000000000000000000000000000000000000000000436f7265 0x0000 0x626f6f746564 0x6d657461 +txn ApplicationID +intc_1 // 0 +== +bnz main_l75 +txn OnCompletion +pushint 4 // UpdateApplication +== +bnz main_l74 +txn OnCompletion +pushint 5 // DeleteApplication +== +bnz main_l73 +txn OnCompletion +intc_0 // OptIn +== +bnz main_l72 +txn OnCompletion +intc_1 // NoOp +== +bnz main_l6 +err +main_l6: +txna ApplicationArgs 0 +bytec 10 // "publishMessage" +== +bnz main_l69 +txna ApplicationArgs 0 +bytec 4 // "nop" +== +bnz main_l68 +txna ApplicationArgs 0 +pushbytes 0x696e6974 // "init" +== +bnz main_l52 +txna ApplicationArgs 0 +bytec 5 // "verifySigs" +== +bnz main_l51 +txna ApplicationArgs 0 +bytec 7 // "verifyVAA" +== +bnz main_l29 +txna ApplicationArgs 0 +pushbytes 0x676f7665726e616e6365 // "governance" +== +bnz main_l13 +err +main_l13: +callsub checkForDuplicate_11 +txn GroupIndex +intc_0 // 1 +- +gtxns TypeEnum +pushint 6 // appl +== +txn GroupIndex +intc_0 // 1 +- +gtxns ApplicationID +txn ApplicationID +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxnsa ApplicationArgs 0 +bytec 7 // "verifyVAA" +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxns Sender +txn Sender +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxns RekeyTo +global ZeroAddress +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxnsa ApplicationArgs 1 +txna ApplicationArgs 1 +== +&& +txn GroupIndex +gtxns RekeyTo +global ZeroAddress +== +&& +txn GroupIndex +gtxns Sender +txn Sender +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxnsa Accounts 0 +txna Accounts 0 +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxnsa Accounts 1 +txna Accounts 1 +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxnsa Accounts 2 +txna Accounts 2 +== +&& +pushint 483 // 483 +&& +assert +bytec_3 // "currentGuardianSetIndex" +app_global_get +store 26 +load 26 +intc_1 // 0 +!= +bnz main_l28 +main_l14: +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 14 // 14 ++ +store 21 +txna ApplicationArgs 1 +load 21 +intc_3 // 2 +extract3 +bytec 11 // 0x0001 +== +intc 5 // 202 +&& +assert +txna ApplicationArgs 1 +load 21 +intc_3 // 2 ++ +pushint 32 // 32 +extract3 +bytec 12 // 0x0000000000000000000000000000000000000000000000000000000000000004 +== +intc 6 // 204 +&& +assert +load 21 +pushint 43 // 43 ++ +store 21 +txna ApplicationArgs 1 +load 21 +pushint 32 // 32 +extract3 +bytec 13 // 0x00000000000000000000000000000000000000000000000000000000436f7265 +== +intc 7 // 208 +&& +assert +load 21 +pushint 32 // 32 ++ +store 21 +txna ApplicationArgs 1 +load 21 +intc_0 // 1 ++ +intc_3 // 2 +extract3 +store 28 +load 28 +bytec_1 // 0x0008 +== +load 28 +bytec 14 // 0x0000 +== +|| +intc 8 // 213 +&& +assert +txna ApplicationArgs 1 +load 21 +intc_0 // 1 +extract3 +btoi +store 22 +load 22 +intc_0 // 1 +== +bnz main_l27 +load 22 +intc_3 // 2 +== +bnz main_l22 +load 22 +pushint 3 // 3 +== +bnz main_l21 +load 22 +pushint 4 // 4 +== +bnz main_l19 +err +main_l19: +load 21 +intc_0 // 1 ++ +store 21 +load 28 +bytec_1 // 0x0008 +== +intc 9 // 274 +&& +assert +load 21 +pushint 26 // 26 ++ +store 21 +txna ApplicationArgs 1 +load 21 +pushint 8 // 8 +extract3 +btoi +store 24 +load 21 +pushint 8 // 8 ++ +store 21 +txna ApplicationArgs 1 +load 21 +pushint 32 // 32 +extract3 +store 23 +itxn_begin +intc_0 // pay +itxn_field TypeEnum +load 23 +itxn_field Receiver +load 24 +itxn_field Amount +intc_1 // 0 +itxn_field Fee +itxn_submit +main_l20: +intc_0 // 1 +return +intc_0 // 1 +return +main_l21: +load 21 +intc_0 // 1 ++ +store 21 +load 28 +bytec_1 // 0x0008 +== +intc 10 // 267 +&& +assert +load 21 +intc_3 // 2 ++ +pushint 24 // 24 ++ +store 21 +txna ApplicationArgs 1 +load 21 +pushint 8 // 8 +extract3 +btoi +store 24 +bytec 6 // "MessageFee" +load 24 +app_global_put +b main_l20 +main_l22: +load 21 +pushint 3 // 3 ++ +store 21 +txna ApplicationArgs 1 +load 21 +pushint 4 // 4 +extract3 +btoi +store 25 +txna Accounts 3 +load 25 +bytec_2 // "guardian" +callsub getsigaddress_9 +== +intc 11 // 237 +&& +assert +intc_1 // 0 +intc_1 // 0 +== +bnz main_l26 +main_l23: +bytec_3 // "currentGuardianSetIndex" +load 25 +app_global_put +load 21 +pushint 4 // 4 ++ +store 21 +txna ApplicationArgs 1 +load 21 +intc_0 // 1 +extract3 +btoi +store 27 +load 27 +intc_1 // 0 +> +intc 12 // 253 +&& +assert +pushint 3 // 3 +intc_1 // 0 +txna ApplicationArgs 1 +load 21 +intc_0 // 1 +pushint 20 // 20 +load 27 +* ++ +extract3 +callsub write_7 +pop +txna Accounts 3 +txna Accounts 2 +!= +bnz main_l25 +main_l24: +pushint 3 // 3 +bytec_2 // "guardian" +callsub meta_5 +b main_l20 +main_l25: +intc_3 // 2 +intc 4 // 1000 +txn FirstValid +intc 13 // 19200 ++ +itob +callsub write_7 +pop +b main_l24 +main_l26: +txna Accounts 3 +txna Accounts 2 +!= +intc 14 // 241 +&& +assert +load 25 +load 26 +> +intc 15 // 242 +&& +assert +b main_l23 +main_l27: +load 21 +pushint 3 // 3 ++ +store 21 +bytec 8 // "validUpdateApproveHash" +txna ApplicationArgs 1 +load 21 +pushint 32 // 32 +extract3 +app_global_put +b main_l20 +main_l28: +txna ApplicationArgs 1 +extract 1 4 +store 25 +load 25 +btoi +load 26 +== +intc 16 // 196 +&& +assert +b main_l14 +main_l29: +txna Accounts 2 +txna ApplicationArgs 1 +extract 1 4 +btoi +bytec_2 // "guardian" +callsub getsigaddress_9 +== +pushint 372 // 372 +&& +assert +intc_3 // 2 +bytec_2 // "guardian" +callsub checkMeta_6 +intc_3 // 2 +intc_1 // 0 +callsub getbyte_2 +store 12 +intc_3 // 2 +intc_0 // 1 +intc_0 // 1 +pushint 20 // 20 +load 12 +* ++ +callsub read_4 +store 13 +intc_3 // 2 +intc 4 // 1000 +pushint 1008 // 1008 +callsub read_4 +btoi +store 18 +load 18 +intc_1 // 0 +!= +bnz main_l50 +main_l30: +pushbytes 0x00000000 // 0x00000000 +store 17 +txna ApplicationArgs 1 +extract 5 1 +btoi +store 14 +pushint 6 // 6 +load 14 +pushint 66 // 66 +* ++ +store 15 +txna ApplicationArgs 1 +load 15 +txna ApplicationArgs 1 +len +load 15 +- +extract3 +keccak256 +keccak256 +store 16 +load 12 +intc_1 // 0 +> +load 14 +load 12 +<= +&& +load 14 +load 12 +intc_3 // 2 +* +pushint 3 // 3 +/ +> +&& +pushint 393 // 393 +&& +assert +pushint 6 // 6 +store 15 +txn GroupIndex +intc_1 // 0 +> +pushint 403 // 403 +&& +assert +txn GroupIndex +intc_0 // 1 +- +store 10 +load 10 +gtxns NumAppArgs +intc_1 // 0 +> +pushint 405 // 405 +&& +assert +load 10 +gtxnsa ApplicationArgs 0 +store 11 +main_l31: +load 10 +intc_1 // 0 +> +load 11 +bytec 5 // "verifySigs" +== +load 11 +bytec 4 // "nop" +== +|| +&& +bnz main_l47 +main_l32: +load 11 +bytec 5 // "verifySigs" +!= +load 11 +bytec 4 // "nop" +!= +&& +bnz main_l46 +main_l33: +load 10 +txn GroupIndex +<= +bnz main_l35 +load 15 +pushint 6 // 6 +load 14 +pushint 66 // 66 +* ++ +== +pushint 474 // 474 +&& +assert +intc_0 // 1 +return +main_l35: +load 10 +gtxns TypeEnum +pushint 6 // appl +== +load 10 +gtxns RekeyTo +global ZeroAddress +== +&& +load 10 +gtxns ApplicationID +txn ApplicationID +== +&& +load 10 +gtxnsa Accounts 1 +txna Accounts 1 +== +&& +load 10 +gtxnsa Accounts 2 +txna Accounts 2 +== +&& +pushint 421 // 421 +&& +assert +load 10 +gtxnsa ApplicationArgs 0 +store 11 +load 11 +bytec 5 // "verifySigs" +== +bnz main_l42 +load 11 +bytec 4 // "nop" +== +bnz main_l41 +load 11 +bytec 7 // "verifyVAA" +== +bnz main_l41 +intc_0 // 1 +intc_0 // 1 +== +bnz main_l40 +err +main_l40: +intc_1 // 0 +return +main_l41: +load 10 +intc_0 // 1 ++ +store 10 +b main_l33 +main_l42: +load 10 +gtxnsa ApplicationArgs 1 +store 18 +txna ApplicationArgs 1 +load 15 +load 18 +len +extract3 +load 18 +== +pushint 438 // 438 +&& +assert +load 15 +load 18 +len ++ +store 19 +bytec_0 // "" +store 18 +main_l43: +load 15 +load 19 +< +bnz main_l45 +load 10 +gtxnsa ApplicationArgs 2 +load 18 +== +load 10 +gtxns Sender +bytec 9 // "vphash" +app_global_get +== +&& +load 10 +gtxnsa ApplicationArgs 3 +load 16 +== +&& +pushint 458 // 458 +&& +assert +b main_l41 +main_l45: +txna ApplicationArgs 1 +load 15 +intc_0 // 1 +extract3 +btoi +store 20 +load 17 +load 20 +getbit +intc_1 // 0 +== +pushint 449 // 449 +&& +assert +load 17 +load 20 +intc_0 // 1 +setbit +store 17 +load 18 +load 13 +load 20 +pushint 20 // 20 +* +pushint 20 // 20 +extract3 +concat +store 18 +load 15 +pushint 66 // 66 ++ +store 15 +b main_l43 +main_l46: +load 10 +intc_0 // 1 ++ +store 10 +b main_l33 +main_l47: +load 10 +intc_0 // 1 +- +store 10 +load 10 +gtxns NumAppArgs +intc_1 // 0 +> +bnz main_l49 +bytec_0 // "" +store 11 +b main_l32 +main_l49: +load 10 +gtxnsa ApplicationArgs 0 +store 11 +b main_l31 +main_l50: +txn FirstValid +load 18 +< +pushint 381 // 381 +&& +assert +b main_l30 +main_l51: +intc_0 // 1 +return +main_l52: +bytec 9 // "vphash" +txna ApplicationArgs 2 +app_global_put +txn Sender +global CreatorAddress +== +pushint 301 // 301 +&& +assert +bytec 15 // "booted" +app_global_get +intc_1 // 0 +== +pushint 304 // 304 +&& +assert +bytec 15 // "booted" +pushbytes 0x74727565 // "true" +app_global_put +callsub checkForDuplicate_11 +bytec_3 // "currentGuardianSetIndex" +app_global_get +store 7 +load 7 +intc_1 // 0 +!= +bnz main_l67 +main_l53: +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 14 // 14 ++ +store 2 +txna ApplicationArgs 1 +load 2 +intc_3 // 2 +extract3 +bytec 11 // 0x0001 +== +intc 5 // 202 +&& +assert +txna ApplicationArgs 1 +load 2 +intc_3 // 2 ++ +pushint 32 // 32 +extract3 +bytec 12 // 0x0000000000000000000000000000000000000000000000000000000000000004 +== +intc 6 // 204 +&& +assert +load 2 +pushint 43 // 43 ++ +store 2 +txna ApplicationArgs 1 +load 2 +pushint 32 // 32 +extract3 +bytec 13 // 0x00000000000000000000000000000000000000000000000000000000436f7265 +== +intc 7 // 208 +&& +assert +load 2 +pushint 32 // 32 ++ +store 2 +txna ApplicationArgs 1 +load 2 +intc_0 // 1 ++ +intc_3 // 2 +extract3 +store 9 +load 9 +bytec_1 // 0x0008 +== +load 9 +bytec 14 // 0x0000 +== +|| +intc 8 // 213 +&& +assert +txna ApplicationArgs 1 +load 2 +intc_0 // 1 +extract3 +btoi +store 3 +load 3 +intc_0 // 1 +== +bnz main_l66 +load 3 +intc_3 // 2 +== +bnz main_l61 +load 3 +pushint 3 // 3 +== +bnz main_l60 +load 3 +pushint 4 // 4 +== +bnz main_l58 +err +main_l58: +load 2 +intc_0 // 1 ++ +store 2 +load 9 +bytec_1 // 0x0008 +== +intc 9 // 274 +&& +assert +load 2 +pushint 26 // 26 ++ +store 2 +txna ApplicationArgs 1 +load 2 +pushint 8 // 8 +extract3 +btoi +store 5 +load 2 +pushint 8 // 8 ++ +store 2 +txna ApplicationArgs 1 +load 2 +pushint 32 // 32 +extract3 +store 4 +itxn_begin +intc_0 // pay +itxn_field TypeEnum +load 4 +itxn_field Receiver +load 5 +itxn_field Amount +intc_1 // 0 +itxn_field Fee +itxn_submit +main_l59: +intc_0 // 1 +return +main_l60: +load 2 +intc_0 // 1 ++ +store 2 +load 9 +bytec_1 // 0x0008 +== +intc 10 // 267 +&& +assert +load 2 +intc_3 // 2 ++ +pushint 24 // 24 ++ +store 2 +txna ApplicationArgs 1 +load 2 +pushint 8 // 8 +extract3 +btoi +store 5 +bytec 6 // "MessageFee" +load 5 +app_global_put +b main_l59 +main_l61: +load 2 +pushint 3 // 3 ++ +store 2 +txna ApplicationArgs 1 +load 2 +pushint 4 // 4 +extract3 +btoi +store 6 +txna Accounts 3 +load 6 +bytec_2 // "guardian" +callsub getsigaddress_9 +== +intc 11 // 237 +&& +assert +intc_0 // 1 +intc_1 // 0 +== +bnz main_l65 +main_l62: +bytec_3 // "currentGuardianSetIndex" +load 6 +app_global_put +load 2 +pushint 4 // 4 ++ +store 2 +txna ApplicationArgs 1 +load 2 +intc_0 // 1 +extract3 +btoi +store 8 +load 8 +intc_1 // 0 +> +intc 12 // 253 +&& +assert +pushint 3 // 3 +intc_1 // 0 +txna ApplicationArgs 1 +load 2 +intc_0 // 1 +pushint 20 // 20 +load 8 +* ++ +extract3 +callsub write_7 +pop +txna Accounts 3 +txna Accounts 2 +!= +bnz main_l64 +main_l63: +pushint 3 // 3 +bytec_2 // "guardian" +callsub meta_5 +b main_l59 +main_l64: +intc_3 // 2 +intc 4 // 1000 +txn FirstValid +intc 13 // 19200 ++ +itob +callsub write_7 +pop +b main_l63 +main_l65: +txna Accounts 3 +txna Accounts 2 +!= +intc 14 // 241 +&& +assert +load 6 +load 7 +> +intc 15 // 242 +&& +assert +b main_l62 +main_l66: +load 2 +pushint 3 // 3 ++ +store 2 +bytec 8 // "validUpdateApproveHash" +txna ApplicationArgs 1 +load 2 +pushint 32 // 32 +extract3 +app_global_put +b main_l59 +main_l67: +txna ApplicationArgs 1 +extract 1 4 +store 6 +load 6 +btoi +load 7 +== +intc 16 // 196 +&& +assert +b main_l53 +main_l68: +intc_0 // 1 +return +main_l69: +txna Accounts 1 +intc_1 // 0 +txn Sender +callsub getsigaddress_9 +== +pushint 154 // 154 +&& +assert +bytec 6 // "MessageFee" +app_global_get +store 1 +load 1 +intc_1 // 0 +> +bnz main_l71 +main_l70: +intc_0 // 1 +intc_1 // 0 +pushint 8 // 8 +callsub read_4 +btoi +intc_0 // 1 ++ +itob +store 0 +intc_0 // 1 +intc_1 // 0 +load 0 +callsub write_7 +pop +load 0 +log +intc_0 // 1 +bytec 10 // "publishMessage" +callsub meta_5 +intc_0 // 1 +return +main_l71: +txn GroupIndex +intc_0 // 1 +- +gtxns TypeEnum +intc_0 // pay +== +txn GroupIndex +intc_0 // 1 +- +gtxns Amount +load 1 +>= +&& +txn GroupIndex +intc_0 // 1 +- +gtxns Receiver +global CurrentApplicationAddress +== +&& +txn GroupIndex +intc_0 // 1 +- +gtxns RekeyTo +global ZeroAddress +== +&& +pushint 158 // 158 +&& +assert +b main_l70 +main_l72: +callsub optin_10 +return +main_l73: +intc_1 // 0 +return +main_l74: +txn Sender +global CreatorAddress +== +return +main_l75: +bytec 6 // "MessageFee" +intc_1 // 0 +app_global_put +bytec 9 // "vphash" +bytec_0 // "" +app_global_put +bytec_3 // "currentGuardianSetIndex" +intc_1 // 0 +app_global_put +bytec 8 // "validUpdateApproveHash" +bytec_0 // "" +app_global_put +pushbytes 0x76616c6964557064617465436c65617248617368 // "validUpdateClearHash" +pushbytes 0x73be5fd7cd378289177bf4a7ca5433ab30d91b417381bba8bd704aff2dec424f // 0x73be5fd7cd378289177bf4a7ca5433ab30d91b417381bba8bd704aff2dec424f +app_global_put +intc_0 // 1 +return + +// intkey +intkey_0: +itob +extract 7 1 +retsub + +// zero +zero_1: +store 51 +intc_1 // 0 +store 52 +zero_1_l1: +load 52 +pushint 15 // 15 +< +bz zero_1_l3 +load 51 +load 52 +callsub intkey_0 +intc_2 // 127 +bzero +app_local_put +load 52 +intc_0 // 1 ++ +store 52 +b zero_1_l1 +zero_1_l3: +retsub + +// get_byte +getbyte_2: +store 29 +load 29 +intc_2 // 127 +/ +callsub intkey_0 +app_local_get +load 29 +intc_2 // 127 +% +getbyte +retsub + +// set_byte +setbyte_3: +store 60 +store 59 +store 58 +load 58 +load 59 +intc_2 // 127 +/ +callsub intkey_0 +load 58 +load 59 +intc_2 // 127 +/ +callsub intkey_0 +app_local_get +load 59 +intc_2 // 127 +% +load 60 +setbyte +app_local_put +retsub + +// read +read_4: +store 32 +store 31 +store 30 +bytec_0 // "" +store 34 +load 31 +intc_2 // 127 +/ +store 33 +read_4_l1: +load 33 +load 32 +intc_2 // 127 +/ +<= +bz read_4_l9 +load 33 +load 31 +intc_2 // 127 +/ +== +bnz read_4_l8 +intc_1 // 0 +read_4_l4: +store 35 +load 33 +load 32 +intc_2 // 127 +/ +== +bnz read_4_l7 +intc_2 // 127 +read_4_l6: +store 36 +load 34 +load 30 +load 33 +callsub intkey_0 +app_local_get +load 35 +load 36 +substring3 +concat +store 34 +load 33 +intc_0 // 1 ++ +store 33 +b read_4_l1 +read_4_l7: +load 32 +intc_2 // 127 +% +b read_4_l6 +read_4_l8: +load 31 +intc_2 // 127 +% +b read_4_l4 +read_4_l9: +load 34 +retsub + +// meta +meta_5: +store 37 +bytec 16 // "meta" +load 37 +app_local_put +retsub + +// checkMeta +checkMeta_6: +store 38 +bytec 16 // "meta" +app_local_get +load 38 +== +pushint 145 // 145 +&& +assert +retsub + +// write +write_7: +store 41 +store 40 +store 39 +intc_1 // 0 +store 45 +load 40 +intc_2 // 127 +/ +store 42 +write_7_l1: +load 42 +load 40 +load 41 +len ++ +intc_2 // 127 +/ +<= +bz write_7_l12 +load 42 +load 40 +intc_2 // 127 +/ +== +bnz write_7_l11 +intc_1 // 0 +write_7_l4: +store 43 +load 42 +load 40 +load 41 +len ++ +intc_2 // 127 +/ +== +bnz write_7_l10 +intc_2 // 127 +write_7_l6: +store 44 +load 39 +load 42 +callsub intkey_0 +load 44 +intc_2 // 127 +!= +load 43 +intc_1 // 0 +!= +|| +bnz write_7_l9 +intc_2 // 127 +store 46 +load 41 +load 45 +intc_2 // 127 +extract3 +write_7_l8: +app_local_put +load 45 +load 46 ++ +store 45 +load 42 +intc_0 // 1 ++ +store 42 +b write_7_l1 +write_7_l9: +load 44 +load 43 +- +store 46 +load 39 +load 42 +callsub intkey_0 +app_local_get +intc_1 // 0 +load 43 +substring3 +load 41 +load 45 +load 46 +extract3 +concat +load 39 +load 42 +callsub intkey_0 +app_local_get +load 44 +intc_2 // 127 +substring3 +concat +b write_7_l8 +write_7_l10: +load 40 +load 41 +len ++ +intc_2 // 127 +% +b write_7_l6 +write_7_l11: +load 40 +intc_2 // 127 +% +b write_7_l4 +write_7_l12: +load 45 +retsub + +// encode_uvarint +encodeuvarint_8: +store 50 +store 49 +load 50 +load 49 +intc 17 // 128 +>= +bnz encodeuvarint_8_l2 +load 49 +intc 18 // 255 +& +itob +extract 7 1 +b encodeuvarint_8_l3 +encodeuvarint_8_l2: +load 49 +pushint 7 // 7 +shr +load 49 +intc 18 // 255 +& +intc 17 // 128 +| +itob +extract 7 1 +load 49 +load 50 +uncover 3 +uncover 3 +callsub encodeuvarint_8 +cover 2 +store 50 +store 49 +encodeuvarint_8_l3: +concat +retsub + +// get_sig_address +getsigaddress_9: +store 48 +store 47 +pushbytes 0x50726f6772616d // "Program" +pushbytes 0x0620010181 // 0x0620010181 +concat +load 47 +bytec_0 // "" +callsub encodeuvarint_8 +concat +pushbytes 0x4880 // 0x4880 +concat +load 48 +len +bytec_0 // "" +callsub encodeuvarint_8 +concat +load 48 +concat +pushbytes 0x483110810612443119221244311881 // 0x483110810612443119221244311881 +concat +global CurrentApplicationID +bytec_0 // "" +callsub encodeuvarint_8 +concat +pushbytes 0x1244312080 // 0x1244312080 +concat +global CurrentApplicationAddress +len +bytec_0 // "" +callsub encodeuvarint_8 +concat +global CurrentApplicationAddress +concat +pushbytes 0x124431018100124431093203124431153203124422 // 0x124431018100124431093203124431153203124422 +concat +sha512_256 +retsub + +// optin +optin_10: +gtxn 0 TypeEnum +intc_0 // pay +== +gtxn 0 Amount +pushint 1002000 // 1002000 +== +&& +gtxn 1 TypeEnum +pushint 6 // appl +== +&& +gtxn 1 OnCompletion +intc_0 // OptIn +== +&& +gtxn 1 ApplicationID +global CurrentApplicationID +== +&& +pushint 136 // 136 +&& +assert +intc_1 // 0 +callsub zero_1 +intc_0 // 1 +retsub + +// checkForDuplicate +checkForDuplicate_11: +txna ApplicationArgs 1 +extract 0 1 +btoi +intc_0 // 1 +== +pushint 330 // 330 +&& +assert +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 14 // 14 ++ +store 53 +txna ApplicationArgs 1 +load 53 +pushint 34 // 34 +extract3 +store 54 +txna ApplicationArgs 1 +load 53 +pushint 34 // 34 ++ +pushint 8 // 8 +extract3 +btoi +store 55 +load 55 +pushint 15240 // 15240 +/ +store 57 +txna Accounts 1 +load 57 +load 54 +callsub getsigaddress_9 +== +pushint 340 // 340 +&& +assert +load 55 +pushint 8 // 8 +/ +pushint 1905 // 1905 +% +store 57 +intc_0 // 1 +load 57 +callsub getbyte_2 +store 56 +load 56 +load 55 +pushint 8 // 8 +% +getbit +intc_1 // 0 +== +pushint 347 // 347 +&& +assert +intc_0 // 1 +load 57 +load 56 +load 55 +pushint 8 // 8 +% +intc_0 // 1 +setbit +callsub setbyte_3 +intc_0 // 1 +pushbytes 0x6475706c6963617465 // "duplicate" +callsub meta_5 +retsub \ No newline at end of file diff --git a/algorand/teal/core_clear.teal b/algorand/teal/core_clear.teal new file mode 100644 index 000000000..1105cd643 --- /dev/null +++ b/algorand/teal/core_clear.teal @@ -0,0 +1,3 @@ +#pragma version 6 +pushint 1 // 1 +return \ No newline at end of file diff --git a/algorand/teal/sig.tmpl.teal b/algorand/teal/sig.tmpl.teal new file mode 100644 index 000000000..bcc72ecb9 --- /dev/null +++ b/algorand/teal/sig.tmpl.teal @@ -0,0 +1,65 @@ +#pragma version 6 +intcblock 1 +pushint TMPL_ADDR_IDX // TMPL_ADDR_IDX +pop +pushbytes TMPL_EMITTER_ID // TMPL_EMITTER_ID +pop +callsub init_0 +return + +// init +init_0: +global GroupSize +pushint 3 // 3 +== +assert +gtxn 0 TypeEnum +intc_0 // pay +== +assert +gtxn 0 Amount +pushint TMPL_SEED_AMT // TMPL_SEED_AMT +== +assert +gtxn 0 RekeyTo +global ZeroAddress +== +assert +gtxn 0 CloseRemainderTo +global ZeroAddress +== +assert +gtxn 1 TypeEnum +pushint 6 // appl +== +assert +gtxn 1 OnCompletion +intc_0 // OptIn +== +assert +gtxn 1 ApplicationID +pushint TMPL_APP_ID // TMPL_APP_ID +== +assert +gtxn 1 RekeyTo +global ZeroAddress +== +assert +gtxn 2 TypeEnum +intc_0 // pay +== +assert +gtxn 2 Amount +pushint 0 // 0 +== +assert +gtxn 2 RekeyTo +pushbytes TMPL_APP_ADDRESS // TMPL_APP_ADDRESS +== +assert +gtxn 2 CloseRemainderTo +global ZeroAddress +== +assert +intc_0 // 1 +return \ No newline at end of file diff --git a/algorand/teal/token_approve.teal b/algorand/teal/token_approve.teal new file mode 100644 index 000000000..df2696817 --- /dev/null +++ b/algorand/teal/token_approve.teal @@ -0,0 +1,2380 @@ +#pragma version 6 +intcblock 0 1 2 127 133 100000 128 255 +bytecblock 0x 0x636f72656964 0x436861696e 0x6e6174697665 0x7075626c6973684d657373616765 0x6e6f70 0x766572696679564141 0x0008 0x76616c6964557064617465417070726f766548617368 0x414c474f 0x636f726541646472 +txn ApplicationID +intc_0 // 0 +== +bnz main_l80 +txn OnCompletion +pushint 4 // UpdateApplication +== +bnz main_l79 +txn OnCompletion +pushint 5 // DeleteApplication +== +bnz main_l78 +txn OnCompletion +intc_1 // OptIn +== +bnz main_l77 +txn OnCompletion +intc_0 // NoOp +== +bnz main_l6 +err +main_l6: +txna ApplicationArgs 0 +bytec 5 // "nop" +== +bnz main_l76 +txna ApplicationArgs 0 +pushbytes 0x72656365697665417474657374 // "receiveAttest" +== +bnz main_l69 +txna ApplicationArgs 0 +pushbytes 0x617474657374546f6b656e // "attestToken" +== +bnz main_l57 +txna ApplicationArgs 0 +pushbytes 0x636f6d706c6574655472616e73666572 // "completeTransfer" +== +bnz main_l41 +txna ApplicationArgs 0 +pushbytes 0x73656e645472616e73666572 // "sendTransfer" +== +bnz main_l21 +txna ApplicationArgs 0 +pushbytes 0x6f7074696e // "optin" +== +bnz main_l20 +txna ApplicationArgs 0 +pushbytes 0x676f7665726e616e6365 // "governance" +== +bnz main_l14 +err +main_l14: +callsub checkForDuplicate_21 +callsub governanceSet_7 +store 70 +txna ApplicationArgs 1 +extract 1 4 +btoi +load 70 +== +pushint 232 // 232 +&& +assert +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 14 // 14 ++ +store 65 +txn GroupIndex +intc_1 // 1 +- +store 71 +load 71 +gtxns TypeEnum +pushint 6 // appl +== +load 71 +gtxns ApplicationID +bytec_1 // "coreid" +app_global_get +== +&& +load 71 +gtxnsa ApplicationArgs 0 +bytec 6 // "verifyVAA" +== +&& +load 71 +gtxns Sender +txn Sender +== +&& +load 71 +gtxnsa ApplicationArgs 1 +txna ApplicationArgs 1 +== +&& +load 71 +gtxnsa Accounts 0 +txna Accounts 0 +== +&& +load 71 +gtxnsa Accounts 1 +txna Accounts 1 +== +&& +load 71 +gtxnsa Accounts 2 +txna Accounts 2 +== +&& +txna ApplicationArgs 1 +load 65 +intc_2 // 2 +extract3 +pushbytes 0x0001 // 0x0001 +== +&& +txna ApplicationArgs 1 +load 65 +intc_2 // 2 ++ +pushint 32 // 32 +extract3 +pushint 31 // 31 +bzero +pushbytes 0x04 // 0x04 +concat +== +&& +pushint 239 // 239 +&& +assert +load 71 +gtxns RekeyTo +global ZeroAddress +== +load 71 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 71 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txn RekeyTo +global ZeroAddress +== +txn CloseRemainderTo +global ZeroAddress +== +&& +txn AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txna ApplicationArgs 1 +load 65 +pushint 43 // 43 ++ +pushint 32 // 32 +extract3 +pushint 21 // 21 +bzero +pushbytes 0x546f6b656e427269646765 // 0x546f6b656e427269646765 +concat +== +pushint 263 // 263 +&& +assert +txna ApplicationArgs 1 +load 65 +pushint 75 // 75 ++ +intc_1 // 1 +extract3 +btoi +store 66 +load 65 +pushint 76 // 76 ++ +store 65 +load 66 +intc_1 // 1 +== +bnz main_l19 +load 66 +intc_2 // 2 +== +bnz main_l17 +err +main_l17: +txna ApplicationArgs 1 +load 65 +intc_2 // 2 +extract3 +bytec 7 // 0x0008 +== +pushint 282 // 282 +&& +assert +bytec 8 // "validUpdateApproveHash" +txna ApplicationArgs 1 +load 65 +intc_2 // 2 ++ +pushint 32 // 32 +extract3 +app_global_put +main_l18: +intc_1 // 1 +return +main_l19: +txna ApplicationArgs 1 +load 65 +intc_2 // 2 +extract3 +btoi +store 67 +load 67 +intc_0 // 0 +== +load 67 +pushint 8 // 8 +== +|| +pushint 271 // 271 +&& +assert +txna ApplicationArgs 1 +load 65 +intc_2 // 2 ++ +intc_2 // 2 +extract3 +store 68 +txna ApplicationArgs 1 +load 65 +pushint 4 // 4 ++ +pushint 32 // 32 +extract3 +store 69 +bytec_2 // "Chain" +load 68 +concat +app_global_get +intc_0 // 0 +== +pushint 277 // 277 +&& +assert +bytec_2 // "Chain" +load 68 +concat +load 69 +app_global_put +b main_l18 +main_l20: +txna Accounts 1 +txna ApplicationArgs 1 +btoi +bytec_3 // "native" +callsub getsigaddress_15 +== +pushint 800 // 800 +&& +assert +txn RekeyTo +global ZeroAddress +== +txn CloseRemainderTo +global ZeroAddress +== +&& +txn AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +itxn_begin +txna Accounts 1 +itxn_field Sender +pushint 4 // axfer +itxn_field TypeEnum +txna ApplicationArgs 1 +btoi +itxn_field XferAsset +intc_0 // 0 +itxn_field AssetAmount +txna Accounts 1 +itxn_field AssetReceiver +intc_0 // 0 +itxn_field Fee +itxn_submit +intc_1 // 1 +return +main_l21: +callsub getMessageFee_8 +store 23 +pushint 32 // 32 +bzero +store 62 +txna ApplicationArgs 1 +btoi +store 55 +txna ApplicationArgs 5 +btoi +store 64 +intc_2 // 2 +callsub checkFeePmt_10 +txn GroupIndex +intc_1 // 1 +- +store 22 +load 55 +intc_0 // 0 +== +bnz main_l40 +load 22 +gtxns TypeEnum +pushint 4 // axfer +== +load 22 +gtxns Sender +txn Sender +== +&& +load 22 +gtxns XferAsset +load 55 +== +&& +load 22 +gtxns AssetReceiver +txna Accounts 2 +== +&& +pushint 693 // 693 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +load 22 +gtxns AssetAmount +store 56 +load 64 +load 56 +<= +pushint 706 // 706 +&& +assert +load 56 +load 64 +- +store 56 +load 55 +callsub extractdecimal_20 +btoi +callsub getFactor_14 +store 63 +load 63 +intc_1 // 1 +!= +bnz main_l39 +main_l23: +load 56 +intc_0 // 0 +> +load 64 +intc_0 // 0 +>= +&& +pushint 722 // 722 +&& +assert +load 55 +intc_0 // 0 +!= +bnz main_l38 +bytec_0 // "" +store 59 +main_l25: +load 59 +global CurrentApplicationAddress +== +bnz main_l37 +txna Accounts 2 +load 55 +bytec_3 // "native" +callsub getsigaddress_15 +== +pushint 746 // 746 +&& +assert +bytec 7 // 0x0008 +store 61 +txna ApplicationArgs 1 +store 60 +main_l27: +load 60 +len +pushint 32 // 32 +<= +load 61 +len +intc_2 // 2 +== +&& +txna ApplicationArgs 3 +len +pushint 32 // 32 +<= +&& +pushint 753 // 753 +&& +assert +txn NumAppArgs +pushint 6 // 6 +== +bnz main_l36 +pushbytes 0x03 // 0x03 +main_l29: +load 62 +extract 0 24 +concat +load 56 +itob +concat +load 62 +intc_0 // 0 +pushint 32 // 32 +load 60 +len +- +extract3 +concat +load 60 +concat +load 61 +concat +load 62 +intc_0 // 0 +pushint 32 // 32 +txna ApplicationArgs 3 +len +- +extract3 +concat +txna ApplicationArgs 3 +concat +txna ApplicationArgs 4 +extract 6 2 +concat +load 62 +extract 0 24 +concat +load 64 +itob +concat +txn NumAppArgs +pushint 7 // 7 +== +bnz main_l35 +bytec_0 // "" +main_l31: +concat +store 57 +txn NumAppArgs +pushint 7 // 7 +== +bnz main_l34 +load 57 +len +intc 4 // 133 +== +pushint 779 // 779 +&& +assert +main_l33: +itxn_begin +callsub sendMfee_11 +pushint 6 // appl +itxn_field TypeEnum +bytec_1 // "coreid" +app_global_get +itxn_field ApplicationID +bytec 4 // "publishMessage" +itxn_field ApplicationArgs +load 57 +itxn_field ApplicationArgs +intc_0 // 0 +itob +itxn_field ApplicationArgs +txna Accounts 1 +itxn_field Accounts +bytec 4 // "publishMessage" +itxn_field Note +intc_0 // 0 +itxn_field Fee +itxn_submit +intc_1 // 1 +return +main_l34: +load 57 +len +intc 4 // 133 +txna ApplicationArgs 6 +len ++ +== +pushint 778 // 778 +&& +assert +b main_l33 +main_l35: +txna ApplicationArgs 6 +b main_l31 +main_l36: +pushbytes 0x01 // 0x01 +b main_l29 +main_l37: +intc_2 // 2 +intc_0 // 0 +pushint 8 // 8 +callsub read_4 +store 58 +txna ApplicationArgs 1 +load 58 +== +pushint 735 // 735 +&& +assert +intc_2 // 2 +pushint 60 // 60 +pushint 92 // 92 +callsub read_4 +store 60 +intc_2 // 2 +pushint 92 // 92 +pushint 94 // 94 +callsub read_4 +store 61 +txna Accounts 2 +load 61 +btoi +load 60 +callsub getsigaddress_15 +== +pushint 742 // 742 +&& +assert +b main_l27 +main_l38: +load 55 +callsub extractcreator_18 +callsub authaddr_16 +store 59 +b main_l25 +main_l39: +load 56 +load 63 +/ +store 56 +load 64 +load 63 +/ +store 64 +b main_l23 +main_l40: +load 22 +gtxns TypeEnum +intc_1 // pay +== +load 22 +gtxns Sender +txn Sender +== +&& +load 22 +gtxns Receiver +txna Accounts 2 +== +&& +pushint 678 // 678 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +load 22 +gtxns Amount +store 56 +load 64 +load 56 +< +pushint 688 // 688 +&& +assert +load 56 +load 64 +- +store 56 +b main_l23 +main_l41: +callsub checkForDuplicate_21 +pushint 32 // 32 +bzero +store 53 +txn GroupIndex +intc_1 // 1 +- +store 22 +load 22 +gtxns TypeEnum +pushint 6 // appl +== +load 22 +gtxns ApplicationID +bytec_1 // "coreid" +app_global_get +== +&& +load 22 +gtxnsa ApplicationArgs 0 +bytec 6 // "verifyVAA" +== +&& +load 22 +gtxns Sender +txn Sender +== +&& +load 22 +gtxnsa ApplicationArgs 1 +txna ApplicationArgs 1 +== +&& +load 22 +gtxnsa Accounts 0 +txna Accounts 0 +== +&& +load 22 +gtxnsa Accounts 1 +txna Accounts 1 +== +&& +load 22 +gtxnsa Accounts 2 +txna Accounts 2 +== +&& +pushint 464 // 464 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txn RekeyTo +global ZeroAddress +== +txn CloseRemainderTo +global ZeroAddress +== +&& +txn AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 6 // 6 ++ +pushint 8 // 8 ++ +store 42 +txna ApplicationArgs 1 +load 42 +intc_2 // 2 +extract3 +btoi +store 43 +txna ApplicationArgs 1 +load 42 +intc_2 // 2 ++ +pushint 32 // 32 +extract3 +store 44 +load 43 +pushint 8 // 8 +== +bnz main_l56 +bytec_2 // "Chain" +txna ApplicationArgs 1 +load 42 +intc_2 // 2 +extract3 +concat +app_global_get +load 44 +== +pushint 491 // 491 +&& +assert +main_l43: +load 42 +pushint 43 // 43 ++ +store 42 +txna ApplicationArgs 1 +load 42 +intc_1 // 1 +extract3 +btoi +store 54 +load 54 +intc_1 // 1 +== +load 54 +pushint 3 // 3 +== +|| +pushint 498 // 498 +&& +assert +txna ApplicationArgs 1 +load 42 +intc_1 // 1 ++ +pushint 24 // 24 +extract3 +load 53 +extract 0 24 +== +pushint 500 // 500 +&& +assert +txna ApplicationArgs 1 +load 42 +pushint 25 // 25 ++ +pushint 8 // 8 +extract3 +btoi +store 45 +txna ApplicationArgs 1 +load 42 +pushint 33 // 33 ++ +pushint 32 // 32 +extract3 +store 46 +txna ApplicationArgs 1 +load 42 +pushint 65 // 65 ++ +intc_2 // 2 +extract3 +btoi +store 47 +txna ApplicationArgs 1 +load 42 +pushint 67 // 67 ++ +pushint 32 // 32 +extract3 +store 48 +txna ApplicationArgs 1 +load 42 +pushint 99 // 99 ++ +intc_2 // 2 +extract3 +btoi +store 49 +txna ApplicationArgs 1 +load 42 +pushint 101 // 101 ++ +pushint 24 // 24 +extract3 +load 53 +extract 0 24 +== +pushint 508 // 508 +&& +assert +txna ApplicationArgs 1 +load 42 +pushint 125 // 125 ++ +pushint 8 // 8 +extract3 +btoi +store 50 +load 49 +pushint 8 // 8 +== +pushint 512 // 512 +&& +assert +load 50 +load 45 +<= +pushint 514 // 514 +&& +assert +load 54 +pushint 3 // 3 +== +bnz main_l55 +main_l44: +load 47 +pushint 8 // 8 +== +bnz main_l49 +pushint 3 // 3 +intc_0 // 0 +pushint 8 // 8 +callsub read_4 +btoi +store 51 +load 51 +intc_0 // 0 +!= +txna Accounts 3 +load 47 +load 46 +callsub getsigaddress_15 +== +&& +pushint 577 // 577 +&& +assert +main_l46: +itxn_begin +txna Accounts 3 +itxn_field Sender +pushint 4 // axfer +itxn_field TypeEnum +load 51 +itxn_field XferAsset +load 45 +itxn_field AssetAmount +load 48 +itxn_field AssetReceiver +intc_0 // 0 +itxn_field Fee +load 50 +intc_0 // 0 +> +bnz main_l48 +main_l47: +itxn_submit +intc_1 // 1 +return +main_l48: +itxn_next +txna Accounts 3 +itxn_field Sender +pushint 4 // axfer +itxn_field TypeEnum +load 51 +itxn_field XferAsset +load 50 +itxn_field AssetAmount +txn Sender +itxn_field AssetReceiver +intc_0 // 0 +itxn_field Fee +b main_l47 +main_l49: +load 46 +extract 24 8 +btoi +store 51 +txna Accounts 3 +load 51 +bytec_3 // "native" +callsub getsigaddress_15 +== +pushint 529 // 529 +&& +assert +load 51 +intc_0 // 0 +== +bnz main_l52 +load 51 +callsub extractdecimal_20 +btoi +callsub getFactor_14 +store 52 +load 52 +intc_1 // 1 +!= +bz main_l46 +load 45 +load 52 +* +store 45 +load 50 +load 52 +* +store 50 +b main_l46 +main_l52: +itxn_begin +txna Accounts 3 +itxn_field Sender +intc_1 // pay +itxn_field TypeEnum +load 48 +itxn_field Receiver +load 45 +itxn_field Amount +intc_0 // 0 +itxn_field Fee +load 50 +intc_0 // 0 +> +bnz main_l54 +main_l53: +itxn_submit +intc_1 // 1 +return +main_l54: +itxn_next +txna Accounts 3 +itxn_field Sender +intc_1 // pay +itxn_field TypeEnum +txn Sender +itxn_field Receiver +load 50 +itxn_field Amount +intc_0 // 0 +itxn_field Fee +b main_l53 +main_l55: +txn GroupIndex +intc_1 // 1 ++ +store 22 +load 22 +gtxns TypeEnum +pushint 6 // appl +== +load 22 +gtxnsa ApplicationArgs 0 +txna ApplicationArgs 0 +== +&& +load 22 +gtxnsa ApplicationArgs 1 +txna ApplicationArgs 1 +== +&& +pushint 518 // 518 +&& +assert +callsub getNextAddress_9 +load 48 +== +pushint 523 // 523 +&& +assert +b main_l44 +main_l56: +global CurrentApplicationAddress +load 44 +== +pushint 490 // 490 +&& +assert +b main_l43 +main_l57: +callsub getMessageFee_8 +store 23 +intc_1 // 1 +callsub checkFeePmt_10 +txna ApplicationArgs 1 +btoi +store 39 +load 39 +intc_0 // 0 +!= +bnz main_l68 +intc_0 // 0 +main_l59: +bnz main_l67 +txna Accounts 2 +load 39 +bytec_3 // "native" +callsub getsigaddress_15 +== +pushint 862 // 862 +&& +assert +pushint 32 // 32 +bzero +store 35 +txna ApplicationArgs 1 +btoi +store 39 +load 39 +intc_0 // 0 +== +bnz main_l66 +load 39 +callsub extractdecimal_20 +store 36 +load 36 +btoi +pushint 8 // 8 +> +bnz main_l65 +main_l62: +load 39 +callsub extractunitname_19 +store 37 +load 39 +callsub extractname_17 +store 38 +main_l63: +pushbytes 0x02 // 0x02 +load 35 +extract 0 24 +concat +load 39 +itob +concat +bytec 7 // 0x0008 +concat +load 36 +concat +load 37 +concat +load 35 +intc_0 // 0 +pushint 32 // 32 +load 37 +len +- +extract3 +concat +load 38 +concat +load 35 +intc_0 // 0 +pushint 32 // 32 +load 38 +len +- +extract3 +concat +store 34 +main_l64: +load 34 +len +pushint 100 // 100 +== +pushint 904 // 904 +&& +assert +itxn_begin +callsub sendMfee_11 +pushint 6 // appl +itxn_field TypeEnum +bytec_1 // "coreid" +app_global_get +itxn_field ApplicationID +bytec 4 // "publishMessage" +itxn_field ApplicationArgs +load 34 +itxn_field ApplicationArgs +intc_0 // 0 +itob +itxn_field ApplicationArgs +txna Accounts 1 +itxn_field Accounts +bytec 4 // "publishMessage" +itxn_field Note +intc_0 // 0 +itxn_field Fee +itxn_submit +intc_1 // 1 +return +main_l65: +pushbytes 0x08 // 0x08 +store 36 +b main_l62 +main_l66: +pushbytes 0x06 // 0x06 +store 36 +bytec 9 // "ALGO" +store 37 +bytec 9 // "ALGO" +store 38 +b main_l63 +main_l67: +intc_2 // 2 +intc_0 // 0 +pushint 8 // 8 +callsub read_4 +store 33 +txna ApplicationArgs 1 +load 33 +== +pushint 845 // 845 +&& +assert +intc_2 // 2 +pushint 60 // 60 +pushint 92 // 92 +callsub read_4 +store 40 +intc_2 // 2 +pushint 92 // 92 +pushint 94 // 94 +callsub read_4 +btoi +store 41 +txna Accounts 2 +load 41 +load 40 +callsub getsigaddress_15 +== +pushint 852 // 852 +&& +assert +load 39 +callsub extractdecimal_20 +btoi +pushint 8 // 8 +<= +pushint 855 // 855 +&& +assert +intc_2 // 2 +pushint 8 // 8 +pushint 108 // 108 +callsub read_4 +store 34 +b main_l64 +main_l68: +load 39 +callsub extractcreator_18 +callsub authaddr_16 +global CurrentApplicationAddress +== +b main_l59 +main_l69: +callsub checkForDuplicate_21 +txn GroupIndex +pushint 4 // 4 +- +store 22 +load 22 +gtxns TypeEnum +pushint 6 // appl +== +load 22 +gtxns ApplicationID +bytec_1 // "coreid" +app_global_get +== +&& +load 22 +gtxnsa ApplicationArgs 0 +bytec 6 // "verifyVAA" +== +&& +load 22 +gtxns Sender +txn Sender +== +&& +load 22 +gtxnsa ApplicationArgs 1 +txna ApplicationArgs 1 +== +&& +load 22 +gtxnsa Accounts 0 +txna Accounts 0 +== +&& +load 22 +gtxnsa Accounts 1 +txna Accounts 1 +== +&& +load 22 +gtxnsa Accounts 2 +txna Accounts 2 +== +&& +pushint 310 // 310 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txn GroupIndex +pushint 3 // 3 +- +store 22 +load 22 +gtxns TypeEnum +intc_1 // pay +== +load 22 +gtxns Amount +intc 5 // 100000 +>= +&& +load 22 +gtxns Sender +txn Sender +== +&& +load 22 +gtxns Receiver +txna Accounts 3 +== +&& +pushint 328 // 328 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txn GroupIndex +intc_2 // 2 +- +store 22 +load 22 +gtxns TypeEnum +pushint 6 // appl +== +load 22 +gtxns ApplicationID +global CurrentApplicationID +== +&& +load 22 +gtxnsa ApplicationArgs 0 +bytec 5 // "nop" +== +&& +load 22 +gtxns Sender +txn Sender +== +&& +pushint 338 // 338 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txn GroupIndex +intc_1 // 1 +- +store 22 +load 22 +gtxns TypeEnum +pushint 6 // appl +== +load 22 +gtxns ApplicationID +global CurrentApplicationID +== +&& +load 22 +gtxnsa ApplicationArgs 0 +bytec 5 // "nop" +== +&& +load 22 +gtxns Sender +txn Sender +== +&& +global GroupSize +intc_1 // 1 +- +txn GroupIndex +== +&& +pushint 348 // 348 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 6 // 6 ++ +pushint 8 // 8 ++ +store 24 +txna ApplicationArgs 1 +load 24 +intc_2 // 2 +extract3 +btoi +store 26 +bytec_2 // "Chain" +txna ApplicationArgs 1 +load 24 +intc_2 // 2 +extract3 +concat +app_global_get +txna ApplicationArgs 1 +load 24 +intc_2 // 2 ++ +pushint 32 // 32 +extract3 +== +pushint 362 // 362 +&& +assert +load 24 +pushint 43 // 43 ++ +store 24 +intc_2 // 2 +txna ApplicationArgs 1 +load 24 +intc_1 // 1 +extract3 +btoi +== +pushint 367 // 367 +&& +assert +txna ApplicationArgs 1 +load 24 +intc_1 // 1 ++ +pushint 32 // 32 +extract3 +store 25 +txna ApplicationArgs 1 +load 24 +pushint 33 // 33 ++ +intc_2 // 2 +extract3 +btoi +store 27 +txna ApplicationArgs 1 +load 24 +pushint 35 // 35 ++ +intc_1 // 1 +extract3 +btoi +store 28 +txna ApplicationArgs 1 +load 24 +pushint 36 // 36 ++ +pushint 32 // 32 +extract3 +store 29 +txna ApplicationArgs 1 +load 24 +pushint 68 // 68 ++ +pushint 32 // 32 +extract3 +store 30 +load 29 +callsub trimbytes_13 +store 29 +load 29 +len +pushint 7 // 7 +> +bnz main_l75 +main_l70: +load 30 +callsub trimbytes_13 +store 30 +load 28 +pushint 8 // 8 +> +bnz main_l74 +main_l71: +txna Accounts 3 +load 27 +load 25 +callsub getsigaddress_15 +== +pushint 392 // 392 +&& +assert +pushint 3 // 3 +intc_0 // 0 +pushint 8 // 8 +callsub read_4 +store 31 +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 6 // 6 ++ +store 24 +load 31 +intc_0 // 0 +itob +== +bnz main_l73 +main_l72: +txna ApplicationArgs 1 +store 32 +pushint 3 // 3 +pushint 8 // 8 +load 32 +load 24 +load 32 +len +load 24 +- +extract3 +callsub write_6 +pop +intc_1 // 1 +return +main_l73: +itxn_begin +txna Accounts 3 +itxn_field Sender +pushint 3 // acfg +itxn_field TypeEnum +load 30 +itxn_field ConfigAssetName +load 29 +itxn_field ConfigAssetUnitName +pushint 18446744073709551614 // 18446744073709551614 +itxn_field ConfigAssetTotal +load 28 +itxn_field ConfigAssetDecimals +global CurrentApplicationAddress +itxn_field ConfigAssetManager +global CurrentApplicationAddress +itxn_field ConfigAssetReserve +global ZeroAddress +itxn_field ConfigAssetFreeze +global ZeroAddress +itxn_field ConfigAssetClawback +intc_0 // 0 +itxn_field Fee +itxn_submit +itxn CreatedAssetID +itob +store 31 +pushint 3 // 3 +intc_0 // 0 +load 31 +callsub write_6 +pop +pushint 3 // 3 +pushbytes 0x6173736574 // "asset" +callsub meta_5 +b main_l72 +main_l74: +pushint 8 // 8 +store 28 +b main_l71 +main_l75: +load 29 +extract 0 7 +store 29 +b main_l70 +main_l76: +intc_1 // 1 +return +main_l77: +callsub optin_22 +return +main_l78: +intc_0 // 0 +return +main_l79: +txn Sender +global CreatorAddress +== +return +main_l80: +bytec_1 // "coreid" +txna ApplicationArgs 0 +btoi +app_global_put +bytec 10 // "coreAddr" +txna ApplicationArgs 1 +app_global_put +bytec 8 // "validUpdateApproveHash" +bytec_0 // "" +app_global_put +pushbytes 0x76616c6964557064617465436c65617248617368 // "validUpdateClearHash" +pushbytes 0x73be5fd7cd378289177bf4a7ca5433ab30d91b417381bba8bd704aff2dec424f // 0x73be5fd7cd378289177bf4a7ca5433ab30d91b417381bba8bd704aff2dec424f +app_global_put +intc_1 // 1 +return + +// intkey +intkey_0: +itob +extract 7 1 +retsub + +// zero +zero_1: +store 17 +intc_0 // 0 +store 18 +zero_1_l1: +load 18 +pushint 15 // 15 +< +bz zero_1_l3 +load 17 +load 18 +callsub intkey_0 +intc_3 // 127 +bzero +app_local_put +load 18 +intc_1 // 1 ++ +store 18 +b zero_1_l1 +zero_1_l3: +retsub + +// get_byte +getbyte_2: +store 0 +load 0 +intc_3 // 127 +/ +callsub intkey_0 +app_local_get +load 0 +intc_3 // 127 +% +getbyte +retsub + +// set_byte +setbyte_3: +store 21 +store 20 +store 19 +load 19 +load 20 +intc_3 // 127 +/ +callsub intkey_0 +load 19 +load 20 +intc_3 // 127 +/ +callsub intkey_0 +app_local_get +load 20 +intc_3 // 127 +% +load 21 +setbyte +app_local_put +retsub + +// read +read_4: +store 3 +store 2 +store 1 +bytec_0 // "" +store 5 +load 2 +intc_3 // 127 +/ +store 4 +read_4_l1: +load 4 +load 3 +intc_3 // 127 +/ +<= +bz read_4_l9 +load 4 +load 2 +intc_3 // 127 +/ +== +bnz read_4_l8 +intc_0 // 0 +read_4_l4: +store 6 +load 4 +load 3 +intc_3 // 127 +/ +== +bnz read_4_l7 +intc_3 // 127 +read_4_l6: +store 7 +load 5 +load 1 +load 4 +callsub intkey_0 +app_local_get +load 6 +load 7 +substring3 +concat +store 5 +load 4 +intc_1 // 1 ++ +store 4 +b read_4_l1 +read_4_l7: +load 3 +intc_3 // 127 +% +b read_4_l6 +read_4_l8: +load 2 +intc_3 // 127 +% +b read_4_l4 +read_4_l9: +load 5 +retsub + +// meta +meta_5: +store 8 +pushbytes 0x6d657461 // "meta" +load 8 +app_local_put +retsub + +// write +write_6: +store 11 +store 10 +store 9 +intc_0 // 0 +store 15 +load 10 +intc_3 // 127 +/ +store 12 +write_6_l1: +load 12 +load 10 +load 11 +len ++ +intc_3 // 127 +/ +<= +bz write_6_l12 +load 12 +load 10 +intc_3 // 127 +/ +== +bnz write_6_l11 +intc_0 // 0 +write_6_l4: +store 13 +load 12 +load 10 +load 11 +len ++ +intc_3 // 127 +/ +== +bnz write_6_l10 +intc_3 // 127 +write_6_l6: +store 14 +load 9 +load 12 +callsub intkey_0 +load 14 +intc_3 // 127 +!= +load 13 +intc_0 // 0 +!= +|| +bnz write_6_l9 +intc_3 // 127 +store 16 +load 11 +load 15 +intc_3 // 127 +extract3 +write_6_l8: +app_local_put +load 15 +load 16 ++ +store 15 +load 12 +intc_1 // 1 ++ +store 12 +b write_6_l1 +write_6_l9: +load 14 +load 13 +- +store 16 +load 9 +load 12 +callsub intkey_0 +app_local_get +intc_0 // 0 +load 13 +substring3 +load 11 +load 15 +load 16 +extract3 +concat +load 9 +load 12 +callsub intkey_0 +app_local_get +load 14 +intc_3 // 127 +substring3 +concat +b write_6_l8 +write_6_l10: +load 10 +load 11 +len ++ +intc_3 // 127 +% +b write_6_l6 +write_6_l11: +load 10 +intc_3 // 127 +% +b write_6_l4 +write_6_l12: +load 15 +retsub + +// governanceSet +governanceSet_7: +bytec_1 // "coreid" +app_global_get +pushbytes 0x63757272656e74477561726469616e536574496e646578 // "currentGuardianSetIndex" +app_global_get_ex +store 73 +store 72 +load 73 +pushint 76 // 76 +&& +assert +load 72 +retsub + +// getMessageFee +getMessageFee_8: +bytec_1 // "coreid" +app_global_get +pushbytes 0x4d657373616765466565 // "MessageFee" +app_global_get_ex +store 75 +store 74 +load 75 +pushint 81 // 81 +&& +assert +load 74 +retsub + +// getNextAddress +getNextAddress_9: +txn GroupIndex +intc_1 // 1 ++ +gtxns ApplicationID +app_params_get AppAddress +store 77 +store 76 +load 77 +pushint 86 // 86 +&& +assert +load 76 +retsub + +// checkFeePmt +checkFeePmt_10: +store 78 +load 23 +intc_0 // 0 +> +bz checkFeePmt_10_l2 +txn GroupIndex +load 78 +- +store 22 +load 22 +gtxns TypeEnum +intc_1 // pay +== +load 22 +gtxns Sender +txn Sender +== +&& +load 22 +gtxns Receiver +global CurrentApplicationAddress +== +&& +load 22 +gtxns Amount +load 23 +>= +&& +pushint 100 // 100 +&& +assert +load 22 +gtxns RekeyTo +global ZeroAddress +== +load 22 +gtxns CloseRemainderTo +global ZeroAddress +== +&& +load 22 +gtxns AssetCloseTo +global ZeroAddress +== +&& +pushint 89 // 89 +&& +assert +checkFeePmt_10_l2: +retsub + +// sendMfee +sendMfee_11: +load 23 +intc_0 // 0 +> +bz sendMfee_11_l2 +intc_1 // pay +itxn_field TypeEnum +bytec 10 // "coreAddr" +app_global_get +itxn_field Receiver +load 23 +itxn_field Amount +intc_0 // 0 +itxn_field Fee +itxn_next +sendMfee_11_l2: +retsub + +// encode_uvarint +encodeuvarint_12: +store 87 +store 86 +load 87 +load 86 +intc 6 // 128 +>= +bnz encodeuvarint_12_l2 +load 86 +intc 7 // 255 +& +itob +extract 7 1 +b encodeuvarint_12_l3 +encodeuvarint_12_l2: +load 86 +pushint 7 // 7 +shr +load 86 +intc 7 // 255 +& +intc 6 // 128 +| +itob +extract 7 1 +load 86 +load 87 +uncover 3 +uncover 3 +callsub encodeuvarint_12 +cover 2 +store 87 +store 86 +encodeuvarint_12_l3: +concat +retsub + +// trim_bytes +trimbytes_13: +store 82 +load 82 +len +store 79 +intc_1 // 1 +bzero +store 81 +intc_0 // 0 +store 80 +trimbytes_13_l1: +load 80 +load 79 +< +bz trimbytes_13_l5 +load 82 +load 80 +intc_1 // 1 +extract3 +load 81 +== +bnz trimbytes_13_l4 +trimbytes_13_l3: +load 80 +intc_1 // 1 ++ +store 80 +b trimbytes_13_l1 +trimbytes_13_l4: +load 82 +intc_0 // 0 +load 80 +extract3 +store 82 +load 79 +store 80 +b trimbytes_13_l3 +trimbytes_13_l5: +load 82 +retsub + +// getFactor +getFactor_14: +store 83 +load 83 +pushint 9 // 9 +== +bnz getFactor_14_l20 +load 83 +pushint 10 // 10 +== +bnz getFactor_14_l19 +load 83 +pushint 11 // 11 +== +bnz getFactor_14_l18 +load 83 +pushint 12 // 12 +== +bnz getFactor_14_l17 +load 83 +pushint 13 // 13 +== +bnz getFactor_14_l16 +load 83 +pushint 14 // 14 +== +bnz getFactor_14_l15 +load 83 +pushint 15 // 15 +== +bnz getFactor_14_l14 +load 83 +pushint 16 // 16 +== +bnz getFactor_14_l13 +load 83 +pushint 16 // 16 +> +bnz getFactor_14_l12 +load 83 +pushint 9 // 9 +< +bnz getFactor_14_l11 +err +getFactor_14_l11: +intc_1 // 1 +b getFactor_14_l21 +getFactor_14_l12: +intc_0 // 0 +return +intc_1 // 1 +getFactor_14_l13: +pushint 100000000 // 100000000 +b getFactor_14_l21 +getFactor_14_l14: +pushint 10000000 // 10000000 +b getFactor_14_l21 +getFactor_14_l15: +pushint 1000000 // 1000000 +b getFactor_14_l21 +getFactor_14_l16: +intc 5 // 100000 +b getFactor_14_l21 +getFactor_14_l17: +pushint 10000 // 10000 +b getFactor_14_l21 +getFactor_14_l18: +pushint 1000 // 1000 +b getFactor_14_l21 +getFactor_14_l19: +pushint 100 // 100 +b getFactor_14_l21 +getFactor_14_l20: +pushint 10 // 10 +getFactor_14_l21: +retsub + +// get_sig_address +getsigaddress_15: +store 85 +store 84 +pushbytes 0x50726f6772616d // "Program" +pushbytes 0x0620010181 // 0x0620010181 +concat +load 84 +bytec_0 // "" +callsub encodeuvarint_12 +concat +pushbytes 0x4880 // 0x4880 +concat +load 85 +len +bytec_0 // "" +callsub encodeuvarint_12 +concat +load 85 +concat +pushbytes 0x483110810612443119221244311881 // 0x483110810612443119221244311881 +concat +global CurrentApplicationID +bytec_0 // "" +callsub encodeuvarint_12 +concat +pushbytes 0x1244312080 // 0x1244312080 +concat +global CurrentApplicationAddress +len +bytec_0 // "" +callsub encodeuvarint_12 +concat +global CurrentApplicationAddress +concat +pushbytes 0x124431018100124431093203124431153203124422 // 0x124431018100124431093203124431153203124422 +concat +sha512_256 +retsub + +// auth_addr +authaddr_16: +acct_params_get AcctAuthAddr +store 89 +store 88 +load 89 +bnz authaddr_16_l2 +bytec_0 // "" +b authaddr_16_l3 +authaddr_16_l2: +load 88 +authaddr_16_l3: +retsub + +// extract_name +extractname_17: +asset_params_get AssetName +store 91 +store 90 +load 91 +bnz extractname_17_l2 +bytec_0 // "" +b extractname_17_l3 +extractname_17_l2: +load 90 +extractname_17_l3: +retsub + +// extract_creator +extractcreator_18: +asset_params_get AssetCreator +store 93 +store 92 +load 93 +bnz extractcreator_18_l2 +bytec_0 // "" +b extractcreator_18_l3 +extractcreator_18_l2: +load 92 +extractcreator_18_l3: +retsub + +// extract_unit_name +extractunitname_19: +asset_params_get AssetUnitName +store 95 +store 94 +load 95 +bnz extractunitname_19_l2 +bytec_0 // "" +b extractunitname_19_l3 +extractunitname_19_l2: +load 94 +extractunitname_19_l3: +retsub + +// extract_decimal +extractdecimal_20: +asset_params_get AssetDecimals +store 97 +store 96 +load 97 +bnz extractdecimal_20_l2 +pushbytes 0x00 // 0x00 +b extractdecimal_20_l3 +extractdecimal_20_l2: +load 96 +itob +extract 7 1 +extractdecimal_20_l3: +retsub + +// checkForDuplicate +checkForDuplicate_21: +txna ApplicationArgs 1 +extract 0 1 +btoi +intc_1 // 1 +== +pushint 933 // 933 +&& +assert +txna ApplicationArgs 1 +extract 5 1 +btoi +pushint 66 // 66 +* +pushint 14 // 14 ++ +store 98 +txna ApplicationArgs 1 +load 98 +pushint 34 // 34 +extract3 +store 99 +txna ApplicationArgs 1 +load 98 +pushint 34 // 34 ++ +pushint 8 // 8 +extract3 +btoi +store 100 +load 100 +pushint 15240 // 15240 +/ +store 102 +txna Accounts 1 +load 102 +load 99 +callsub getsigaddress_15 +== +pushint 943 // 943 +&& +assert +load 100 +pushint 8 // 8 +/ +pushint 1905 // 1905 +% +store 102 +intc_1 // 1 +load 102 +callsub getbyte_2 +store 101 +load 101 +load 100 +pushint 8 // 8 +% +getbit +intc_0 // 0 +== +pushint 950 // 950 +&& +assert +intc_1 // 1 +load 102 +load 101 +load 100 +pushint 8 // 8 +% +intc_1 // 1 +setbit +callsub setbyte_3 +retsub + +// optin +optin_22: +gtxn 0 TypeEnum +intc_1 // pay +== +gtxn 0 Amount +pushint 1002000 // 1002000 +== +&& +gtxn 1 TypeEnum +pushint 6 // appl +== +&& +gtxn 1 OnCompletion +intc_1 // OptIn +== +&& +pushint 1008 // 1008 +&& +assert +intc_0 // 0 +callsub zero_1 +intc_1 // 1 +retsub \ No newline at end of file diff --git a/algorand/teal/token_clear.teal b/algorand/teal/token_clear.teal new file mode 100644 index 000000000..1105cd643 --- /dev/null +++ b/algorand/teal/token_clear.teal @@ -0,0 +1,3 @@ +#pragma version 6 +pushint 1 // 1 +return \ No newline at end of file diff --git a/algorand/teal/vaa_verify.teal b/algorand/teal/vaa_verify.teal new file mode 100644 index 000000000..119941c37 --- /dev/null +++ b/algorand/teal/vaa_verify.teal @@ -0,0 +1,88 @@ +#pragma version 6 +txn RekeyTo +global ZeroAddress +== +assert +txn Fee +int 0 +== +assert +txn TypeEnum +int appl +== +assert +txna ApplicationArgs 1 +txna ApplicationArgs 3 +txna ApplicationArgs 2 +callsub sigcheck_0 +assert +int 1 +return + +// sig_check +sigcheck_0: +store 2 +store 1 +store 0 +byte "" +store 240 +byte "" +store 241 +load 0 +len +store 5 +int 0 +store 3 +int 0 +store 4 +sigcheck_0_l1: +load 3 +load 5 +< +bz sigcheck_0_l3 +load 1 +load 0 +load 3 +int 65 ++ +int 1 +extract3 +btoi +load 0 +load 3 +int 1 ++ +int 32 +extract3 +load 0 +load 3 +int 33 ++ +int 32 +extract3 +ecdsa_pk_recover Secp256k1 +store 241 +store 240 +load 2 +load 4 +int 20 +extract3 +load 240 +load 241 +concat +keccak256 +extract 12 20 +== +assert +load 3 +int 66 ++ +store 3 +load 4 +int 20 ++ +store 4 +b sigcheck_0_l1 +sigcheck_0_l3: +int 1 +retsub \ No newline at end of file diff --git a/algorand/test/NOTES b/algorand/test/NOTES new file mode 100644 index 000000000..ac67ce854 --- /dev/null +++ b/algorand/test/NOTES @@ -0,0 +1,65 @@ +index 0 +appId 4 +textToHexString("guardian"); +guardianAddr CLAOUBJPZ5WNLM7ZU237TCOV2WODAGNUX3536PZ3JSWMBN7M46UADLN3GY + +('CLAOUBJPZ5WNLM7ZU237TCOV2WODAGNUX3536PZ3JSWMBN7M46UADLN3GY', + '01befa429d57cd18b7f8a4d91a2da9ab4af05d0fbe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000677561726469616e') + +illness illegal arrive clip fork palm skull south impose verify toss ocean shrug vital swift similar depend margin climb uniform risk pizza canal absorb forward + +# Locally in your project. +npm install -D typescript +npm install -D ts-node + +# Or globally with TypeScript. +npm install -g typescript +npm install -g ts-node + +# Depending on configuration, you may also need these +npm install -D tslib @types/node + +go to .../ethereum/ +npm ci +go to ..../sdk/js +npm ci; npm run build + +Then, in a new window, you can run + tsc -p tsconfig-cjs.json --watch +which will track updates + +ts-node foo2.ts + + +https://github.com/barnjamin/sdk-extras/blob/master/py/block_fetcher.py + +package main + +import ( + "context" + "strings" + + "github.com/algorand/go-algorand/rpcs" + "github.com/algorand/indexer/fetcher" + "github.com/sirupsen/logrus" +) + +var log = logrus.New() + +func main() { + f, err := fetcher.ForNetAndToken("http://localhost:4001", strings.Repeat("a", 64), log) + if err != nil { + log.Fatalf("Failed to create fetcher: %+v", err) + } + + f.SetBlockHandler(handler) + + f.Run(context.Background()) +} + +func handler(ctx context.Context, cert *rpcs.EncodedBlockCert) error { + for _, stxn := range cert.Block.Payset { + log.Printf("%+v", stxn.SignedTxn.Txn.Type) + } + return nil +} diff --git a/algorand/test/attest.py b/algorand/test/attest.py new file mode 100644 index 000000000..604ffc4f2 --- /dev/null +++ b/algorand/test/attest.py @@ -0,0 +1,550 @@ +# python3 -m pip install pycryptodomex uvarint pyteal web3 coincurve + +import sys +sys.path.append("..") + +from admin import PortalCore, Account +from gentest import GenTest +from base64 import b64decode + +from typing import List, Tuple, Dict, Any, Optional, Union +import base64 +import random +import time +import hashlib +import uuid +import json + +from algosdk.v2client.algod import AlgodClient +from algosdk.kmd import KMDClient +from algosdk import account, mnemonic +from algosdk.encoding import decode_address, encode_address +from algosdk.future import transaction +from pyteal import compileTeal, Mode, Expr +from pyteal import * +from algosdk.logic import get_application_address +from vaa_verify import get_vaa_verify + +from algosdk.future.transaction import LogicSig + +from test_contract import get_test_app + +from algosdk.v2client import indexer + +import pprint + +class AlgoTest(PortalCore): + def __init__(self) -> None: + super().__init__() + + def getBalances(self, client: AlgodClient, account: str) -> Dict[int, int]: + balances: Dict[int, int] = dict() + + accountInfo = client.account_info(account) + + # set key 0 to Algo balance + balances[0] = accountInfo["amount"] + + assets: List[Dict[str, Any]] = accountInfo.get("assets", []) + for assetHolding in assets: + assetID = assetHolding["asset-id"] + amount = assetHolding["amount"] + balances[assetID] = amount + + return balances + + def createTestApp( + self, + client: AlgodClient, + sender: Account, + ) -> int: + approval, clear = get_test_app(client) + + globalSchema = transaction.StateSchema(num_uints=4, num_byte_slices=30) + localSchema = transaction.StateSchema(num_uints=0, num_byte_slices=16) + + app_args = [] + + txn = transaction.ApplicationCreateTxn( + sender=sender.getAddress(), + on_complete=transaction.OnComplete.NoOpOC, + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + global_schema=globalSchema, + local_schema=localSchema, + app_args=app_args, + sp=client.suggested_params(), + ) + + signedTxn = txn.sign(sender.getPrivateKey()) + + client.send_transaction(signedTxn) + + response = self.waitForTransaction(client, signedTxn.get_txid()) + assert response.applicationIndex is not None and response.applicationIndex > 0 + + txn = transaction.PaymentTxn(sender = sender.getAddress(), sp = client.suggested_params(), + receiver = get_application_address(response.applicationIndex), amt = 300000) + signedTxn = txn.sign(sender.getPrivateKey()) + client.send_transaction(signedTxn) + + return response.applicationIndex + + def parseSeqFromLog(self, txn): + try: + return int.from_bytes(b64decode(txn.innerTxns[-1]["logs"][0]), "big") + except Exception as err: + pprint.pprint(txn.__dict__) + raise + + def getVAA(self, client, sender, sid, app): + if sid == None: + raise Exception("getVAA called with a sid of None") + + saddr = get_application_address(app) + + # SOOO, we send a nop txn through to push the block forward + # one + + # This is ONLY needed on a local net... the indexer will sit + # on the last block for 30 to 60 seconds... we don't want this + # log in prod since it is wasteful of gas + + if (self.INDEXER_ROUND > 512 and not self.args.testnet): # until they fix it + print("indexer is broken in local net... stop/clean/restart the sandbox") + sys.exit(0) + + txns = [] + + txns.append( + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=client.suggested_params(), + ) + ) + self.sendTxn(client, sender, txns, False) + + if self.myindexer == None: + print("indexer address: " + self.INDEXER_ADDRESS) + self.myindexer = indexer.IndexerClient(indexer_token=self.INDEXER_TOKEN, indexer_address=self.INDEXER_ADDRESS) + + while True: + nexttoken = "" + while True: + response = self.myindexer.search_transactions( min_round=self.INDEXER_ROUND, note_prefix=self.NOTE_PREFIX, next_page=nexttoken) +# pprint.pprint(response) + for x in response["transactions"]: +# pprint.pprint(x) + for y in x["inner-txns"]: + if "application-transaction" not in y: + continue + if y["application-transaction"]["application-id"] != self.coreid: + continue + if len(y["logs"]) == 0: + continue + args = y["application-transaction"]["application-args"] + if len(args) < 2: + continue + if base64.b64decode(args[0]) != b'publishMessage': + continue + seq = int.from_bytes(base64.b64decode(y["logs"][0]), "big") + if seq != sid: + continue + if y["sender"] != saddr: + continue; + emitter = decode_address(y["sender"]) + payload = base64.b64decode(args[1]) +# pprint.pprint([seq, y["sender"], payload.hex()]) +# sys.exit(0) + return self.gt.genVaa(emitter, seq, payload) + + if 'next-token' in response: + nexttoken = response['next-token'] + else: + self.INDEXER_ROUND = response['current-round'] + 1 + break + time.sleep(1) + + def publishMessage(self, client, sender, vaa, appid): + aa = decode_address(get_application_address(appid)).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + txns = [] + sp = client.suggested_params() + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=appid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"test1", vaa, self.coreid], + foreign_apps = [self.coreid], + accounts=[emitter_addr], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + self.INDEXER_ROUND = resp.confirmedRound + + return self.parseSeqFromLog(resp) + + def createTestAsset(self, client, sender): + txns = [] + + a = transaction.PaymentTxn( + sender = sender.getAddress(), + sp = client.suggested_params(), + receiver = get_application_address(self.testid), + amt = 300000 + ) + + txns.append(a) + + sp = client.suggested_params() + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.testid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"setup"], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + transaction.assign_group_id(txns) + + grp = [] + pk = sender.getPrivateKey() + for t in txns: + grp.append(t.sign(pk)) + + client.send_transactions(grp) + resp = self.waitForTransaction(client, grp[-1].get_txid()) + + aid = int.from_bytes(resp.__dict__["logs"][0], "big") + + print("Opting " + sender.getAddress() + " into " + str(aid)) + self.asset_optin(client, sender, aid, sender.getAddress()) + + txns = [] + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.testid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"mint"], + foreign_assets = [aid], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + +# self.INDEXER_ROUND = resp.confirmedRound + + return aid + + def getCreator(self, client, sender, asset_id): + return client.asset_info(asset_id)["params"]["creator"] + + def testAttest(self, client, sender, asset_id): + taddr = get_application_address(self.tokenid) + aa = decode_address(taddr).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + creator = self.getCreator(client, sender, asset_id) + c = client.account_info(creator) + wormhole = c.get("auth-addr") == taddr + + if not wormhole: + creator = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + + txns = [] + sp = client.suggested_params() + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=sp + )) + + mfee = self.getMessageFee() + if (mfee > 0): + txns.append(transaction.PaymentTxn(sender = sender.getAddress(), sp = sp, receiver = get_application_address(self.tokenid), amt = mfee)) + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"attestToken", asset_id], + foreign_apps = [self.coreid], + foreign_assets = [asset_id], + accounts=[emitter_addr, creator, c["address"], get_application_address(self.coreid)], + sp=sp + ) + + if (mfee > 0): + a.fee = a.fee * 3 + else: + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + # Point us at the correct round + self.INDEXER_ROUND = resp.confirmedRound + +# print(encode_address(resp.__dict__["logs"][0])) +# print(encode_address(resp.__dict__["logs"][1])) +# pprint.pprint(resp.__dict__) + return self.parseSeqFromLog(resp) + + def transferAsset(self, client, sender, asset_id, quantity, receiver, chain, fee, payload = None): +# pprint.pprint(["transferAsset", asset_id, quantity, receiver, chain, fee]) + + taddr = get_application_address(self.tokenid) + aa = decode_address(taddr).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + # asset_id 0 is ALGO + + if asset_id == 0: + wormhole = False + else: + creator = self.getCreator(client, sender, asset_id) + c = client.account_info(creator) + wormhole = c.get("auth-addr") == taddr + + txns = [] + + + mfee = self.getMessageFee() + if (mfee > 0): + txns.append(transaction.PaymentTxn(sender = sender.getAddress(), sp = sp, receiver = get_application_address(self.tokenid), amt = mfee)) + + if not wormhole: + creator = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + print("non wormhole account " + creator) + + sp = client.suggested_params() + + if (asset_id != 0) and (not self.asset_optin_check(client, sender, asset_id, creator)): + print("Looks like we need to optin") + + txns.append( + transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=creator, + amt=100000, + sp=sp + ) + ) + + # The tokenid app needs to do the optin since it has signature authority + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"optin", asset_id], + foreign_assets = [asset_id], + accounts=[creator], + sp=sp + ) + + a.fee = a.fee * 2 + txns.append(a) + self.sendTxn(client, sender, txns, False) + txns = [] + + txns.insert(0, + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=client.suggested_params(), + ) + ) + + if asset_id == 0: + print("asset_id == 0") + txns.append(transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=creator, + amt=quantity, + sp=sp, + )) + accounts=[emitter_addr, creator, creator] + else: + print("asset_id != 0") + txns.append( + transaction.AssetTransferTxn( + sender = sender.getAddress(), + sp = sp, + receiver = creator, + amt = quantity, + index = asset_id + )) + accounts=[emitter_addr, creator, c["address"]] + + args = [b"sendTransfer", asset_id, quantity, decode_address(receiver), chain, fee] + if None != payload: + args.append(payload) + + #pprint.pprint(args) + +# print(self.tokenid) + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=args, + foreign_apps = [self.coreid], + foreign_assets = [asset_id], + accounts=accounts, + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + self.INDEXER_ROUND = resp.confirmedRound + +# pprint.pprint([self.coreid, self.tokenid, resp.__dict__, +# int.from_bytes(resp.__dict__["logs"][1], "big"), +# int.from_bytes(resp.__dict__["logs"][2], "big"), +# int.from_bytes(resp.__dict__["logs"][3], "big"), +# int.from_bytes(resp.__dict__["logs"][4], "big"), +# int.from_bytes(resp.__dict__["logs"][5], "big") +# ]) +# print(encode_address(resp.__dict__["logs"][0])) +# print(encode_address(resp.__dict__["logs"][1])) + return self.parseSeqFromLog(resp) + + def asset_optin_check(self, client, sender, asset, receiver): + if receiver not in self.asset_cache: + self.asset_cache[receiver] = {} + + if asset in self.asset_cache[receiver]: + return True + + ai = client.account_info(receiver) + if "assets" in ai: + for x in ai["assets"]: + if x["asset-id"] == asset: + self.asset_cache[receiver][asset] = True + return True + + return False + + def asset_optin(self, client, sender, asset, receiver): + if self.asset_optin_check(client, sender, asset, receiver): + return + + pprint.pprint(["asset_optin", asset, receiver]) + + sp = client.suggested_params() + optin_txn = transaction.AssetTransferTxn( + sender = sender.getAddress(), + sp = sp, + receiver = receiver, + amt = 0, + index = asset + ) + + transaction.assign_group_id([optin_txn]) + signed_optin = optin_txn.sign(sender.getPrivateKey()) + client.send_transactions([signed_optin]) + resp = self.waitForTransaction(client, signed_optin.get_txid()) + assert self.asset_optin_check(client, sender, asset, receiver), "The optin failed" + print("woah! optin succeeded") + + def simple_test(self): +# q = bytes.fromhex(gt.genAssetMeta(gt.guardianPrivKeys, 1, 1, 1, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, 8, b"USDC", b"CircleCoin")) +# pprint.pprint(self.parseVAA(q)) +# sys.exit(0) + + +# vaa = self.parseVAA(bytes.fromhex("01000000010100e1232697de3681d67ca0c46fbbc9ea5d282c473daae8fda2b23145e7b7167f9a35888acf80ed9d091af3069108c25324a22d8665241db884dda53ca53a8212d100625436600000000100020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585000000000000000120010000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000004523c3F29447d1f32AEa95BEBD00383c4640F1b400020000000000000000000000000000000000000000000000000000aabbcc00080000000000000000000000000000000000000000000000000000000000000000")) +# pprint.pprint(vaa) +# sys.exit(0) + + gt = GenTest(True) + self.gt = gt + + self.setup_args() + + if self.args.testnet: + self.testnet() + + client = self.client = self.getAlgodClient() + + self.genTeal() + + self.vaa_verify = self.client.compile(get_vaa_verify()) + self.vaa_verify["lsig"] = LogicSig(base64.b64decode(self.vaa_verify["result"])) + + vaaLogs = [] + + args = self.args + + if self.args.mnemonic: + self.foundation = Account.FromMnemonic(self.args.mnemonic) + + if self.foundation == None: + print("Generating the foundation account...") + self.foundation = self.getTemporaryAccount(self.client) + + if self.foundation == None: + print("We dont have a account? ") + sys.exit(0) + + foundation = self.foundation + + seq = int(time.time()) + + self.coreid = 4 + self.tokenid = 6 + + + player = self.getTemporaryAccount(client) + print("token bridge " + str(self.tokenid) + " address " + get_application_address(self.tokenid)) + + player2 = self.getTemporaryAccount(client) + player3 = self.getTemporaryAccount(client) + + # This creates a asset by using another app... you can also just creat the asset from the client sdk like we do in the typescript test + self.testid = self.createTestApp(client, player2) + + print("Lets create a brand new non-wormhole asset and try to attest and send it out") + self.testasset = self.createTestAsset(client, player2) + + print("test asset id: " + str(self.testasset)) + + print("Lets try to create an attest for a non-wormhole thing with a huge number of decimals") + # paul - attestFromAlgorand + sid = self.testAttest(client, player2, self.testasset) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + v = self.parseVAA(bytes.fromhex(vaa)) + print("We got a " + v["Meta"]) + +if __name__ == "__main__": + core = AlgoTest() + core.simple_test() diff --git a/algorand/test/foo b/algorand/test/foo new file mode 100644 index 000000000..e6ad407ff --- /dev/null +++ b/algorand/test/foo @@ -0,0 +1,48 @@ +{'applicationIndex': None, + 'assetIndex': None, + 'closeRewards': None, + 'closingAmount': None, + 'confirmedRound': 69, + 'globalStateDelta': None, + 'innerTxns': [{'local-state-delta': [{'address': 'RYXQG6MGNASBPG7CHP5B2R4HOPYJGY5S25SZ6YLAMBJ5LRB6DJQZUAQ7QE', + 'delta': [{'key': 'AA==', + 'value': {'action': 1, + 'bytes': 'AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=='}}, + {'key': 'bWV0YQ==', + 'value': {'action': 1, + 'bytes': 'cHVibGlzaE1lc3NhZ2U='}}]}], + 'logs': ['AAAAAAAAAAE='], + 'pool-error': '', + 'txn': {'txn': {'apaa': ['cHVibGlzaE1lc3NhZ2U=', + 'YjnPtmI5z7wAAexzcpldXMhzI5f7CtNcASHg6qkNJvgopTTKtUORs6T1AAAAAGI5z7wgAgAAAAAAAAAAAAAAAEUjw/KUR9HzKuqVvr0AODxGQPG0AAEIVVNEMkMAAAAAAAAAAA==', + 'AAAAAAAAAAA='], + 'apat': ['RYXQG6MGNASBPG7CHP5B2R4HOPYJGY5S25SZ6YLAMBJ5LRB6DJQZUAQ7QE'], + 'apid': 150, + 'fv': 68, + 'lv': 1068, + 'note': 'cHVibGlzaE1lc3NhZ2U=', + 'snd': 'AZV2EHAFODMFHNTJ3NHDJKYF4ZZRSUUKI5O472GDD3JYBXZFXZIANBFWVE', + 'type': 'appl'}}}], + 'localStateDelta': None, + 'logs': [], + 'poolError': '', + 'receiverRewards': None, + 'senderRewards': None, + 'txn': {'sig': 'WUQv35J6KTg/kFKvU6ateUR0Skkq85+9xDK57oZ/IQHUQkU2NoYraRNrLTwb5Sf/y9PRZGCO0xzEMzLr3TK9DA==', + 'txn': {'apaa': ['YXR0ZXN0VG9rZW4=', 'AAAAAAAAAPA='], + 'apas': [240], + 'apat': ['RYXQG6MGNASBPG7CHP5B2R4HOPYJGY5S25SZ6YLAMBJ5LRB6DJQZUAQ7QE', + 'Y55KVPNTESVJFIZXCHI7BPQLQK65CNB3J5V4RQW4W4QTPXC7KH3BOIICKI', + 'Y55KVPNTESVJFIZXCHI7BPQLQK65CNB3J5V4RQW4W4QTPXC7KH3BOIICKI', + 'YC6MOPFZT6GSQOYKYMQCUVTQ7KCIF4QAUA32Q6EBMSQQ4DAGRYJ2P3NFT4'], + 'apfa': [150], + 'apid': 171, + 'fee': 2000, + 'fv': 68, + 'gen': 'sandnet-v1', + 'gh': 'DyppoDq/KVGRmtli693nOkDgN6/RadREW+ZiHPsEIsE=', + 'grp': 'jsuD9/MGrNF458IXz671THTBRHetESK9Z44Yl4nxvRg=', + 'lv': 1068, + 'snd': 'VDTSI73333EKLV4ZZLOWSF3LFMLJ7E42Q7CAURHIRI4FT7WUPGVR7WH5GI', + 'type': 'appl'}}} +1 diff --git a/algorand/test/foo.js b/algorand/test/foo.js new file mode 100644 index 000000000..02186b3ca --- /dev/null +++ b/algorand/test/foo.js @@ -0,0 +1,60 @@ +var varint = require('varint') +// +// +t = { + 'contract': '0620010181004880220001000000000000000000000000000000000000000000000000000000000000000448880001433204810312443300102212443300088190943d124433002032031244330009320312443301108106124433011922124433011881df0412443301203203124433021022124433020881001244330220802050b9d5cd33b835f53649f25be3ba6e6b8271b6d16c0af8aa97cc11761e417feb1244330209320312442243', + 'TMPL_ADDR_IDX': 0, + 'TMPL_APP_ADDRESS': '50b9d5cd33b835f53649f25be3ba6e6b8271b6d16c0af8aa97cc11761e417feb', + 'TMPL_APP_ID': 607, + 'TMPL_EMITTER_ID': '00010000000000000000000000000000000000000000000000000000000000000004', + 'TMPL_SEED_AMT': 1002000 +} + + +t2 = { + 'contract': '062001018101488008677561726469616e48880001433204810312443300102212443300088190943d124433002032031244330009320312443301108106124433011922124433011881df0412443301203203124433021022124433020881001244330220802050b9d5cd33b835f53\ +649f25be3ba6e6b8271b6d16c0af8aa97cc11761e417feb1244330209320312442243', + 'TMPL_ADDR_IDX': 1, + 'TMPL_APP_ADDRESS': '50b9d5cd33b835f53649f25be3ba6e6b8271b6d16c0af8aa97cc11761e417feb', + 'TMPL_APP_ID': 607, + 'TMPL_EMITTER_ID': '677561726469616e', + 'TMPL_SEED_AMT': 1002000 +} + +function properHex(v) { + if (v < 10) + return '0' + v.toString(16) + else + return v.toString(16) +} + +function populate(v) { + foo = [ + '0620010181', + varint.encode(v["TMPL_ADDR_IDX"]).map (n => properHex(n)).join(''), + '4880', + varint.encode(v["TMPL_EMITTER_ID"].length / 2).map (n => properHex(n)).join(''), + v["TMPL_EMITTER_ID"], + '488800014332048103124433001022124433000881', + varint.encode(v["TMPL_SEED_AMT"]).map (n => properHex(n)).join(''), + '124433002032031244330009320312443301108106124433011922124433011881', + varint.encode(v["TMPL_APP_ID"]).map (n => properHex(n)).join(''), + '1244330120320312443302102212443302088100124433022080', + varint.encode(v["TMPL_APP_ADDRESS"].length/2).map (n => properHex(n)).join(''), + v["TMPL_APP_ADDRESS"], + '1244330209320312442243' + ].join('') + return foo +} + +if (t["contract"] == populate(t)) { + console.log("omg it works!") +} else { + console.log("You are weak") +} + +if (t2["contract"] == populate(t2)) { + console.log("omg it works!") +} else { + console.log("You are weak") +} diff --git a/algorand/test/foo2.ts b/algorand/test/foo2.ts new file mode 100644 index 000000000..b310fdbf4 --- /dev/null +++ b/algorand/test/foo2.ts @@ -0,0 +1,63 @@ +const algosdk = require('algosdk'); +const TestLib = require('./testlib.ts') +const testLib = new TestLib.TestLib() +const fs = require('fs'); +const path = require('path'); + +import { + submitVAA, + submitVAAHdr, + simpleSignVAA, + parseVAA, +// Account, +} from "../../sdk/js/src/token_bridge/Algorand"; + +//const AlgorandLib = require('../../sdk/js/src/token_bridge/Algorand.ts') +//const algorandLib = new AlgorandLib.AlgorandLib() + +const guardianKeys = [ + "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe" +] +const guardianPrivKeys = [ + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0" +] + +const PYTH_EMITTER = '0x3afda841c1f43dd7d546c8a581ba1f92a139f4133f9f6ab095558f6a359df5d4' +const PYTH_PAYLOAD = '0x50325748000101230abfe0ec3b460bd55fc4fb36356716329915145497202b8eb8bf1af6a0a3b9fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd010000002f17254388fffffff70000002eed73d9000000000070d3b43f0000000037faa03d000000000e9e555100000000894af11c0000000037faa03d000000000dda6eb801000000000061a5ff9a' + +async function firstTransaction() { + try { + // This is a funded account... + let myAccount = algosdk.mnemonicToSecretKey("intact frozen tooth wealth syrup elevator list book property census imitate attend draft silly fortune afford injury poem section wait main bench feel absent giraffe") + + console.log(myAccount) + + // Connect your client + const algodToken = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'; + const algodServer = 'http://localhost'; + const algodPort = 4001; + let algodClient = new algosdk.Algodv2(algodToken, algodServer, algodPort); + + //Check your balance + let accountInfo = await algodClient.accountInformation(myAccount.addr).do(); + console.log("Account balance: %d microAlgos", accountInfo.amount); + +// let vaa = testLib.genGuardianSetUpgrade(guardianPrivKeys, 0, 1, 1, 1, guardianKeys) +// console.log(vaa) +// console.log(parseVAA(new Uint8Array(Buffer.from(vaa, "hex")))) +// process.exit(0) + + let vaa = testLib.createSignedVAA(0, guardianPrivKeys, 1, 1, 1, PYTH_EMITTER, 0, 0, PYTH_PAYLOAD) + console.log(vaa) + let evaa = new Uint8Array(Buffer.from(vaa, "hex")) + + let sstate = await submitVAAHdr(evaa, algodClient, myAccount, 4); + console.log(await simpleSignVAA(algodClient, myAccount, sstate.txns)); + } + catch (err) { + console.log("err", err); + } + process.exit(); +}; + +firstTransaction(); diff --git a/algorand/test/simple.py b/algorand/test/simple.py new file mode 100644 index 000000000..705645242 --- /dev/null +++ b/algorand/test/simple.py @@ -0,0 +1,578 @@ +# python3 -m pip install pycryptodomex uvarint pyteal web3 coincurve + +import sys +sys.path.append("..") + +from admin import PortalCore, Account +from gentest import GenTest +from base64 import b64decode + +from typing import List, Tuple, Dict, Any, Optional, Union +import base64 +import random +import time +import hashlib +import uuid +import json + +from algosdk.v2client.algod import AlgodClient +from algosdk.kmd import KMDClient +from algosdk import account, mnemonic +from algosdk.encoding import decode_address, encode_address +from algosdk.future import transaction +from pyteal import compileTeal, Mode, Expr +from pyteal import * +from algosdk.logic import get_application_address +from vaa_verify import get_vaa_verify + +from algosdk.future.transaction import LogicSig + +from test_contract import get_test_app + +from algosdk.v2client import indexer + +import pprint + +class AlgoTest(PortalCore): + def __init__(self) -> None: + super().__init__() + + def getBalances(self, client: AlgodClient, account: str) -> Dict[int, int]: + balances: Dict[int, int] = dict() + + accountInfo = client.account_info(account) + + # set key 0 to Algo balance + balances[0] = accountInfo["amount"] + + assets: List[Dict[str, Any]] = accountInfo.get("assets", []) + for assetHolding in assets: + assetID = assetHolding["asset-id"] + amount = assetHolding["amount"] + balances[assetID] = amount + + return balances + + def createTestApp( + self, + client: AlgodClient, + sender: Account, + ) -> int: + approval, clear = get_test_app(client) + + globalSchema = transaction.StateSchema(num_uints=4, num_byte_slices=30) + localSchema = transaction.StateSchema(num_uints=0, num_byte_slices=16) + + app_args = [] + + txn = transaction.ApplicationCreateTxn( + sender=sender.getAddress(), + on_complete=transaction.OnComplete.NoOpOC, + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + global_schema=globalSchema, + local_schema=localSchema, + app_args=app_args, + sp=client.suggested_params(), + ) + + signedTxn = txn.sign(sender.getPrivateKey()) + + client.send_transaction(signedTxn) + + response = self.waitForTransaction(client, signedTxn.get_txid()) + assert response.applicationIndex is not None and response.applicationIndex > 0 + + txn = transaction.PaymentTxn(sender = sender.getAddress(), sp = client.suggested_params(), + receiver = get_application_address(response.applicationIndex), amt = 300000) + signedTxn = txn.sign(sender.getPrivateKey()) + client.send_transaction(signedTxn) + + return response.applicationIndex + + def parseSeqFromLog(self, txn): + return int.from_bytes(b64decode(txn.innerTxns[0]["logs"][0]), "big") + + def getVAA(self, client, sender, sid, app): + if sid == None: + raise Exception("getVAA called with a sid of None") + + saddr = get_application_address(app) + + # SOOO, we send a nop txn through to push the block forward + # one + + # This is ONLY needed on a local net... the indexer will sit + # on the last block for 30 to 60 seconds... we don't want this + # log in prod since it is wasteful of gas + + if (self.INDEXER_ROUND > 512): # until they fix it + print("indexer is broken in local net... stop/clean/restart the sandbox") + sys.exit(0) + + txns = [] + + txns.append( + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=client.suggested_params(), + ) + ) + self.sendTxn(client, sender, txns, False) + + while True: + nexttoken = "" + while True: + response = self.myindexer.search_transactions( min_round=self.INDEXER_ROUND, note_prefix=self.NOTE_PREFIX, next_page=nexttoken) +# pprint.pprint(response) + for x in response["transactions"]: +# pprint.pprint(x) + for y in x["inner-txns"]: + if y["application-transaction"]["application-id"] != self.coreid: + continue + if len(y["logs"]) == 0: + continue + args = y["application-transaction"]["application-args"] + if len(args) < 2: + continue + if base64.b64decode(args[0]) != b'publishMessage': + continue + seq = int.from_bytes(base64.b64decode(y["logs"][0]), "big") + if seq != sid: +# print(str(seq) + " != " + str(sid)) + continue + if y["sender"] != saddr: + continue; + emitter = decode_address(y["sender"]) + payload = base64.b64decode(args[1]) +# pprint.pprint([seq, y["sender"], payload.hex()]) +# sys.exit(0) + return self.gt.genVaa(emitter, seq, payload) + + if 'next-token' in response: + nexttoken = response['next-token'] + else: + self.INDEXER_ROUND = response['current-round'] + 1 + break + time.sleep(1) + + def publishMessage(self, client, sender, vaa, appid): + aa = decode_address(get_application_address(appid)).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + txns = [] + sp = client.suggested_params() + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=appid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"test1", vaa, self.coreid], + foreign_apps = [self.coreid], + accounts=[emitter_addr], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + self.INDEXER_ROUND = resp.confirmedRound + + return self.parseSeqFromLog(resp) + + def createTestAsset(self, client, sender): + txns = [] + + a = transaction.PaymentTxn( + sender = sender.getAddress(), + sp = client.suggested_params(), + receiver = get_application_address(self.testid), + amt = 300000 + ) + + txns.append(a) + + sp = client.suggested_params() + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.testid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"setup"], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + transaction.assign_group_id(txns) + + grp = [] + pk = sender.getPrivateKey() + for t in txns: + grp.append(t.sign(pk)) + + client.send_transactions(grp) + resp = self.waitForTransaction(client, grp[-1].get_txid()) + + aid = int.from_bytes(resp.__dict__["logs"][0], "big") + + print("Opting " + sender.getAddress() + " into " + str(aid)) + self.asset_optin(client, sender, aid, sender.getAddress()) + + txns = [] + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.testid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"mint"], + foreign_assets = [aid], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + +# self.INDEXER_ROUND = resp.confirmedRound + + return aid + + def getCreator(self, client, sender, asset_id): + return client.asset_info(asset_id)["params"]["creator"] + + def testAttest(self, client, sender, asset_id): + taddr = get_application_address(self.tokenid) + aa = decode_address(taddr).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + creator = self.getCreator(client, sender, asset_id) + c = client.account_info(creator) + wormhole = c.get("auth-addr") == taddr + + if not wormhole: + creator = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + + txns = [] + sp = client.suggested_params() + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"attestToken", asset_id], + foreign_apps = [self.coreid], + foreign_assets = [asset_id], + accounts=[emitter_addr, creator, c["address"]], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + # Point us at the correct round + self.INDEXER_ROUND = resp.confirmedRound + +# print(encode_address(resp.__dict__["logs"][0])) +# print(encode_address(resp.__dict__["logs"][1])) + return self.parseSeqFromLog(resp) + + def transferAsset(self, client, sender, asset_id, quantity, receiver, chain, fee, payload = None): + taddr = get_application_address(self.tokenid) + aa = decode_address(taddr).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + # asset_id 0 is ALGO + + if asset_id == 0: + wormhole = False + else: + creator = self.getCreator(client, sender, asset_id) + c = client.account_info(creator) + wormhole = c.get("auth-addr") == taddr + + txns = [] + + if not wormhole: + creator = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + print("non wormhole account " + creator) + + sp = client.suggested_params() + + if (asset_id != 0) and (not self.asset_optin_check(client, sender, asset_id, creator)): + print("Looks like we need to optin") + + txns.append( + transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=creator, + amt=100000, + sp=sp + ) + ) + + # The tokenid app needs to do the optin since it has signature authority + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"optin", asset_id], + foreign_assets = [asset_id], + accounts=[creator], + sp=sp + ) + + a.fee = a.fee * 2 + txns.append(a) + self.sendTxn(client, sender, txns, False) + txns = [] + + if asset_id == 0: + print("asset_id == 0") + txns.append(transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=creator, + amt=quantity, + sp=sp, + )) + accounts=[emitter_addr, creator, creator] + else: + print("asset_id != 0") + txns.append( + transaction.AssetTransferTxn( + sender = sender.getAddress(), + sp = sp, + receiver = creator, + amt = quantity, + index = asset_id + )) + accounts=[emitter_addr, creator, c["address"]] + + args = [b"sendTransfer", asset_id, quantity, decode_address(receiver), chain, fee] + if None != payload: + args.append(payload) + +# pprint.pprint(args) + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=args, + foreign_apps = [self.coreid], + foreign_assets = [asset_id], + accounts=accounts, + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + self.INDEXER_ROUND = resp.confirmedRound + +# pprint.pprint(resp.__dict__) +# print(encode_address(resp.__dict__["logs"][0])) +# print(encode_address(resp.__dict__["logs"][1])) + return self.parseSeqFromLog(resp) + + def asset_optin_check(self, client, sender, asset, receiver): + if receiver not in self.asset_cache: + self.asset_cache[receiver] = {} + + if asset in self.asset_cache[receiver]: + return True + + ai = client.account_info(receiver) + if "assets" in ai: + for x in ai["assets"]: + if x["asset-id"] == asset: + self.asset_cache[receiver][asset] = True + return True + + return False + + def asset_optin(self, client, sender, asset, receiver): + if self.asset_optin_check(client, sender, asset, receiver): + return + + pprint.pprint(["asset_optin", asset, receiver]) + + sp = client.suggested_params() + optin_txn = transaction.AssetTransferTxn( + sender = sender.getAddress(), + sp = sp, + receiver = receiver, + amt = 0, + index = asset + ) + + transaction.assign_group_id([optin_txn]) + signed_optin = optin_txn.sign(sender.getPrivateKey()) + client.send_transactions([signed_optin]) + resp = self.waitForTransaction(client, signed_optin.get_txid()) + assert self.asset_optin_check(client, sender, asset, receiver), "The optin failed" + print("woah! optin succeeded") + + def simple_test(self): +# q = bytes.fromhex(gt.genAssetMeta(gt.guardianPrivKeys, 1, 1, 1, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, 8, b"USDC", b"CircleCoin")) +# pprint.pprint(self.parseVAA(q)) +# sys.exit(0) + + +# vaa = self.parseVAA(bytes.fromhex("01000000011300c412b9e5b304bde8f8633a41568991ca56b7c11a925847f0059e95010ec5241b761719f12d3f4a79d1515e08152b2e8584cd1e8217dd7743c2bf863b78b2bf040001aebade2f601a4e9083585b1bb5f98d421f116e0393f525b95d51afbe69051587531771dc127a5e9d7b74662bb7ac378d44181522dc748b1b0cbfe1b1de6ed39d01024b4e9fc86ac64aaeef84ea14e4265c3c186042a3ae9ab2933bf06c0cbf326b3c2b89e7d9854fc5204a447bd202592a72d1d6db3d007bef9fea0e35953afbd9f1010342e4446ac94545a0447851eda5d5e3b8c97c6f4ef338977562cd4ecbee2b8fea42d536d7655c28a7f7fb2ff5fc8e5775e892d853c9b2e4969f9ce054ede801700104af0d783996ccfd31d6fc6f86b634288cd2f9cc29695cfcbf12d915c1b9c383dc792c7abbe8126cd917fb8658a8de843d64171122db182453584c0c330e8889730105f34d45ec63ec0a0c4535303fd9c83a0fad6b0a112b27306a288c1b46f2a78399754536ecb07f1ab6c32d92ed50b11fef3668b23d5c1ca010ec4c924441367eac0006566671ff859eec8429874ba9e07dd107b22859cf5029928bebec6eb73cdca6752f91bb252bca76cb15ede1121a84a9a54dad126f50f282a47f7d30880ef86a3900076d0d1241e1fc9d039810a8aebd7cab863017c9420eb67f4578577c5ec4d37162723dcd6213ff6895f280a88ba70de1a5b9257fe2937cbdea007e84886abc46dd0108b24dcddaae10f5e12b7085a0c3885a050640af17ba265a448102401854183e9f3ae9a14cad1af64eb57c6f145c6f709d7ed6bb8712a6b315dc2780c9eb42812e0109df696bf506dfcd8fce57968a84d5f773706b117fad31f86bbb089ede77d71a6e54b7729f79a82e7d6e4a6797380796fbcb9ba9428e8fcdf0400515f8205b31c5010a90a03c76fdec510712b2a6ee52cc0b6df5c921437896756f34b3782aa486eb5b5d02df783664257539233502ec25bbda7dd754afc139823da8a43c0d3c91c279000b33549edd8353c4d577cb273b88b545ae547ad01e85161a4fbbbb371cff453d6311c787254e2852c3b874ea60c67d40efc3ee3f24b51bc3fe95cc0a873e8a3fb6000ce2e206214ae2b4b048857f061ed3cf8cef060c67a85ad863f266145238c5d2a85e38b4eb9b3be4d33f502df4c45762504eb43a6bf78f01363d1399b67c354df8000d2d362d64a2e3d1583e1299238829cc11d81e9b9820121c0a2eb91d542aa54c993861e8225bc3e8d028dc128d284118703a4ec69144d69402efd72a29bb9f6b8f000e6bf56fa3ae6303f495f1379b450eb52580d7d9098dd909762e6186d19e06480d2bba8f06602dbd6d3d5deac7080fc2e61bd1be97e442b63435c91fa72b33534c000fad870b47c86f6997286bd4def4bacc5a8abbfef3f730f62183c638131004ea2f706ab73ebfe8f4879bf54f580444acec212e96e41abaf4acfc3383f05478e528001089599974feaab33862cd881af13f1645079bd2fa2ff07ca744674c8556aaf97c5c9c90df332d5b4ad1428776b68612f0b1ecb98c2ebc83f44f42426f180062cd00116aa93eecb4d528afaa07b72484acd5b79ad20e9ad8e55ce37cb9138b4c12a8eb3d10fa7d932b06ac441905e0226d3420101971a72c5488e4bfef222de8c3acd1011203a3e3d8ec938ffbc3a27d8caf50fc925bd25bd286d5ad6077dffd7e205ce0806e166b661d502f8c49acf88d42fde20e6015830d5517a0bfd40f79963ded4d2d006227697a000f68690008a0ae83030f1423aa97121527f65bbbb97925b43b95231bb0478fd650a057cc4b00000000000000072003000000000000000000000000000000000000000000000000000000000007a12000000000000000000000000000000000000000000000000000000000000000000008cf9ee7255420a50c55ef35d4bdcdd8048dee5c3c1333ecd97aff98869ea280780008000000000000000000000000000000000000000000000000000000000007a1206869206d6f6d")) +# pprint.pprint(vaa) +# sys.exit(0) + + gt = GenTest(False) + self.gt = gt + + client = self.getAlgodClient() + + print("Generating the foundation account...") + foundation = self.getTemporaryAccount(client) + player = self.getTemporaryAccount(client) + player2 = self.getTemporaryAccount(client) + player3 = self.getTemporaryAccount(client) + + self.coreid = 4 + print("coreid = " + str(self.coreid)) + + self.tokenid = 6 + print("token bridge " + str(self.tokenid) + " address " + get_application_address(self.tokenid)) + + self.testid = self.createTestApp(client, player2) + print("testid " + str(self.testid) + " address " + get_application_address(self.testid)) + + print("Lets create a brand new non-wormhole asset and try to attest and send it out") + self.testasset = self.createTestAsset(client, player2) + + print("test asset id: " + str(self.testasset)) + + print("Lets try to create an attest for a non-wormhole thing with a huge number of decimals") + # paul - attestFromAlgorand + sid = self.testAttest(client, player2, self.testasset) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + v = self.parseVAA(bytes.fromhex(vaa)) + print("We got a " + v["Meta"]) + +# pprint.pprint(self.getBalances(client, player.getAddress())) +# pprint.pprint(self.getBalances(client, player2.getAddress())) +# pprint.pprint(self.getBalances(client, player3.getAddress())) +# +# print("Lets transfer that asset to one of our other accounts... first lets create the vaa") +# # paul - transferFromAlgorand +# sid = self.transferAsset(client, player2, self.testasset, 100, player3.getAddress(), 8, 0) +# print("... track down the generated VAA") +# vaa = self.getVAA(client, player, sid, self.tokenid) +# print(".. and lets pass that to player3") +# self.submitVAA(bytes.fromhex(vaa), client, player3) +# +# pprint.pprint(self.getBalances(client, player.getAddress())) +# pprint.pprint(self.getBalances(client, player2.getAddress())) +# pprint.pprint(self.getBalances(client, player3.getAddress())) +# +# # Lets split it into two parts... the payload and the fee +# print("Lets split it into two parts... the payload and the fee") +# sid = self.transferAsset(client, player2, self.testasset, 1000, player3.getAddress(), 8, 500) +# print("... track down the generated VAA") +# vaa = self.getVAA(client, player, sid, self.tokenid) +# print(".. and lets pass that to player3 with fees being passed to player acting as a relayer") +# self.submitVAA(bytes.fromhex(vaa), client, player) +# +# pprint.pprint(self.getBalances(client, player.getAddress())) +# pprint.pprint(self.getBalances(client, player2.getAddress())) +# pprint.pprint(self.getBalances(client, player3.getAddress())) +# +# # Now it gets tricky, lets create a virgin account... +# pk, addr = account.generate_account() +# emptyAccount = Account(pk) +# +# print("How much is in the empty account? (" + addr + ")") +# pprint.pprint(self.getBalances(client, emptyAccount.getAddress())) +# +# # paul - transferFromAlgorand +# print("Lets transfer algo this time.... first lets create the vaa") +# sid = self.transferAsset(client, player2, 0, 1000000, emptyAccount.getAddress(), 8, 0) +# print("... track down the generated VAA") +# vaa = self.getVAA(client, player, sid, self.tokenid) +## pprint.pprint(vaa) +# print(".. and lets pass that to the empty account.. but use somebody else to relay since we cannot pay for it") +# +# # paul - redeemOnAlgorand +# self.submitVAA(bytes.fromhex(vaa), client, player) +# +# print("=================================================") +# +# print("How much is in the source account now?") +# pprint.pprint(self.getBalances(client, player2.getAddress())) +# +# print("How much is in the empty account now?") +# pprint.pprint(self.getBalances(client, emptyAccount.getAddress())) +# +# print("How much is in the player3 account now?") +# pprint.pprint(self.getBalances(client, player3.getAddress())) +# +# print("Lets transfer more algo.. splut 50/50 with the relayer.. going to player3") +# sid = self.transferAsset(client, player2, 0, 1000000, player3.getAddress(), 8, 500000) +# print("... track down the generated VAA") +# vaa = self.getVAA(client, player, sid, self.tokenid) +# print(".. and lets pass that to player3.. but use the previously empty account to relay it") +# self.submitVAA(bytes.fromhex(vaa), client, emptyAccount) +# +# print("How much is in the source account now?") +# pprint.pprint(self.getBalances(client, player2.getAddress())) +# +# print("How much is in the empty account now?") +# pprint.pprint(self.getBalances(client, emptyAccount.getAddress())) +# +# print("How much is in the player3 account now?") +# pprint.pprint(self.getBalances(client, player3.getAddress())) +# +# print("How about a payload3") +# sid = self.transferAsset(client, player2, 0, 100, player3.getAddress(), 8, 0, b'hi mom') +# print("... track down the generated VAA") +# vaa = self.getVAA(client, player, sid, self.tokenid) +# +# print(".. and lets pass that to the wrong account") +# try: +# self.submitVAA(bytes.fromhex(vaa), client, emptyAccount) +# except: +# print("Exception thrown... nice") +# +# print(".. and lets pass that to the right account") +# self.submitVAA(bytes.fromhex(vaa), client, player3) + +# print("player account: " + player.getAddress()) +# pprint.pprint(client.account_info(player.getAddress())) + +# print("player2 account: " + player2.getAddress()) +# pprint.pprint(client.account_info(player2.getAddress())) + +# print("foundation account: " + foundation.getAddress()) +# pprint.pprint(client.account_info(foundation.getAddress())) +# +# print("core app: " + get_application_address(self.coreid)) +# pprint.pprint(client.account_info(get_application_address(self.coreid))), +# +# print("token app: " + get_application_address(self.tokenid)) +# pprint.pprint(client.account_info(get_application_address(self.tokenid))), +# +# print("asset app: " + chain_addr) +# pprint.pprint(client.account_info(chain_addr)) + +core = AlgoTest() +core.simple_test() diff --git a/algorand/test/teal b/algorand/test/teal new file mode 120000 index 000000000..d3dc86643 --- /dev/null +++ b/algorand/test/teal @@ -0,0 +1 @@ +../teal \ No newline at end of file diff --git a/algorand/test/test.py b/algorand/test/test.py new file mode 100644 index 000000000..f00d5ee58 --- /dev/null +++ b/algorand/test/test.py @@ -0,0 +1,786 @@ +# python3 -m pip install pycryptodomex uvarint pyteal web3 coincurve + +import sys +sys.path.append("..") + +from admin import PortalCore, Account +from gentest import GenTest +from base64 import b64decode + +from typing import List, Tuple, Dict, Any, Optional, Union +import base64 +import random +import time +import hashlib +import uuid +import json + +from algosdk.v2client.algod import AlgodClient +from algosdk.kmd import KMDClient +from algosdk import account, mnemonic +from algosdk.encoding import decode_address, encode_address +from algosdk.future import transaction +from pyteal import compileTeal, Mode, Expr +from pyteal import * +from algosdk.logic import get_application_address +from vaa_verify import get_vaa_verify + +from algosdk.future.transaction import LogicSig + +from test_contract import get_test_app + +from algosdk.v2client import indexer + +import pprint + +class AlgoTest(PortalCore): + def __init__(self) -> None: + super().__init__() + + def getBalances(self, client: AlgodClient, account: str) -> Dict[int, int]: + balances: Dict[int, int] = dict() + + accountInfo = client.account_info(account) + + # set key 0 to Algo balance + balances[0] = accountInfo["amount"] + + assets: List[Dict[str, Any]] = accountInfo.get("assets", []) + for assetHolding in assets: + assetID = assetHolding["asset-id"] + amount = assetHolding["amount"] + balances[assetID] = amount + + return balances + + def createTestApp( + self, + client: AlgodClient, + sender: Account, + ) -> int: + approval, clear = get_test_app(client) + + globalSchema = transaction.StateSchema(num_uints=4, num_byte_slices=30) + localSchema = transaction.StateSchema(num_uints=0, num_byte_slices=16) + + app_args = [] + + txn = transaction.ApplicationCreateTxn( + sender=sender.getAddress(), + on_complete=transaction.OnComplete.NoOpOC, + approval_program=b64decode(approval["result"]), + clear_program=b64decode(clear["result"]), + global_schema=globalSchema, + local_schema=localSchema, + app_args=app_args, + sp=client.suggested_params(), + ) + + signedTxn = txn.sign(sender.getPrivateKey()) + + client.send_transaction(signedTxn) + + response = self.waitForTransaction(client, signedTxn.get_txid()) + assert response.applicationIndex is not None and response.applicationIndex > 0 + + txn = transaction.PaymentTxn(sender = sender.getAddress(), sp = client.suggested_params(), + receiver = get_application_address(response.applicationIndex), amt = 300000) + signedTxn = txn.sign(sender.getPrivateKey()) + client.send_transaction(signedTxn) + + return response.applicationIndex + + def parseSeqFromLog(self, txn): + try: + return int.from_bytes(b64decode(txn.innerTxns[-1]["logs"][0]), "big") + except Exception as err: + pprint.pprint(txn.__dict__) + raise + + def getVAA(self, client, sender, sid, app): + if sid == None: + raise Exception("getVAA called with a sid of None") + + saddr = get_application_address(app) + + # SOOO, we send a nop txn through to push the block forward + # one + + # This is ONLY needed on a local net... the indexer will sit + # on the last block for 30 to 60 seconds... we don't want this + # log in prod since it is wasteful of gas + + if (self.INDEXER_ROUND > 512 and not self.args.testnet): # until they fix it + print("indexer is broken in local net... stop/clean/restart the sandbox") + sys.exit(0) + + txns = [] + + txns.append( + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=client.suggested_params(), + ) + ) + self.sendTxn(client, sender, txns, False) + + if self.myindexer == None: + print("indexer address: " + self.INDEXER_ADDRESS) + self.myindexer = indexer.IndexerClient(indexer_token=self.INDEXER_TOKEN, indexer_address=self.INDEXER_ADDRESS) + + while True: + nexttoken = "" + while True: + response = self.myindexer.search_transactions( min_round=self.INDEXER_ROUND, note_prefix=self.NOTE_PREFIX, next_page=nexttoken) +# pprint.pprint(response) + for x in response["transactions"]: +# pprint.pprint(x) + for y in x["inner-txns"]: + if "application-transaction" not in y: + continue + if y["application-transaction"]["application-id"] != self.coreid: + continue + if len(y["logs"]) == 0: + continue + args = y["application-transaction"]["application-args"] + if len(args) < 2: + continue + if base64.b64decode(args[0]) != b'publishMessage': + continue + seq = int.from_bytes(base64.b64decode(y["logs"][0]), "big") + if seq != sid: + continue + if y["sender"] != saddr: + continue; + emitter = decode_address(y["sender"]) + payload = base64.b64decode(args[1]) +# pprint.pprint([seq, y["sender"], payload.hex()]) +# sys.exit(0) + return self.gt.genVaa(emitter, seq, payload) + + if 'next-token' in response: + nexttoken = response['next-token'] + else: + self.INDEXER_ROUND = response['current-round'] + 1 + break + time.sleep(1) + + def publishMessage(self, client, sender, vaa, appid): + aa = decode_address(get_application_address(appid)).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + txns = [] + sp = client.suggested_params() + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=appid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"test1", vaa, self.coreid], + foreign_apps = [self.coreid], + accounts=[emitter_addr], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + self.INDEXER_ROUND = resp.confirmedRound + + return self.parseSeqFromLog(resp) + + def createTestAsset(self, client, sender): + txns = [] + + a = transaction.PaymentTxn( + sender = sender.getAddress(), + sp = client.suggested_params(), + receiver = get_application_address(self.testid), + amt = 300000 + ) + + txns.append(a) + + sp = client.suggested_params() + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.testid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"setup"], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + transaction.assign_group_id(txns) + + grp = [] + pk = sender.getPrivateKey() + for t in txns: + grp.append(t.sign(pk)) + + client.send_transactions(grp) + resp = self.waitForTransaction(client, grp[-1].get_txid()) + + aid = int.from_bytes(resp.__dict__["logs"][0], "big") + + print("Opting " + sender.getAddress() + " into " + str(aid)) + self.asset_optin(client, sender, aid, sender.getAddress()) + + txns = [] + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.testid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"mint"], + foreign_assets = [aid], + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + +# self.INDEXER_ROUND = resp.confirmedRound + + return aid + + def getCreator(self, client, sender, asset_id): + return client.asset_info(asset_id)["params"]["creator"] + + def testAttest(self, client, sender, asset_id): + taddr = get_application_address(self.tokenid) + aa = decode_address(taddr).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + if asset_id != 0: + creator = self.getCreator(client, sender, asset_id) + c = client.account_info(creator) + wormhole = c.get("auth-addr") == taddr + else: + c = None + wormhole = False + + if not wormhole: + creator = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + + txns = [] + sp = client.suggested_params() + + txns.append(transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=sp + )) + + mfee = self.getMessageFee() + if (mfee > 0): + txns.append(transaction.PaymentTxn(sender = sender.getAddress(), sp = sp, receiver = get_application_address(self.tokenid), amt = mfee)) + + accts = [emitter_addr, creator, get_application_address(self.coreid)] + if c != None: + accts.append(c["address"]) + + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"attestToken", asset_id], + foreign_apps = [self.coreid], + foreign_assets = [asset_id], + accounts=accts, + sp=sp + ) + + if (mfee > 0): + a.fee = a.fee * 3 + else: + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + # Point us at the correct round + self.INDEXER_ROUND = resp.confirmedRound + +# print(encode_address(resp.__dict__["logs"][0])) +# print(encode_address(resp.__dict__["logs"][1])) +# pprint.pprint(resp.__dict__) + return self.parseSeqFromLog(resp) + + def transferFromAlgorand(self, client, sender, asset_id, quantity, receiver, chain, fee, payload = None): +# pprint.pprint(["transferFromAlgorand", asset_id, quantity, receiver, chain, fee]) + + taddr = get_application_address(self.tokenid) + aa = decode_address(taddr).hex() + emitter_addr = self.optin(client, sender, self.coreid, 0, aa) + + # asset_id 0 is ALGO + + if asset_id == 0: + wormhole = False + else: + creator = self.getCreator(client, sender, asset_id) + c = client.account_info(creator) + wormhole = c.get("auth-addr") == taddr + + txns = [] + + + mfee = self.getMessageFee() + if (mfee > 0): + txns.append(transaction.PaymentTxn(sender = sender.getAddress(), sp = sp, receiver = get_application_address(self.tokenid), amt = mfee)) + + if not wormhole: + creator = self.optin(client, sender, self.tokenid, asset_id, b"native".hex()) + print("non wormhole account " + creator) + + sp = client.suggested_params() + + if (asset_id != 0) and (not self.asset_optin_check(client, sender, asset_id, creator)): + print("Looks like we need to optin") + + txns.append( + transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=creator, + amt=100000, + sp=sp + ) + ) + + # The tokenid app needs to do the optin since it has signature authority + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"optin", asset_id], + foreign_assets = [asset_id], + accounts=[creator], + sp=sp + ) + + a.fee = a.fee * 2 + txns.append(a) + self.sendTxn(client, sender, txns, False) + txns = [] + + txns.insert(0, + transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=[b"nop"], + sp=client.suggested_params(), + ) + ) + + if asset_id == 0: + print("asset_id == 0") + txns.append(transaction.PaymentTxn( + sender=sender.getAddress(), + receiver=creator, + amt=quantity, + sp=sp, + )) + accounts=[emitter_addr, creator, creator] + else: + print("asset_id != 0") + txns.append( + transaction.AssetTransferTxn( + sender = sender.getAddress(), + sp = sp, + receiver = creator, + amt = quantity, + index = asset_id + )) + accounts=[emitter_addr, creator, c["address"]] + + args = [b"sendTransfer", asset_id, quantity, decode_address(receiver), chain, fee] + if None != payload: + args.append(payload) + + #pprint.pprint(args) + +# print(self.tokenid) + a = transaction.ApplicationCallTxn( + sender=sender.getAddress(), + index=self.tokenid, + on_complete=transaction.OnComplete.NoOpOC, + app_args=args, + foreign_apps = [self.coreid], + foreign_assets = [asset_id], + accounts=accounts, + sp=sp + ) + + a.fee = a.fee * 2 + + txns.append(a) + + resp = self.sendTxn(client, sender, txns, True) + + self.INDEXER_ROUND = resp.confirmedRound + +# pprint.pprint([self.coreid, self.tokenid, resp.__dict__, +# int.from_bytes(resp.__dict__["logs"][1], "big"), +# int.from_bytes(resp.__dict__["logs"][2], "big"), +# int.from_bytes(resp.__dict__["logs"][3], "big"), +# int.from_bytes(resp.__dict__["logs"][4], "big"), +# int.from_bytes(resp.__dict__["logs"][5], "big") +# ]) +# print(encode_address(resp.__dict__["logs"][0])) +# print(encode_address(resp.__dict__["logs"][1])) + return self.parseSeqFromLog(resp) + + def asset_optin_check(self, client, sender, asset, receiver): + if receiver not in self.asset_cache: + self.asset_cache[receiver] = {} + + if asset in self.asset_cache[receiver]: + return True + + ai = client.account_info(receiver) + if "assets" in ai: + for x in ai["assets"]: + if x["asset-id"] == asset: + self.asset_cache[receiver][asset] = True + return True + + return False + + def asset_optin(self, client, sender, asset, receiver): + if self.asset_optin_check(client, sender, asset, receiver): + return + + pprint.pprint(["asset_optin", asset, receiver]) + + sp = client.suggested_params() + optin_txn = transaction.AssetTransferTxn( + sender = sender.getAddress(), + sp = sp, + receiver = receiver, + amt = 0, + index = asset + ) + + transaction.assign_group_id([optin_txn]) + signed_optin = optin_txn.sign(sender.getPrivateKey()) + client.send_transactions([signed_optin]) + resp = self.waitForTransaction(client, signed_optin.get_txid()) + assert self.asset_optin_check(client, sender, asset, receiver), "The optin failed" + print("woah! optin succeeded") + + def simple_test(self): +# q = bytes.fromhex(gt.genAssetMeta(gt.guardianPrivKeys, 1, 1, 1, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, 8, b"USDC", b"CircleCoin")) +# pprint.pprint(self.parseVAA(q)) +# sys.exit(0) + + +# vaa = self.parseVAA(bytes.fromhex("0100000001010001ca2fbf60ac6227d47dda4fe2e7bccc087f27d22170a212b9800da5b4cbf0d64c52deb2f65ce58be2267bf5b366437c267b5c7b795cd6cea1ac2fee8a1db3ad006225f801000000010001000000000000000000000000000000000000000000000000000000000000000400000000000000012000000000000000000000000000000000000000000000000000000000436f72650200000000000001beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe")) +# pprint.pprint(vaa) +# vaa = self.parseVAA(bytes.fromhex("01000000010100c22ce0a3c995fca993cb0e91af74d745b6ec1a04b3adf0bb3e432746b3e2ab5e635b65d34d5148726cac10e84bf5932a7f21b9545c362bd512617aa980e0fbf40062607566000000010001000000000000000000000000000000000000000000000000000000000000000400000000000000012000000000000000000000000000000000000000000000000000000000436f72650200000000000101beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe")) +# pprint.pprint(vaa) +# sys.exit(0) + + gt = GenTest(True) + self.gt = gt + + self.setup_args() + + if self.args.testnet: + self.testnet() + + client = self.client = self.getAlgodClient() + + self.genTeal() + + self.vaa_verify = self.client.compile(get_vaa_verify()) + self.vaa_verify["lsig"] = LogicSig(base64.b64decode(self.vaa_verify["result"])) + + vaaLogs = [] + + args = self.args + + if self.args.mnemonic: + self.foundation = Account.FromMnemonic(self.args.mnemonic) + + if self.foundation == None: + print("Generating the foundation account...") + self.foundation = self.getTemporaryAccount(self.client) + + if self.foundation == None: + print("We dont have a account? ") + sys.exit(0) + + foundation = self.foundation + + seq = int(time.time()) + + print("Creating the PortalCore app") + self.coreid = self.createPortalCoreApp(client=client, sender=foundation) + print("coreid = " + str(self.coreid) + " " + get_application_address(self.coreid)) + + print("bootstrapping the guardian set...") + bootVAA = bytes.fromhex(gt.genGuardianSetUpgrade(gt.guardianPrivKeys, 1, 1, seq, seq)) + + self.bootGuardians(bootVAA, client, foundation, self.coreid) + + seq += 1 + + print("grabbing a untrusted account") + player = self.getTemporaryAccount(client) + print(player.getAddress()) + print("") + + bal = self.getBalances(client, player.getAddress()) + pprint.pprint(bal) + + print("upgrading the the guardian set using untrusted account...") + upgradeVAA = bytes.fromhex(gt.genGuardianSetUpgrade(gt.guardianPrivKeys, 1, 2, seq, seq)) + vaaLogs.append(["guardianUpgrade", upgradeVAA.hex()]) + self.submitVAA(upgradeVAA, client, player, self.coreid) + + bal = self.getBalances(client, player.getAddress()) + pprint.pprint(bal) + + seq += 1 + + print("Create the token bridge") + self.tokenid = self.createTokenBridgeApp(client, foundation) + print("token bridge " + str(self.tokenid) + " address " + get_application_address(self.tokenid)) + + ret = self.devnetUpgradeVAA() +# pprint.pprint(ret) + print("Submitting core") + self.submitVAA(bytes.fromhex(ret[0]), self.client, foundation, self.coreid) + print("Submitting token") + self.submitVAA(bytes.fromhex(ret[1]), self.client, foundation, self.tokenid) + + print("successfully sent upgrade requests") + + for r in range(1, 6): + print("Registering chain " + str(r)) + v = gt.genRegisterChain(gt.guardianPrivKeys, 2, seq, seq, r) + vaa = bytes.fromhex(v) +# pprint.pprint((v, self.parseVAA(vaa))) + if r == 2: + vaaLogs.append(["registerChain", v]) + self.submitVAA(vaa, client, player, self.tokenid) + seq += 1 + + bal = self.getBalances(client, player.getAddress()) + pprint.pprint(bal) + + print("Create a asset") + attestVAA = bytes.fromhex(gt.genAssetMeta(gt.guardianPrivKeys, 2, seq, seq, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, 8, b"USDC", b"CircleCoin")) + # paul - createWrappedOnAlgorand + vaaLogs.append(["createWrappedOnAlgorand", attestVAA.hex()]) + self.submitVAA(attestVAA, client, player, self.tokenid) + seq += 1 + + p = self.parseVAA(attestVAA) + chain_addr = self.optin(client, player, self.tokenid, p["FromChain"], p["Contract"]) + + print("Create the same asset " + str(seq)) + # paul - updateWrappedOnAlgorand + attestVAA = bytes.fromhex(gt.genAssetMeta(gt.guardianPrivKeys, 2, seq, seq, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, 8, b"USD2C", b"Circle2Coin")) + self.submitVAA(attestVAA, client, player, self.tokenid) + seq += 1 + + print("Transfer the asset " + str(seq)) + transferVAA = bytes.fromhex(gt.genTransfer(gt.guardianPrivKeys, 1, 1, 1, 1, bytes.fromhex("4523c3F29447d1f32AEa95BEBD00383c4640F1b4"), 1, decode_address(player.getAddress()), 8, 0)) + # paul - redeemOnAlgorand + vaaLogs.append(["redeemOnAlgorand", transferVAA.hex()]) + self.submitVAA(transferVAA, client, player, self.tokenid) + seq += 1 + + aid = client.account_info(player.getAddress())["assets"][0]["asset-id"] + print("generate an attest of the asset we just received: " + str(aid)) + # paul - attestFromAlgorand + self.testAttest(client, player, aid) + + print("Create the test app we will use to torture ourselves using a new player") + player2 = self.getTemporaryAccount(client) + print("player2 address " + player2.getAddress()) + player3 = self.getTemporaryAccount(client) + print("player3 address " + player3.getAddress()) + + self.testid = self.createTestApp(client, player2) + print("testid " + str(self.testid) + " address " + get_application_address(self.testid)) + + print("Sending a message payload to the core contract") + sid = self.publishMessage(client, player, b"you also suck", self.testid) + self.publishMessage(client, player2, b"second suck", self.testid) + self.publishMessage(client, player3, b"last message", self.testid) + + print("Lets create a brand new non-wormhole asset and try to attest and send it out") + self.testasset = self.createTestAsset(client, player2) + print("test asset id: " + str(self.testasset)) + + print("Now lets create an attest of ALGO") + sid = self.testAttest(client, player2, 0) + vaa = self.getVAA(client, player, sid, self.tokenid) + v = self.parseVAA(bytes.fromhex(vaa)) + print("We got a " + v["Meta"]) + + print("Lets try to create an attest for a non-wormhole thing with a huge number of decimals") + # paul - attestFromAlgorand + sid = self.testAttest(client, player2, self.testasset) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + v = self.parseVAA(bytes.fromhex(vaa)) + print("We got a " + v["Meta"]) + + pprint.pprint(self.getBalances(client, player.getAddress())) + pprint.pprint(self.getBalances(client, player2.getAddress())) + pprint.pprint(self.getBalances(client, player3.getAddress())) + + print("Lets transfer that asset to one of our other accounts... first lets create the vaa") + # paul - transferFromAlgorand + sid = self.transferFromAlgorand(client, player2, self.testasset, 100, player3.getAddress(), 8, 0) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + print(".. and lets pass that to player3") + vaaLogs.append(["transferFromAlgorand", vaa]) + #pprint.pprint(vaaLogs) + self.submitVAA(bytes.fromhex(vaa), client, player3, self.tokenid) + + pprint.pprint(["player", self.getBalances(client, player.getAddress())]) + pprint.pprint(["player2", self.getBalances(client, player2.getAddress())]) + pprint.pprint(["player3", self.getBalances(client, player3.getAddress())]) + + # Lets split it into two parts... the payload and the fee + print("Lets split it into two parts... the payload and the fee (400 should go to player, 600 should go to player3)") + sid = self.transferFromAlgorand(client, player2, self.testasset, 1000, player3.getAddress(), 8, 400) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) +# pprint.pprint(self.parseVAA(bytes.fromhex(vaa))) + print(".. and lets pass that to player3 with fees being passed to player acting as a relayer (" + str(self.tokenid) + ")") + self.submitVAA(bytes.fromhex(vaa), client, player, self.tokenid) + + pprint.pprint(["player", self.getBalances(client, player.getAddress())]) + pprint.pprint(["player2", self.getBalances(client, player2.getAddress())]) + pprint.pprint(["player3", self.getBalances(client, player3.getAddress())]) + +# sys.exit(0) + + # Now it gets tricky, lets create a virgin account... + pk, addr = account.generate_account() + emptyAccount = Account(pk) + + print("How much is in the empty account? (" + addr + ")") + pprint.pprint(self.getBalances(client, emptyAccount.getAddress())) + + # paul - transferFromAlgorand + print("Lets transfer algo this time.... first lets create the vaa") + sid = self.transferFromAlgorand(client, player2, 0, 1000000, emptyAccount.getAddress(), 8, 0) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) +# pprint.pprint(vaa) + print(".. and lets pass that to the empty account.. but use somebody else to relay since we cannot pay for it") + + # paul - redeemOnAlgorand + self.submitVAA(bytes.fromhex(vaa), client, player, self.tokenid) + + print("=================================================") + + print("How much is in the source account now?") + pprint.pprint(self.getBalances(client, player2.getAddress())) + + print("How much is in the empty account now?") + pprint.pprint(self.getBalances(client, emptyAccount.getAddress())) + + print("How much is in the player3 account now?") + pprint.pprint(self.getBalances(client, player3.getAddress())) + + print("Lets transfer more algo.. split 40/60 with the relayer.. going to player3") + sid = self.transferFromAlgorand(client, player2, 0, 1000000, player3.getAddress(), 8, 400000) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + print(".. and lets pass that to player3.. but use the previously empty account to relay it") + self.submitVAA(bytes.fromhex(vaa), client, emptyAccount, self.tokenid) + + print("How much is in the source account now?") + pprint.pprint(self.getBalances(client, player2.getAddress())) + + print("How much is in the empty account now?") + pprint.pprint(self.getBalances(client, emptyAccount.getAddress())) + + print("How much is in the player3 account now?") + pprint.pprint(self.getBalances(client, player3.getAddress())) + + print("How about a payload3") + sid = self.transferFromAlgorand(client, player2, 0, 100, get_application_address(self.testid), 8, 0, self.testid.to_bytes(8, "big")+b'hi mom') + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + + print("testid balance before = ", self.getBalances(client, get_application_address(self.testid))) + + print(".. Lets let player3 relay it for us") + self.submitVAA(bytes.fromhex(vaa), client, player3, self.tokenid) + + print("testid balance after = ", self.getBalances(client, get_application_address(self.testid))) + + print(".. Ok, now it is time to up the message fees") + + bal = self.getBalances(client, get_application_address(self.coreid)) + print("core contract has " + str(bal) + " algo (" + get_application_address(self.coreid) + ")") + print("core contract has a MessageFee set to " + str(self.getMessageFee())) + + seq += 1 + v = gt.genGSetFee(gt.guardianPrivKeys, 2, seq, seq, 2000000) + self.submitVAA(bytes.fromhex(v), client, player, self.coreid) + seq += 1 + + print("core contract now has a MessageFee set to " + str(self.getMessageFee())) + +# v = gt.genGSetFee(gt.guardianPrivKeys, 2, seq, seq, 0) +# self.submitVAA(bytes.fromhex(v), client, player, self.coreid) +# seq += 1 + +# print("core contract is back to " + str(self.getMessageFee())) + + print("Generating an attest.. This will cause a message to get published .. which should cause fees to get sent to the core contract") + sid = self.testAttest(client, player2, self.testasset) + print("... track down the generated VAA") + vaa = self.getVAA(client, player, sid, self.tokenid) + v = self.parseVAA(bytes.fromhex(vaa)) + print("We got a " + v["Meta"]) + + bal = self.getBalances(client, get_application_address(self.coreid)) + print("core contract has " + str(bal) + " algo (" + get_application_address(self.coreid) + ")") + +# print("player account: " + player.getAddress()) +# pprint.pprint(client.account_info(player.getAddress())) + +# print("player2 account: " + player2.getAddress()) +# pprint.pprint(client.account_info(player2.getAddress())) + +# print("foundation account: " + foundation.getAddress()) +# pprint.pprint(client.account_info(foundation.getAddress())) +# +# print("core app: " + get_application_address(self.coreid)) +# pprint.pprint(client.account_info(get_application_address(self.coreid))), +# +# print("token app: " + get_application_address(self.tokenid)) +# pprint.pprint(client.account_info(get_application_address(self.tokenid))), +# +# print("asset app: " + chain_addr) +# pprint.pprint(client.account_info(chain_addr)) + +if __name__ == "__main__": + core = AlgoTest() + core.simple_test() diff --git a/algorand/test/test.ts b/algorand/test/test.ts new file mode 100644 index 000000000..84de20f4d --- /dev/null +++ b/algorand/test/test.ts @@ -0,0 +1,126 @@ +const algosdk = require('algosdk'); +const TestLib = require('./testlib.ts') +const testLib = new TestLib.TestLib() +const fs = require('fs'); +const path = require('path'); + + +import { + getAlgoClient, + submitVAA, + submitVAAHdr, + simpleSignVAA, + getIsTransferCompletedAlgorand, + parseVAA, + CORE_ID, + TOKEN_BRIDGE_ID, + attestFromAlgorand, + AccountToSigner +} from "@certusone/wormhole-sdk/lib/cjs/algorand/Algorand"; + +import { + hexStringToUint8Array, + uint8ArrayToHexString, +} from "@certusone/wormhole-sdk/lib/cjs/algorand/TmplSig"; + + +import { + getTempAccounts, +} from "@certusone/wormhole-sdk/lib/cjs/algorand/Helpers"; + + +const guardianKeys = [ + "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe" +] +const guardianPrivKeys = [ + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0" +] + + +class AlgoTests { + constructor() { + } + + async runTests() { + let seq = Math.floor(new Date().getTime() / 1000.0); + +// let t = "01000000000100bc942f5b6da266078844b26cb01bb541e0b5963da5bae9aadfe717ed5376efa711224796fc9e893dbf6f19ef6472a62f9af9241ece016e42da8a076bbf1ffe3c006250770b625077090001000000000000000000000000000000000000000000000000000000000000000400000000625077092000000000000000000000000000000000000000000000000000000000436f72650200000000000101beFA429d57cD18b7F8A4d91A29AB4AF05d0FBe" +// console.log(t) +// console.log(parseVAA(hexStringToUint8Array(t))) +// process.exit(0) + + console.log("test start"); + let client = getAlgoClient(); + + let accounts = await getTempAccounts(); + let player = AccountToSigner(accounts[0]) + + console.log("attesting some ALGO"); + console.log(await attestFromAlgorand(client, player, 0)) + process.exit(0); + +// let t = testLib.genTransfer(guardianPrivKeys, 1, 1, 1, 1, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 2, uint8ArrayToHexString(algosdk.decodeAddress(player.addr).publicKey, false), 8, 0) +// console.log(t) +// console.log(parseVAA(hexStringToUint8Array(t))) +// process.exit(0) + + console.log("seq = ", seq); + + console.log("XXX upgrading the the guardian set using untrusted account...", seq) + let upgradeVAA = testLib.genGuardianSetUpgrade(guardianPrivKeys, 0, 1, seq, seq, guardianKeys) + console.log(upgradeVAA) + console.log(parseVAA(hexStringToUint8Array(upgradeVAA))) + + let vaa = hexStringToUint8Array(upgradeVAA); + + if (await getIsTransferCompletedAlgorand(client, vaa, CORE_ID, player) != false) { + console.log("assert failed 1"); + process.exit(-1); + } + + await submitVAA(vaa, client, player, CORE_ID) + + if (await getIsTransferCompletedAlgorand(client, vaa, CORE_ID, player) != true) { + console.log("assert failed 2"); + process.exit(-1); + } + + process.exit(0) + + seq = seq + 1 + + console.log("XXX upgrading again...", seq) + upgradeVAA = testLib.genGuardianSetUpgrade(guardianPrivKeys, 1, 2, seq, seq, guardianKeys) + console.log(upgradeVAA) + await submitVAA(hexStringToUint8Array(upgradeVAA), client, player, CORE_ID) + + seq = seq + 1 + + console.log("XXX registering chain 2", seq) + let reg = testLib.genRegisterChain(guardianPrivKeys, 2, 1, seq, 2) + console.log(reg) + await submitVAA(hexStringToUint8Array(reg), client, player, TOKEN_BRIDGE_ID) + + seq = seq + 1 + + console.log("XXX gen asset meta", seq) + let a = testLib.genAssetMeta(guardianPrivKeys, 2, seq, seq, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 2, 8, "USDC", "CircleCoin") + console.log(a) + await submitVAA(hexStringToUint8Array(a), client, player, TOKEN_BRIDGE_ID) + + seq = seq + 1 + + console.log("XXX Transfer the asset ") + let transferVAA = testLib.genTransfer(guardianPrivKeys, 2, 1, seq, 1, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 2, uint8ArrayToHexString(algosdk.decodeAddress(player.addr).publicKey, false), 8, 0) + await submitVAA(hexStringToUint8Array(transferVAA), client, player, TOKEN_BRIDGE_ID) + + seq = seq + 1 + + console.log("test complete"); + } +}; + +let t = new AlgoTests() +t.runTests() + + diff --git a/algorand/test/test2.ts b/algorand/test/test2.ts new file mode 100644 index 000000000..62c67f9be --- /dev/null +++ b/algorand/test/test2.ts @@ -0,0 +1,133 @@ +const algosdk = require('algosdk'); +const TestLib = require('./testlib.ts') +const testLib = new TestLib.TestLib() +const fs = require('fs'); +const path = require('path'); + + +import { + getAlgoClient, + submitVAA, + submitVAAHdr, + simpleSignVAA, + getIsTransferCompletedAlgorand, + parseVAA, + CORE_ID, + TOKEN_BRIDGE_ID +} from "@certusone/wormhole-sdk/lib/cjs/algorand/Algorand"; + +import { + hexStringToUint8Array, + uint8ArrayToHexString, +} from "@certusone/wormhole-sdk/lib/cjs/algorand/TmplSig"; + + +import { + getTempAccounts, +} from "@certusone/wormhole-sdk/lib/cjs/algorand/Helpers"; + + +const guardianKeys = [ + "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe" +] +const guardianPrivKeys = [ + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0" +] + + +class AlgoTests { + constructor() { + } + + async runTests() { + let seq = Math.floor(new Date().getTime() / 1000.0); + +// let t = "01000000000100bc942f5b6da266078844b26cb01bb541e0b5963da5bae9aadfe717ed5376efa711224796fc9e893dbf6f19ef6472a62f9af9241ece016e42da8a076bbf1ffe3c006250770b625077090001000000000000000000000000000000000000000000000000000000000000000400000000625077092000000000000000000000000000000000000000000000000000000000436f72650200000000000101beFA429d57cD18b7F8A4d91A29AB4AF05d0FBe" +// console.log(t) +// console.log(parseVAA(hexStringToUint8Array(t))) +// process.exit(0) + + console.log("test start"); + let client = getAlgoClient(); + + let accounts = await getTempAccounts(); + let player = accounts[0] + + let t = testLib.genAssetMeta(guardianPrivKeys, 0, seq, seq, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 1, 8, "USDC", "CircleCoin") + console.log(t) + console.log(parseVAA(hexStringToUint8Array(t))) + + await submitVAA(hexStringToUint8Array(t), client, player, TOKEN_BRIDGE_ID) + + process.exit(0) + +// vaaLogs.append(["createWrappedOnAlgorand", attestVAA.hex()]) +// self.submitVAA(attestVAA, client, player, self.tokenid) + + + t = testLib.genTransfer(guardianPrivKeys, 1, 1, 1, 1, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 2, uint8ArrayToHexString(algosdk.decodeAddress(player.addr).publicKey, false), 8, 0) + console.log(t) + console.log(parseVAA(hexStringToUint8Array(t))) + + process.exit(0) + + console.log("seq = ", seq); + + console.log("XXX upgrading the the guardian set using untrusted account...", seq) + let upgradeVAA = testLib.genGuardianSetUpgrade(guardianPrivKeys, 0, 1, seq, seq, guardianKeys) + console.log(upgradeVAA) + console.log(parseVAA(hexStringToUint8Array(upgradeVAA))) + + let vaa = hexStringToUint8Array(upgradeVAA); + + if (await getIsTransferCompletedAlgorand(client, vaa, CORE_ID, player) != false) { + console.log("assert failed 1"); + process.exit(-1); + } + + await submitVAA(vaa, client, player, CORE_ID) + + if (await getIsTransferCompletedAlgorand(client, vaa, CORE_ID, player) != true) { + console.log("assert failed 2"); + process.exit(-1); + } + + process.exit(0) + + seq = seq + 1 + + console.log("XXX upgrading again...", seq) + upgradeVAA = testLib.genGuardianSetUpgrade(guardianPrivKeys, 1, 2, seq, seq, guardianKeys) + console.log(upgradeVAA) + await submitVAA(hexStringToUint8Array(upgradeVAA), client, player, CORE_ID) + + seq = seq + 1 + + console.log("XXX registering chain 2", seq) + let reg = testLib.genRegisterChain(guardianPrivKeys, 2, 1, seq, 2) + console.log(reg) + await submitVAA(hexStringToUint8Array(reg), client, player, TOKEN_BRIDGE_ID) + + seq = seq + 1 + + console.log("XXX gen asset meta", seq) + let a = testLib.genAssetMeta(guardianPrivKeys, 2, seq, seq, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 2, 8, "USDC", "CircleCoin") + console.log(a) + await submitVAA(hexStringToUint8Array(a), client, player, TOKEN_BRIDGE_ID) + + seq = seq + 1 + + console.log("XXX Transfer the asset ") + let transferVAA = testLib.genTransfer(guardianPrivKeys, 2, 1, seq, 1, "4523c3F29447d1f32AEa95BEBD00383c4640F1b4", 2, uint8ArrayToHexString(algosdk.decodeAddress(player.addr).publicKey, false), 8, 0) + await submitVAA(hexStringToUint8Array(transferVAA), client, player, TOKEN_BRIDGE_ID) + + seq = seq + 1 + + console.log("test complete"); + } +}; + +let t = new AlgoTests() +t.runTests() + + diff --git a/algorand/test/test_contract.py b/algorand/test/test_contract.py new file mode 100644 index 000000000..19f8c48c7 --- /dev/null +++ b/algorand/test/test_contract.py @@ -0,0 +1,163 @@ +#!/usr/bin/python3 +""" +Copyright 2022 Wormhole Project Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); + +you may not use this file except in compliance with the License. + +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""" + +from typing import List, Tuple, Dict, Any, Optional, Union + +from pyteal.ast import * +from pyteal.types import * +from pyteal.compiler import * +from pyteal.ir import * +from globals import * +from inlineasm import * + +from algosdk.v2client.algod import AlgodClient + +from TmplSig import TmplSig + +from local_blob import LocalBlob + +import sys + +def fullyCompileContract(client: AlgodClient, contract: Expr) -> bytes: + teal = compileTeal(contract, mode=Mode.Application, version=6) + response = client.compile(teal) + return response + +def clear_app(): + return Int(1) + +def approve_app(): + me = Global.current_application_address() + + def nop(): + return Seq([Approve()]) + + def test1(): + # Look! a proxy contract that sends message to the core + return Seq( + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.type_enum: TxnType.ApplicationCall, + TxnField.application_id: Btoi(Txn.application_args[2]), + TxnField.application_args: [Bytes("publishMessage"), Txn.application_args[1]], + TxnField.accounts: [Txn.accounts[1]], + TxnField.note: Bytes("publishMessage"), + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + Approve() + ) + + def setup(): + aid = ScratchVar() + + return Seq([ + # Create a test asset + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Global.current_application_address(), + TxnField.type_enum: TxnType.AssetConfig, + TxnField.config_asset_name: Bytes("TestAsset"), + TxnField.config_asset_unit_name: Bytes("testAsse"), + TxnField.config_asset_total: Int(int(1e17)), + TxnField.config_asset_decimals: Int(10), + TxnField.config_asset_manager: Global.current_application_address(), + TxnField.config_asset_reserve: Global.current_application_address(), + + # We cannot freeze or clawback assets... per the spirit of + TxnField.config_asset_freeze: Global.zero_address(), + TxnField.config_asset_clawback: Global.zero_address(), + + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + + aid.store(Itob(InnerTxn.created_asset_id())), + + App.globalPut(Bytes("asset"), aid.load()), + Log(aid.load()), + + Approve() + ]) + + def completeTransfer(): + return Seq([ + Approve() + ]) + + def mint(): + return Seq([ + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Global.current_application_address(), + TxnField.type_enum: TxnType.AssetTransfer, + TxnField.xfer_asset: Btoi(App.globalGet(Bytes("asset"))), + TxnField.asset_amount: Int(100000), + TxnField.asset_receiver: Txn.sender(), + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + + Approve() + ]) + + METHOD = Txn.application_args[0] + + router = Cond( + [METHOD == Bytes("nop"), nop()], + [METHOD == Bytes("test1"), test1()], + [METHOD == Bytes("setup"), setup()], + [METHOD == Bytes("mint"), mint()], + [METHOD == Bytes("completeTransfer"), completeTransfer()], + ) + + on_create = Seq( [ + Return(Int(1)) + ]) + + on_update = Seq( [ + Return(Int(1)) + ] ) + + on_delete = Seq( [ + Return(Int(1)) + ] ) + + on_optin = Seq( [ + Return(Int(1)) + ] ) + + return Cond( + [Txn.application_id() == Int(0), on_create], + [Txn.on_completion() == OnComplete.UpdateApplication, on_update], + [Txn.on_completion() == OnComplete.DeleteApplication, on_delete], + [Txn.on_completion() == OnComplete.OptIn, on_optin], + [Txn.on_completion() == OnComplete.NoOp, router] + ) + +def get_test_app(client: AlgodClient) -> Tuple[bytes, bytes]: + APPROVAL_PROGRAM = fullyCompileContract(client, approve_app()) + CLEAR_STATE_PROGRAM = fullyCompileContract(client, clear_app()) + + return APPROVAL_PROGRAM, CLEAR_STATE_PROGRAM diff --git a/algorand/test/testlib.ts b/algorand/test/testlib.ts new file mode 100644 index 000000000..ee916d6d6 --- /dev/null +++ b/algorand/test/testlib.ts @@ -0,0 +1,495 @@ +/** + * + * Copyright 2022 Wormhole Project Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { + ChainId, + CHAIN_ID_AVAX, + CHAIN_ID_BSC, + CHAIN_ID_ETH, + CHAIN_ID_FANTOM, + CHAIN_ID_OASIS, + CHAIN_ID_POLYGON, + CHAIN_ID_SOLANA, + CHAIN_ID_TERRA, +} from "@certusone/wormhole-sdk"; + +const web3EthAbi = require("web3-eth-abi"); +const web3Utils = require("web3-utils"); +const elliptic = require("elliptic"); + +export class TestLib { + zeroBytes: string; + + singleGuardianKey: string[] = ["beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe"]; + + singleGuardianPrivKey: string[] = [ + "cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0", + ]; + + constructor() { + this.zeroBytes = + "0000000000000000000000000000000000000000000000000000000000000000"; + } + + hexStringToUint8Array(hs: string): Uint8Array { + if (hs.length % 2 === 1) { + // prepend a 0 + hs = "0" + hs; + } + const buf = Buffer.from(hs, "hex"); + const retval = Uint8Array.from(buf); + return retval; + } + + uint8ArrayToHexString(arr: Uint8Array, add0x: boolean) { + const ret: string = Buffer.from(arr).toString("hex"); + if (!add0x) { + return ret; + } + return "0x" + ret; + } + + guardianKeys: string[] = [ + "52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2", + "389A74E8FFa224aeAD0778c786163a7A2150768C", + "B4459EA6482D4aE574305B239B4f2264239e7599", + "072491bd66F63356090C11Aae8114F5372aBf12B", + "51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfF", + "fa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CB", + "e42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A", + "4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087e", + "c8306B84235D7b0478c61783C50F990bfC44cFc0", + "C8C1035110a13fe788259A4148F871b52bAbcb1B", + "58A2508A20A7198E131503ce26bBE119aA8c62b2", + "8390820f04ddA22AFe03be1c3bb10f4ba6CF94A0", + "1FD6e97387C34a1F36DE0f8341E9D409E06ec45b", + "255a41fC2792209CB998A8287204D40996df9E54", + "bA663B12DD23fbF4FbAC618Be140727986B3BBd0", + "79040E577aC50486d0F6930e160A5C75FD1203C6", + "3580D2F00309A9A85efFAf02564Fc183C0183A96", + "3869795913D3B6dBF3B24a1C7654672c69A23c35", + "1c0Cc52D7673c52DE99785741344662F5b2308a0", + ]; + + guardianPrivKeys: string[] = [ + "563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757", + "8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f", + "9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b", + "5a02c4cd110d20a83a7ce8d1a2b2ae5df252b4e5f6781c7855db5cc28ed2d1b4", + "93d4e3b443bf11f99a00901222c032bd5f63cf73fc1bcfa40829824d121be9b2", + "ea40e40c63c6ff155230da64a2c44fcd1f1c9e50cacb752c230f77771ce1d856", + "87eaabe9c27a82198e618bca20f48f9679c0f239948dbd094005e262da33fe6a", + "61ffed2bff38648a6d36d6ed560b741b1ca53d45391441124f27e1e48ca04770", + "bd12a242c6da318fef8f98002efb98efbf434218a78730a197d981bebaee826e", + "20d3597bb16525b6d09e5fb56feb91b053d961ab156f4807e37d980f50e71aff", + "344b313ffbc0199ff6ca08cacdaf5dc1d85221e2f2dc156a84245bd49b981673", + "848b93264edd3f1a521274ca4da4632989eb5303fd15b14e5ec6bcaa91172b05", + "c6f2046c1e6c172497fc23bd362104e2f4460d0f61984938fa16ef43f27d93f6", + "693b256b1ee6b6fb353ba23274280e7166ab3be8c23c203cc76d716ba4bc32bf", + "13c41508c0da03018d61427910b9922345ced25e2bbce50652e939ee6e5ea56d", + "460ee0ee403be7a4f1eb1c63dd1edaa815fbaa6cf0cf2344dcba4a8acf9aca74", + "b25148579b99b18c8994b0b86e4dd586975a78fa6e7ad6ec89478d7fbafd2683", + "90d7ac6a82166c908b8cf1b352f3c9340a8d1f2907d7146fb7cd6354a5436cca", + "b71d23908e4cf5d6cd973394f3a4b6b164eb1065785feee612efdfd8d30005ed", + ]; + + encoder(type: string, val: any) { + if (type == "uint8") + return web3EthAbi.encodeParameter("uint8", val).substring(2 + (64 - 2)); + if (type == "uint16") + return web3EthAbi.encodeParameter("uint16", val).substring(2 + (64 - 4)); + if (type == "uint32") + return web3EthAbi.encodeParameter("uint32", val).substring(2 + (64 - 8)); + if (type == "uint64") + return web3EthAbi.encodeParameter("uint64", val).substring(2 + (64 - 16)); + if (type == "uint128") + return web3EthAbi + .encodeParameter("uint128", val) + .substring(2 + (64 - 32)); + if (type == "uint256" || type == "bytes32") + return web3EthAbi.encodeParameter(type, val).substring(2 + (64 - 64)); + } + + ord(c: any) { + return c.charCodeAt(0); + } + + genGuardianSetUpgrade( + signers: any, + guardianSet: number, + targetSet: number, + nonce: number, + seq: number, + guardianKeys: string[] + ): string { + const b = [ + "0x", + this.zeroBytes.slice(0, 28 * 2), + this.encoder("uint8", this.ord("C")), + this.encoder("uint8", this.ord("o")), + this.encoder("uint8", this.ord("r")), + this.encoder("uint8", this.ord("e")), + this.encoder("uint8", 2), + this.encoder("uint16", 0), + this.encoder("uint32", targetSet), + this.encoder("uint8", guardianKeys.length), + ]; + + guardianKeys.forEach((x) => { + b.push(x); + }); + + let emitter = "0x" + this.zeroBytes.slice(0, 31 * 2) + "04"; + let seconds = Math.floor(new Date().getTime() / 1000.0); + + return this.createSignedVAA( + guardianSet, + signers, + seconds, + nonce, + 1, + emitter, + seq, + 32, + b.join("") + ); + } + + genGSetFee( + signers: any, + guardianSet: number, + nonce: number, + seq: number, + amt: number + ) { + const b = [ + "0x", + this.zeroBytes.slice(0, 28 * 2), + this.encoder("uint8", this.ord("C")), + this.encoder("uint8", this.ord("o")), + this.encoder("uint8", this.ord("r")), + this.encoder("uint8", this.ord("e")), + this.encoder("uint8", 3), + this.encoder("uint16", 8), + this.encoder("uint256", Math.floor(amt)), + ]; + + let emitter = "0x" + this.zeroBytes.slice(0, 31 * 2) + "04"; + + var seconds = Math.floor(new Date().getTime() / 1000.0); + + return this.createSignedVAA( + guardianSet, + signers, + seconds, + nonce, + 1, + emitter, + seq, + 32, + b.join("") + ); + } + + genGFeePayout( + signers: any, + guardianSet: number, + nonce: number, + seq: number, + amt: number, + dest: Uint8Array + ) { + const b = [ + "0x", + this.zeroBytes.slice(0, 28 * 2), + this.encoder("uint8", this.ord("C")), + this.encoder("uint8", this.ord("o")), + this.encoder("uint8", this.ord("r")), + this.encoder("uint8", this.ord("e")), + this.encoder("uint8", 4), + this.encoder("uint16", 8), + this.encoder("uint256", Math.floor(amt)), + this.uint8ArrayToHexString(dest, false), + ]; + + let emitter = "0x" + this.zeroBytes.slice(0, 31 * 2) + "04"; + + var seconds = Math.floor(new Date().getTime() / 1000.0); + + return this.createSignedVAA( + guardianSet, + signers, + seconds, + nonce, + 1, + emitter, + seq, + 32, + b.join("") + ); + } + + getTokenEmitter(chain: number): string { + if (chain === CHAIN_ID_SOLANA) { + return "c69a1b1a65dd336bf1df6a77afb501fc25db7fc0938cb08595a9ef473265cb4f"; + } + if (chain === CHAIN_ID_ETH) { + return "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"; + } + if (chain === CHAIN_ID_TERRA) { + return "000000000000000000000000784999135aaa8a3ca5914468852fdddbddd8789d"; + } + if (chain === CHAIN_ID_BSC) { + return "0000000000000000000000000290fb167208af455bb137780163b7b7a9a10c16"; + } + if (chain === CHAIN_ID_POLYGON) { + return "0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde"; + } + if (chain === CHAIN_ID_AVAX) { + return "0000000000000000000000000e082f06ff657d94310cb8ce8b0d9a04541d8052"; + } + if (chain === CHAIN_ID_OASIS) { + return "0000000000000000000000005848c791e09901b40a9ef749f2a6735b418d7564"; + } + if (chain === CHAIN_ID_FANTOM) { + return "0000000000000000000000007C9Fc5741288cDFdD83CeB07f3ea7e22618D79D2"; + } + return ""; + } + + getNftEmitter(chain: ChainId): string { + if (chain === CHAIN_ID_SOLANA) { + return "0def15a24423e1edd1a5ab16f557b9060303ddbab8c803d2ee48f4b78a1cfd6b"; + } + if (chain === CHAIN_ID_ETH) { + return "0000000000000000000000006ffd7ede62328b3af38fcd61461bbfc52f5651fe"; + } + if (chain === CHAIN_ID_BSC) { + return "0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde"; + } + if (chain === CHAIN_ID_POLYGON) { + return "00000000000000000000000090bbd86a6fe93d3bc3ed6335935447e75fab7fcf"; + } + if (chain === CHAIN_ID_AVAX) { + return "000000000000000000000000f7b6737ca9c4e08ae573f75a97b73d7a813f5de5"; + } + if (chain === CHAIN_ID_OASIS) { + return "00000000000000000000000004952D522Ff217f40B5Ef3cbF659EcA7b952a6c1"; + } + if (chain === CHAIN_ID_FANTOM) { + return "000000000000000000000000A9c7119aBDa80d4a4E0C06C8F4d8cF5893234535"; + } + return ""; + } + + genRegisterChain( + signers: any, + guardianSet: number, + nonce: number, + seq: number, + chain: string + ) { + const b = [ + "0x", + this.zeroBytes.slice(0, (32 - 11) * 2), + this.encoder("uint8", this.ord("T")), + this.encoder("uint8", this.ord("o")), + this.encoder("uint8", this.ord("k")), + this.encoder("uint8", this.ord("e")), + this.encoder("uint8", this.ord("n")), + this.encoder("uint8", this.ord("B")), + this.encoder("uint8", this.ord("r")), + this.encoder("uint8", this.ord("i")), + this.encoder("uint8", this.ord("d")), + this.encoder("uint8", this.ord("g")), + this.encoder("uint8", this.ord("e")), + this.encoder("uint8", 1), + this.encoder("uint16", 0), + this.encoder("uint16", chain), + this.getTokenEmitter(parseInt(chain)), + ]; + let emitter = "0x" + this.zeroBytes.slice(0, 31 * 2) + "04"; + + var seconds = Math.floor(new Date().getTime() / 1000.0); + + return this.createSignedVAA( + guardianSet, + signers, + seconds, + nonce, + 1, + emitter, + seq, + 32, + b.join("") + ); + } + + genAssetMeta( + signers: any, + guardianSet: number, + nonce: number, + seq: number, + tokenAddress: string, + chain: number, + decimals: number, + symbol: string, + name: string + ) { + const b = [ + "0x", + this.encoder("uint8", 2), + this.zeroBytes.slice(0, 64 - tokenAddress.length), + tokenAddress, + this.encoder("uint16", chain), + this.encoder("uint8", decimals), + Buffer.from(symbol).toString("hex"), + this.zeroBytes.slice(0, (32 - symbol.length) * 2), + Buffer.from(name).toString("hex"), + this.zeroBytes.slice(0, (32 - name.length) * 2), + ]; + + // console.log(b.join()) + // console.log(b.join('').length) + + let emitter = "0x" + this.getTokenEmitter(chain); + let seconds = Math.floor(new Date().getTime() / 1000.0); + + return this.createSignedVAA( + guardianSet, + signers, + seconds, + nonce, + chain, + emitter, + seq, + 32, + b.join("") + ); + } + + genTransfer( signers :any, guardianSet :number, nonce:number, seq:number, amount:number, tokenAddress:string, tokenChain:number, toAddress:string, toChain:number, fee:number) { + const b = [ + "0x", + this.encoder("uint8", 1), + this.encoder("uint256", Math.floor(amount * 100000000)), + this.zeroBytes.slice(0, (64 - tokenAddress.length)), + tokenAddress, + this.encoder("uint16", tokenChain), + this.zeroBytes.slice(0, (64 - toAddress.length)), + toAddress, + this.encoder("uint16", toChain), + this.encoder("uint256", Math.floor(fee * 100000000)), + ]; + + let emitter = "0x" + this.getTokenEmitter(tokenChain); + let seconds = Math.floor(new Date().getTime() / 1000.0); + + return this.createSignedVAA( + guardianSet, + signers, + seconds, + nonce, + tokenChain, + emitter, + seq, + 32, + b.join("") + ); + } + + /** + * Create a packed and signed VAA for testing. + * See https://github.com/certusone/wormhole/blob/dev.v2/design/0001_generic_message_passing.md + * + * @param {} guardianSetIndex The guardian set index + * @param {*} signers The list of private keys for signing the VAA + * @param {*} timestamp The timestamp of VAA + * @param {*} nonce The nonce. + * @param {*} emitterChainId The emitter chain identifier + * @param {*} emitterAddress The emitter chain address, prefixed with 0x + * @param {*} sequence The sequence. + * @param {*} consistencyLevel The reported consistency level + * @param {*} payload This VAA Payload hex string, prefixed with 0x + */ + createSignedVAA( + guardianSetIndex: number, + signers: any, + timestamp: number, + nonce: number, + emitterChainId: number, + emitterAddress: string, + sequence: number, + consistencyLevel: number, + payload: string + ) { + console.log(typeof payload); + + const body = [ + this.encoder("uint32", timestamp), + this.encoder("uint32", nonce), + this.encoder("uint16", emitterChainId), + this.encoder("bytes32", emitterAddress), + this.encoder("uint64", sequence), + this.encoder("uint8", consistencyLevel), + payload.substring(2), + ]; + + const hash = web3Utils.keccak256(web3Utils.keccak256("0x" + body.join(""))); + + let signatures = ""; + + for (const i in signers) { + // eslint-disable-next-line new-cap + const ec = new elliptic.ec("secp256k1"); + const key = ec.keyFromPrivate(signers[i]); + const signature = key.sign(hash.substr(2), { canonical: true }); + + const packSig = [ + this.encoder("uint8", i), + this.zeroPadBytes(signature.r.toString(16), 32), + this.zeroPadBytes(signature.s.toString(16), 32), + this.encoder("uint8", signature.recoveryParam), + ]; + + signatures += packSig.join(""); + } + + const vm = [ + this.encoder("uint8", 1), + this.encoder("uint32", guardianSetIndex), + this.encoder("uint8", signers.length), + + signatures, + body.join(""), + ].join(""); + + return vm; + } + + zeroPadBytes(value: string, length: number) { + while (value.length < 2 * length) { + value = "0" + value; + } + return value; + } +} + +module.exports = { + TestLib, +}; diff --git a/algorand/test/tests.vaa b/algorand/test/tests.vaa new file mode 100644 index 000000000..a14b25359 --- /dev/null +++ b/algorand/test/tests.vaa @@ -0,0 +1,10 @@ +[['guardianUpgrade', + '010000000113006a0fd5b12c71afea701d8cf2bf13aed7511b6f1e239b26a28e2635fe5a68af1902f1eec1e085c754cbebdfb5262f78287e7d110d25cd4ad6504bc36e776d5f4d0001500b3dec9b3c712ea9cf40070ef8616f73966f26845894d796ef2a94a42396121192ceb8cca26c575f648d1b384e9d21689751c73295c424a93a4ac2094c57e70102752dce8a19611490b84e80606a40286cb45bbaea2a8f818a8c9c46e763528de971d45d7aabfafda92e494e120f9d478b7eeecb9c654509f0351f22645f90c83100034966869ea35c27670a4993fba23d8c3e7dc7868c956ec4f78069145e1598c5e96b29894ef82b8a7000bf7e17c6a2c125aaca5fae9c1af30e617d0a3b25e562c20004c51abb12086b1dba7cf129e463fcf4bd0d42720abfd0ac93da2bbc5335496f5a18cb952ad9688c0c91ac083e22df5a4cb55470d6bf107ef1d741698b2a6093c20105e97e64fb124345a9feb9a715b701cfbb3a828d0917f255a94e45a11bcc5ed200049a062a686f202a6e1d8cd3424c5d47d0b2cf302094eef25421ca403a68099c010677a8989bc4eefe4ca35d0944077da1a8b751cc27ac1d8075187438d38c3c7dda28fab818efdc8b9514c3b753d23f2ef58af1dcff743d22cebe4baa3fdd2ace8401072bb8f606278bd301d5c43172626d66bd475f74f5d1966f364b6e2a66e587c94c7f5ddd2710bff83337c88920b9207e1ccbb34aeaf20707bf5ede700bc2a245470008e798887c16ead032eac3a9002a306dfd3650432be1ee2023c673aaec1cde884642cb728ca67e27d10df4fb8bad8e0d1590894e2e4f2e69930c380d7476c0fcc400098bee13bd73fe668d66caea447de67a243f45832b4144070716def14f45b3c39733caa04f0f2feeab698de2b938539c6236239f9753b433a8989e33205a20ce9e010aad6dbe3e46e9bc7b49d6a9cd5efd87c4ec4f478847b197695d553b12c0354999282413948e6515039f19ed5298724ddea9a013a14de68246cc0dbf0412b7b5cd010b2f48337c8a4b09e20bede3fca7c05adfe3c9051eb24651e759daa4a20c701f8363ed7a206faf61880e50c0b2c6167b844cb4ee995750255335cc10a05bf9c75f010c5dbcca21cd3bc92b7d24c25de3ee49eadcc314df34cc2a577a3a9960c13f6317291598fd6b73aebbb24af51d916870757fd8193d8d7b2799e8cdeb0fe3d47433000de95a94e0a4b72c471c92b699fa70b25f70db10e7bac3910eaea5a2b60b7ba13a5b0328ab4d3256452b426a761a2aa919d2695f852d4a6134c733530fce9ab84e000e780ebd790827b19ec30beb6a079d530ace0a98b11378ed9b86af99d7ca1f4b0b2c789574fe59b66648196350b1165916e4067185d6ec3b0a7c715a1efe5c5265000f87d2137693af524bf9aebc735e386bf2a8f3ed383ebeb6ffe0c17652ee59d88b19ad688b0270451269217efb5a0f23047627a8ee21862a77a5bf9ca55c53cde50010eaa77d3646bd79b549ce6919266fd7a9e0f64a2faaa5d61965c1f57bbd41ea4264b1fdf4abcb4e396feccdaf4193b8691119f8b2807a020a8badfb64546ddf94011135252460395af21ada39a775a3c48feb1c2462dfea215f96b974e6c27ac1233e517201697e519ca58a79d27227ef37c1a35997f377825ab6452a2f399287b6c2011229ebc2abc2be958ca1bb0551a1ae4cd9420c17289f9885ece52309f0766034000615684bf8d3ce0d217e8060a60e1940bca6f726dc1564c1467d719a6dcf58e60062319c37000000020001000000000000000000000000000000000000000000000000000000000000000400000000000000022000000000000000000000000000000000000000000000000000000000436f7265020000000000021352a26ce40f8caa8d36155d37ef0d5d783fc614d2389a74e8ffa224aead0778c786163a7a2150768cb4459ea6482d4ae574305b239b4f2264239e7599072491bd66f63356090c11aae8114f5372abf12b51280ea1fd2b0a1c76ae29a7d54dda68860a2bfffa9aa60cff05e20e2ccaa784ee89a0a16c2057cbe42d59f8fcd86a1c5c4ba351bd251a5c5b05df6a4b07ff9d5ce1a6ed58b6e9e7d6974d1babec087ec8306b84235d7b0478c61783c50f990bfc44cfc0c8c1035110a13fe788259a4148f871b52babcb1b58a2508a20a7198e131503ce26bbe119aa8c62b28390820f04dda22afe03be1c3bb10f4ba6cf94a01fd6e97387c34a1f36de0f8341e9d409e06ec45b255a41fc2792209cb998a8287204d40996df9e54ba663b12dd23fbf4fbac618be140727986b3bbd079040e577ac50486d0f6930e160a5c75fd1203c63580d2f00309a9a85effaf02564fc183c0183a963869795913d3b6dbf3b24a1c7654672c69a23c351c0cc52d7673c52de99785741344662f5b2308a0'], + ['registerChain', + '01000000021300d655215e841c8402dd5a5a59cde64d1cdcf4d630794a950572154c419445bd6b0b55a2867128dbdb07a8af7023586c07ee4c2343b436fd4a7bae4c00175eee89010139205169195a576f34f840f5efec49a0c8cfcb15889b8fa7612260444bef8bdc0fd274edfc7c6a3ae9d3f0f560fe39dee3cb2cef578c4acde75d4524c9569c52010204242bf606b8ebd8bba252e9e37e0f3352c044367f8f58c681164cbd024563e604f7836a59e04713c3c351540eb84514bee8983aac088b565bdeb1588facbf240103f334f37f6054f6b35e10531377f9b60dd0ed8153333fd1ac1577ca7f9f849c092c78f980d474947227fc543ea4b8e0a0156dce70024ae123852b6569a972bc3f0004190eaa4d1d635d74563163061a7febab0f560ea5ef772e9b499abbcc8198641e152b9872e395667c3469457ea7b13474597f571a8dd43198ebf924c4d81f6860000590106ff897e2808d3e6591a2939f597855cb8b9edf9b6cf01c571d06d1015bcd43dcc26384167c09ba110a414fc0a37137bcbf8378b7da55e58c86eec2425e9e0106c6658a3ecb9355b4e4699316918903f2b51ea36c5e9eec7d2243c930b16885056e4c9b60bef18c8f311abfac9b4993ca5a5a5563ef70d8ed4643e8a0294a7cee010726d4b97eb4280a87028fb4246ac91e2278045ce9727ac960b45aa0f2f125efe72f8ecc3d5378cb5974575d1ee292595bbcac71237fe25d194bf28ee64a6ed6d30108dc8377d7ae5f922a004f85124f63afc4559a8b29446612e09bb4e22d3e8e1603286d2264aee4745803da7010505c243523593045d0b814cbfbb7a703d92c2aaf000927757c0421497409138a184ba6405fcf669abee706f2d6dce525460f9926f1e0234d420062e95d69e72253898ec7a9bd54a31b09a67a5e6a3080da419102229e010af7b9de76c6be33ac09227a8067b4e82fcae95f1919f4ed8f902b1a735cc3ebc27e217e96c76662b9d5cd614f0cf78b283e5088ecfb939c7556601bcfecf6a6c3000b1574118db342f783559846872ec5f99347b959ab39c934ab40f4285320243de351e2cf6edf7596249cb4a33a2132200f48ee351a9c4d3ab2cedc052994d8702b010cf6944222b35d390b71a6eb09bc96ccac5cef9e7dcae7604e8db11cb050c59f3514acfb6ec06fce2814c8d7509cd24d4225c2cb0666ea879ddabc86e8946d84d6010d5cccc13fa483890fb5ac0d2929d105d7f8c7aa0f9d8c4ef2e7fed502ae02505f1553d7be46ea8c86aa1ecd6106d48cf3b0e38465dc47af137f72d302c71fb623000e44bf3f46476f30e240468592f23877774b775e16d1182e5df6aea08301f716283b8517673e2a295170dc3810b50831d29617c440aff68702e0d94a95d22dee3a010f95b05c152c60079b1b056638ab61a26452b04d44dacd0bba36d7c65a462b27720f97bb310303e320ef75ab043dd80a2fb1e4869f16689665bf076dcf754be84501105c6a4901e6ead756e6a796d6209cf830fe90acf186aa792297f75b751d13accf4004351ec3d6e49ea795be260112be51cf050a49b4213fb4467ba6e5bd8e4ce10011ab3b325b996897ab7fa7231c5eb8f04533fc1acec6429ad2cbd66a1c8e5b916f1775371411be693eb1fef8a89ec60086ca600a7fff8ffe3fc328aba62e84caaa0012f672dda335d096b2a873ce05c9b6b0759282475900678efc7b3b36a5d3fa3cab7fd4165345f61753376f039aa9207ab263786831d82206bf00f7bbb78b7c3fe80162319c3a0000000400010000000000000000000000000000000000000000000000000000000000000004000000000000000420000000000000000000000000000000000000000000546f6b656e42726964676501000000020000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585'], + ['createWrappedOnAlgorand', + '010000000213001169470caf4d5f7a27049c1852e6429c0fa7db56584e1514b8cc3d7242b7710f5d15600562f068cd5bb0d515bd038929b62f14396730d06e99c6a7e14025a62900015157522a094c006c8ceb4b2a8b6e5bfaa613663f34d9ce534d4e4b5f581c720b21eb96062324eac0e9b28cf526698cc70b013436f6341312bc3dc2cd2c5e3b6f0102f1c5fcf6b6df200dbaedb7a923b244fd4563ce727b17d39f27c7fd3b9fb5c76e27f827779e47c98c0fb82bb59c40009d94afc68cec2066e6765292d5274399e20003bd48cbcf25a2ae733077f719f48812dcb5db45551308f98281839f9d1b5ebb2728ad199925b5451a2ac90caaf19eb9f8dbf83880cddd4380ccbd7556f3776beb010460d01f541b5c8664e8163db5ff67e553115a5adbe977e896e00bfe558f15e75771eb6e334827f42738120ff474597770b1dd843ae7bae96e2ebc2b2f111ff3850005577275e235cdc0e95e08b3efa44fd8085551b6f7b59aa0f7f091bf7002bcb9480d6be6196bac66f270a1018a5388b8174548a425c624bb65f06b0a0b2f41ba5c01064e9637c161de6e8588fe50022f4da14726733be790b84cce174a80e5142e17a6266381aa2b84fa3df7608430a5ba27aa188b2d389cbd0c73a4b64593d37bccc50007b70a66f4663afae8759c3639d8213e5094db416404b8058b32d10b42521b458b13d19e7ae8f5a4b9be2c47215d12037c74d5501bc5e1b1c5fa62957f8717e9d00108136ef73c58764c22391a8410e9811dd8a978f52b73c2564938357aab095e476761118053a09e0cad08735629360528ef4362823e1956833bcd8eda5482a03df801097ccf894c000cbc28587ab52627a7b8d05c2dc5434cda6f5cd55ae58e979cfb6e01303ad8ac1697dec213a5fbfeec6e77d483d09ee747a9de32618ea9dfc9a5f7010a1cc64605a4de382441c60a889d5a74f77b3328d9d8cd9e5b02ec69597f87cb60085f1cc6e4ffdb48f125c375c00d7e7d93804e9ea6b589f5a9e92bed9dfdca14000b9330b10a041438d52ccfe3b64bf4fd3a5ea5686b755f356d26d954e86b4384a1523b6e469fc61880324a0774650a5eb6502d677c11457a37674cca0cda76f688000cf1c276efcf8662bd0d59d1ca33ebe08121c76e31b0d74620bce9102ae02a078b4a52f8d626a71c4e5ce43b6524424594d8d0c70eb7cc01cc7ea734e48e85797d010d5a2617b7894ac14e15df109101e2779f6dc6027820613e2f4501a26ca850684a05785d7e02372a8184821cfc23d22ddec4631f2574d1338cafb963a58e1503dc010e674380d092aa52e8f6e237cba930551d9d7493427f9958e59d32eb796ab76a2140ca698e78a7198399935a5a73d5c8e363087f3f8f49722b237e455a15554af3000fcb79ea3c70a75238f841f7c539bfb3ab8c00b539ed9f72b92b26b0edcaf6211a298812b07e52fb9a3a4d1c52aec35453a9c65e48be569b4e6533a22c7d679060011004d7b9d453ddb5834bfb60564d673a1ed2b51aad9db321d72ab3e1089df778467bab44624e4aa2916585cfad0f42ba03b146a57cc40f61a2ea4862a700b7945c0011257311c376bab7646f83a81b85cc3e18545e5a980eef0d8e6a217861bdb34b18342148527c9018811a46a8e2eb38cb8ab25c66dd4d4a817cc031ff163d4f32eb0112d071f99d8b4cf54b034b2276ab76fd324965f9b9a35efc56109b99e637948c024c97988497b61d169eee4f27b649d6dbdc770452be51bc01315ce3f831c9ff000162319c3c000000080001ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5000000000000000820020000000000000000000000004523c3f29447d1f32aea95bebd00383c4640f1b40001085553444300000000000000000000000000000000000000000000000000000000436972636c65436f696e00000000000000000000000000000000000000000000'], + ['redeemOnAlgorand', + '01000000011300d3f66cd953524cd3dd33396bdd24a6e5deb3df3c0404be778b4b939579212e1c66f479a85a3a00c812c775e58ca34878931d955d1939877e2a5e3c4419cd11960101c47a513100d6540304c245f310b6832eaf2477afce3bf2909ea5447732e6bcb651746141998c1de50306ee94eb65b711888c65a43a42528cee0be005151716360002c124c4012062c9b1cbf5f31ca551f50c553f7a97bbd0b1a50fe9e5d5589a7f101ca550bda30503b1b3bb4c092ef9a605ddfc0be08c3634c4b292399a54d63e4200032263333ae6daa49f05ec9deca9122755c9206bd72dfdac3d9c8dcdfb2db284b0265c77f9ee1b1c00e4f298869b1c492bff805045c0d0eef8fc3c0fdfbb82f01b0104a40415447bfadfffaf7d9bca8492dfc7c94dcc15e7ae3cc4f20cb34531ed17977e7711284010d71c868b69a87547b6faa09685aff8048cfc6fffc839d0be0b6a0105dfc1b0de5216abb57b524ce51f336060c3d1625ed28b55c5cd5cf1632c38f9c062f168f3d0f0838daf9c13a4ef48a8c159207045c3cb8e43d4a76baf591223c2000686180a55def6a45e8ea71595df89a69583c671a83e9e89bc5b73c55ed88c49fc5e32c47b8abdf1552bfc311d2dac988811f40c74eef3eb9437cf35b52d30239a0007b082d16d31d8e06d8ad494834b18d3b3d316a399b4d36bfb426e5b60ff81fd2e632da3466d2fa68fc0ec7bb0964cf969cd125966873ce52a1e846d4d8f0495440108487ff6b4956cea68fc8aa225ce47f93a15477f66db4362d0602d62a5b790428578253062d34b8c61665a6637572b095da9037025f426274f3ef40e7ecc493b5b0009b39dbed5560d5de7075fb43496e52b061313c6eb591ece2cde513de818881c30672e4fc180f6e3fbabf6a94813adb0d66a99b38ee27dfc71ad3fc4058c3c976e000a0bfd12ece2d2c845dc13293380784695e98e8ae598c3053426baaf65c9c962960271c8a69e52458f385be5617dde1b571d341a82112fe9aef1468140faebca00000bc0a81d0a8e9278011a0a4e0257401f35bcec9d98222ae2e9f44a39b6899d54551482f68c89040b60315a806c1f7cf18cb65bed3e18c8cf1059999e5107e720f2000c1939897f4dc63ec9ef38844ceb665caabab1f758a8543feff43b4bdd151dc6a56b93ff56d25fc4c0fe0c78d01df793fb4e3bdc2dea55f18694a40bc43dadc654010d1f41f8d5067eccdbf047180de85521ed3bbffd91ec2f157833e9514444d39e8c65c9f9897dcefc5e44469b080021e1715d85688369d24ae89b4858eaf2c89faf000e3310037efb7a37917725a6575f471427686d56e641bd4aa21394f8202f3f52db2f45fcb718ab4550a468bceed0c13ee8040c0da173caf87a7a5c1908f7270811000f6673460a92bce84565571f2b398f1692eb393adbf47b70bc60ca7755208aaf771010726fd66f2953a33fb472dbdcd91fb78b2993b279050d2d15b3b37c347c6e01108421b71f1568cf2f12d25bfbf2755561772c661a6f2cdeae02bbe8204fa8a53632536c4e580af27551a3304f2c87bff489b516e1d9570c1e203c8e0eea8c86520011186b2e2f0a42f554c604679085aeb7226ec2a9807d867ce51f40af5d58ce6a433981cd00f843b5223ebd764026c8a729c32ae92013dd27a8bed271d85a09733600127765a06677c2a9b060e15b361917eeefda093f3951fef93cb9787b05230dad9207635fee6f987a50202cbe3613da1f1e9c51ef09b885004d763da72403a231bd0062319c3e000000010001ec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5000000000000000120010000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000004523c3f29447d1f32aea95bebd00383c4640f1b40001e6b2b620e5c346848e30a40310ef30a359b466148ab5c04f96e024e40de143ac00080000000000000000000000000000000000000000000000000000000000000000'], + ['transferFromAlgorand', + '01000000011300aec87f926f0d7bbe5c37dd580f5e94e7aa9ee8837741ce9a2964efae9f977dac79492e7ed5f84d489aa6d1f3d752c9febaf846589927d1dbe8cd69e7d01e9d44010156195e8b1383bf1d76e5c715f27caa7a6d29cf2aaf10c67eae3ecb855be013f500981e56c346c2122ff2a0a274745093adc6e263ca8b220649fdaedd041be47a0102aeb73afa6c75122d52666da208b1b29221ff5f894da8fd11f9d8ab9c9fee9f6e238231f4a48200637d29fe70b327f7b6cc536d326635d944e80aca84aaf2908000035612a27bb95f0e280502ea7d4631afd2b24d41428f22f58bcd5ba9477be4de8536ab20b4bad90f3f95f3303a1c116ca78c4cce9478c2769aaad74c04b53f17f40104b1fc79501049806997bc793694601566f5d56c3abf5ea3126b0c1c24a97e9e8e592ed505de471ad372f679beee35a5e467144627d72343834c5f96b1afa1b9b400050af609532bb0ea524a35a76c4a46dea2d6a31c545bbba705d99b42259acb77d90f19e2866d7dc12468691988291c154e900fc90d7b6f666ff9f63a66d163331100063bec6164adc6529b2f5d02c9a0da90d3656d4d9bb7a6f9b31f2c00e914d2001f3724cab7fb6a914ee2de2ef622c129e0ccf7a9d9784b6a70deff5cdb0c6bc8a50107179150acf55b02e0a12e484c8f274e411d82333428dfe06440ec7cf51373fc6f2fc5241225c06c8c3ad662ca236e07ce06fc4988c1e2620dcd07e977d3c872480008e476380cdcc35d61881e372f1b6643a8aaa577fdbfc253626997e38773185bf50ae33a4c6127b77369670718fa473a52d6b593e3cb3af479c451bdfeefcf2bd30009674551361eaaff891d590ca699d5b03504d866fe91a8118bb1681e0759edbfca1f2b358398d4d46e6916d9378bcab01e7ff21fd770e63222b2ef6a98c262d83e010a8ad0bc1d8eb89b4a8d7b119d62d737202895e3d80a0ca7367a21bd6587cc6aba0cdb19c089b03d622a1ad6a939ee285f78c3f52e87a81fa51d0fea7238280aba010b13857b3845216d66fe84985bd8d5a16b2440ea0a3e5afc43c19c802fe7c360dd5534c1df47e8ba0c5b4166e13becf5454ac3567fdbdcadcaf625d46ae7a188d7010c70e3859ea2d4c05769bfb72649f0266eef24e310558a7136d931161cafea91674cc3ded48c6715f3326e365ad862444cb867688b834ac12bf0b651d81764951e010dd03c3f06009a37a2c716259c1e86793a5bd9b9bab9cc3d2cc2983a766e87aeb275a9a9a047d81b57bb2b9b747138c391b77768a639b284e662ae5c15504d48a1000e9ccfade4aea4f1d5e1e053a32d1a93c39e855044a09cfd41f974f61986e42ab21d103c1c2c82a1cff1d2f0f79ad64ad8c214f88c1a84518bc6ad3656f827c6f0010f09ed95a03909d4a40041676a7f460c35ea7b9464a855a3aa1df9e2b4841e5ec42b08ca2c1f9997274b9f07120180e8d5b8eeceada584c79cbfc39d983b6dfaba00101c48e160de738770847abef02cdd0a3594dbc80de68403004f987e7676f954df2aa24e5280f5ecf5a61f865af1185220a805a64211b732e3672071801f75a86901117004184bcfa26f19efed445980f65e2450101bf20bb70d36c66e244bc10c1ff33aee94550a5af547e346ffd913335b33b374776b81d408b54dad046a18afcc9f0112420f47b6b5bd0c4b5c5e5c8db36e490c8d250e1e2087a7b43b63fac0f7f6bc6f28593877c492e27c560e39afcd8aa99847feb0193759be61fae2e8130a8993150062319c42002f37460008a8f52a34e2b19ac916d3cc27d3b07bfbfb03f31e0075a2a85ffe99be89d3887c00000000000000032001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000006150008f888ac4b7756ad193876ff85decf58eaa82f5094d528d7cd9b3119737b1e8d2700080000000000000000000000000000000000000000000000000000000000000000']] diff --git a/algorand/testnet-update b/algorand/testnet-update new file mode 100755 index 000000000..30a3ed0c4 --- /dev/null +++ b/algorand/testnet-update @@ -0,0 +1,10 @@ +#!/bin/bash -f +set -x + +#./sandbox down; ./sandbox clean; ./sandbox up dev; python3 admin.py --devnet --boot + +python3 admin.py --testnet --genTeal --upgradeVAA --submit --mnemonic="$1" +python3 admin.py --testnet --updateCore --mnemonic="$1" +python3 admin.py --testnet --updateToken --mnemonic="$1" + +# python3 admin.py --devnet --upgradeVAA --submit --updateToken diff --git a/algorand/token_bridge.py b/algorand/token_bridge.py new file mode 100644 index 000000000..8d5e2bd29 --- /dev/null +++ b/algorand/token_bridge.py @@ -0,0 +1,1033 @@ +#!/usr/bin/python3 +""" +Copyright 2022 Wormhole Project Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); + +you may not use this file except in compliance with the License. + +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""" +from typing import List, Tuple, Dict, Any, Optional, Union + +from pyteal.ast import * +from pyteal.types import * +from pyteal.compiler import * +from pyteal.ir import * +from globals import * +from inlineasm import * + +from algosdk.v2client.algod import AlgodClient + +from TmplSig import TmplSig +from local_blob import LocalBlob + +import pprint +import sys + +max_keys = 15 +max_bytes_per_key = 127 +bits_per_byte = 8 + +bits_per_key = max_bytes_per_key * bits_per_byte +max_bytes = max_bytes_per_key * max_keys +max_bits = bits_per_byte * max_bytes + +def fullyCompileContract(genTeal, client: AlgodClient, contract: Expr, name) -> bytes: + teal = compileTeal(contract, mode=Mode.Application, version=6, assembleConstants=True, optimize=OptimizeOptions(scratch_slots=True)) + + if genTeal: + with open(name, "w") as f: + print("Writing " + name) + f.write(teal) + else: + with open(name, "r") as f: + print("Reading " + name) + teal = f.read() + + response = client.compile(teal) + return response + +def clear_token_bridge(): + return Int(1) + +def approve_token_bridge(seed_amt: int, tmpl_sig: TmplSig, devMode: bool): + blob = LocalBlob() + tidx = ScratchVar() + mfee = ScratchVar() + + def MagicAssert(a) -> Expr: + if devMode: + from inspect import currentframe + return Assert(And(a, Int(currentframe().f_back.f_lineno))) + else: + return Assert(a) + + @Subroutine(TealType.uint64) + def governanceSet() -> Expr: + maybe = App.globalGetEx(App.globalGet(Bytes("coreid")), Bytes("currentGuardianSetIndex")) + return Seq(maybe, MagicAssert(maybe.hasValue()), maybe.value()) + + @Subroutine(TealType.uint64) + def getMessageFee() -> Expr: + maybe = App.globalGetEx(App.globalGet(Bytes("coreid")), Bytes("MessageFee")) + return Seq(maybe, MagicAssert(maybe.hasValue()), maybe.value()) + + @Subroutine(TealType.bytes) + def getNextAddress() -> Expr: + maybe = AppParam.address(Gtxn[Txn.group_index() + Int(1)].application_id()) + return Seq(maybe, MagicAssert(maybe.hasValue()), maybe.value()) + + def assert_common_checks(e) -> Expr: + return MagicAssert(And( + e.rekey_to() == Global.zero_address(), + e.close_remainder_to() == Global.zero_address(), + e.asset_close_to() == Global.zero_address() + )) + + @Subroutine(TealType.none) + def checkFeePmt(off : Expr): + return Seq([ + If(mfee.load() > Int(0), Seq([ + tidx.store(Txn.group_index() - off), + MagicAssert(And( + Gtxn[tidx.load()].type_enum() == TxnType.Payment, + Gtxn[tidx.load()].sender() == Txn.sender(), + Gtxn[tidx.load()].receiver() == Global.current_application_address(), + Gtxn[tidx.load()].amount() >= mfee.load() + )), + assert_common_checks(Gtxn[tidx.load()]) + ])) + ]) + + @Subroutine(TealType.none) + def sendMfee(): + return Seq([ + If (mfee.load() > Int(0), Seq([ + InnerTxnBuilder.SetFields( + { + TxnField.type_enum: TxnType.Payment, + TxnField.receiver: App.globalGet(Bytes("coreAddr")), + TxnField.amount: mfee.load(), + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Next(), + ])), + ]) + + @Subroutine(TealType.bytes) + def encode_uvarint(val: Expr, b: Expr): + buff = ScratchVar() + return Seq( + buff.store(b), + Concat( + buff.load(), + If( + val >= Int(128), + encode_uvarint( + val >> Int(7), + Extract(Itob((val & Int(255)) | Int(128)), Int(7), Int(1)), + ), + Extract(Itob(val & Int(255)), Int(7), Int(1)), + ), + ), + ) + + @Subroutine(TealType.bytes) + def trim_bytes(str: Expr): + len = ScratchVar() + off = ScratchVar() + zero = ScratchVar() + r = ScratchVar() + + return Seq([ + r.store(str), + + len.store(Len(r.load())), + zero.store(BytesZero(Int(1))), + off.store(Int(0)), + + While(off.load() < len.load()).Do(Seq([ + If(Extract(r.load(), off.load(), Int(1)) == zero.load()).Then(Seq([ + r.store(Extract(r.load(), Int(0), off.load())), + off.store(len.load()) + ])), + off.store(off.load() + Int(1)) + ])), + r.load() + ]) + + @Subroutine(TealType.uint64) + def getFactor(dec: Expr): + return Cond( + [dec == Int(9), Int(10)], + [dec == Int(10), Int(100)], + [dec == Int(11), Int(1000)], + [dec == Int(12), Int(10000)], + [dec == Int(13), Int(100000)], + [dec == Int(14), Int(1000000)], + [dec == Int(15), Int(10000000)], + [dec == Int(16), Int(100000000)], + [dec > Int(16), Seq(Reject(), Int(1))], + [dec < Int(9), Int(1)] + ) + + @Subroutine(TealType.bytes) + def get_sig_address(acct_seq_start: Expr, emitter: Expr): + # We could iterate over N items and encode them for a more general interface + # but we inline them directly here + + return Sha512_256( + Concat( + Bytes("Program"), + # ADDR_IDX aka sequence start + tmpl_sig.get_bytecode_chunk(0), + encode_uvarint(acct_seq_start, Bytes("")), + + # EMMITTER_ID + tmpl_sig.get_bytecode_chunk(1), + encode_uvarint(Len(emitter), Bytes("")), + emitter, + + # APP_ID + tmpl_sig.get_bytecode_chunk(2), + encode_uvarint(Global.current_application_id(), Bytes("")), + + # TMPL_APP_ADDRESS + tmpl_sig.get_bytecode_chunk(3), + encode_uvarint(Len(Global.current_application_address()), Bytes("")), + Global.current_application_address(), + + tmpl_sig.get_bytecode_chunk(4), + ) + ) + + def governance(): + off = ScratchVar() + a = ScratchVar() + targetChain = ScratchVar() + chain = ScratchVar() + emitter = ScratchVar() + set = ScratchVar() + idx = ScratchVar() + verifyIdx = ScratchVar() + + verifyVAA = Gtxn[verifyIdx.load()] + + + return Seq([ + checkForDuplicate(), + + # All governance must be done with the most recent guardian set... + set.store(governanceSet()), + idx.store(Extract(Txn.application_args[1], Int(1), Int(4))), + MagicAssert(Btoi(idx.load()) == set.load()), + + # The offset of the chain + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(14)), + + verifyIdx.store(Txn.group_index() - Int(1)), + + MagicAssert(And( + # Did verifyVAA pass? + verifyVAA.type_enum() == TxnType.ApplicationCall, + verifyVAA.application_id() == App.globalGet(Bytes("coreid")), + verifyVAA.application_args[0] == Bytes("verifyVAA"), + verifyVAA.sender() == Txn.sender(), + + # Lets see if the vaa we are about to process was actually verified by the core + verifyVAA.application_args[1] == Txn.application_args[1], + + # We all opted into the same accounts? + verifyVAA.accounts[0] == Txn.accounts[0], + verifyVAA.accounts[1] == Txn.accounts[1], + verifyVAA.accounts[2] == Txn.accounts[2], + + # Better be the right emitters + Extract(Txn.application_args[1], off.load(), Int(2)) == Bytes("base16", "0001"), + Extract(Txn.application_args[1], off.load() + Int(2), Int(32)) == Concat(BytesZero(Int(31)), Bytes("base16", "04")), + )), + + assert_common_checks(verifyVAA), + assert_common_checks(Txn), + + # correct module? + MagicAssert(Extract(Txn.application_args[1], off.load() + Int(43), Int(32)) == Concat(BytesZero(Int(21)), Bytes("base16", "546f6b656e427269646765"))), + a.store(Btoi(Extract(Txn.application_args[1], off.load() + Int(75), Int(1)))), + off.store(off.load() + Int(76)), + + Cond( + [a.load() == Int(1), Seq([ + targetChain.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(2)))), + + MagicAssert(Or((targetChain.load() == Int(0)), (targetChain.load() == Int(8)))), + + chain.store(Extract(Txn.application_args[1], off.load() + Int(2), Int(2))), + emitter.store(Extract(Txn.application_args[1], off.load() + Int(4), Int(32))), + + # Can I only register once? Rumor says yes + MagicAssert(App.globalGet(Concat(Bytes("Chain"), chain.load())) == Int(0)), + + App.globalPut(Concat(Bytes("Chain"), chain.load()), emitter.load()), + ])], + [a.load() == Int(2), Seq([ + MagicAssert(Extract(Txn.application_args[1], off.load(), Int(2)) == Bytes("base16", "0008")), + App.globalPut(Bytes("validUpdateApproveHash"), Extract(Txn.application_args[1], off.load() + Int(2), Int(32))) + ])] + ), + + Approve() + ]) + + def receiveAttest(): + me = Global.current_application_address() + off = ScratchVar() + + Address = ScratchVar() + Chain = ScratchVar() + FromChain = ScratchVar() + Decimals = ScratchVar() + Symbol = ScratchVar() + Name = ScratchVar() + + asset = ScratchVar() + buf = ScratchVar() + c = ScratchVar() + a = ScratchVar() + + return Seq([ + checkForDuplicate(), + + tidx.store(Txn.group_index() - Int(4)), + MagicAssert(And( + # Lets see if the vaa we are about to process was actually verified by the core + Gtxn[tidx.load()].type_enum() == TxnType.ApplicationCall, + Gtxn[tidx.load()].application_id() == App.globalGet(Bytes("coreid")), + Gtxn[tidx.load()].application_args[0] == Bytes("verifyVAA"), + Gtxn[tidx.load()].sender() == Txn.sender(), + + # we are all taking about the same vaa? + Gtxn[tidx.load()].application_args[1] == Txn.application_args[1], + + # We all opted into the same accounts? + Gtxn[tidx.load()].accounts[0] == Txn.accounts[0], + Gtxn[tidx.load()].accounts[1] == Txn.accounts[1], + Gtxn[tidx.load()].accounts[2] == Txn.accounts[2], + )), + assert_common_checks(Gtxn[tidx.load()]), + + tidx.store(Txn.group_index() - Int(3)), + MagicAssert(And( + # Did the user pay the lsig to attest a new product? + Gtxn[tidx.load()].type_enum() == TxnType.Payment, + Gtxn[tidx.load()].amount() >= Int(100000), + Gtxn[tidx.load()].sender() == Txn.sender(), + Gtxn[tidx.load()].receiver() == Txn.accounts[3], + )), + assert_common_checks(Gtxn[tidx.load()]), + + tidx.store(Txn.group_index() - Int(2)), + MagicAssert(And( + # We had to buy some extra CPU + Gtxn[tidx.load()].type_enum() == TxnType.ApplicationCall, + Gtxn[tidx.load()].application_id() == Global.current_application_id(), + Gtxn[tidx.load()].application_args[0] == Bytes("nop"), + Gtxn[tidx.load()].sender() == Txn.sender(), + )), + assert_common_checks(Gtxn[tidx.load()]), + + tidx.store(Txn.group_index() - Int(1)), + MagicAssert(And( + Gtxn[tidx.load()].type_enum() == TxnType.ApplicationCall, + Gtxn[tidx.load()].application_id() == Global.current_application_id(), + Gtxn[tidx.load()].application_args[0] == Bytes("nop"), + Gtxn[tidx.load()].sender() == Txn.sender(), + + (Global.group_size() - Int(1)) == Txn.group_index() # This should be the last entry... + )), + assert_common_checks(Gtxn[tidx.load()]), + + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(6) + Int(8)), # The offset of the chain + Chain.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(2)))), + + # Make sure that the emitter on the sending chain is correct for the token bridge + MagicAssert(App.globalGet(Concat(Bytes("Chain"), Extract(Txn.application_args[1], off.load(), Int(2)))) + == Extract(Txn.application_args[1], off.load() + Int(2), Int(32))), + + off.store(off.load()+Int(43)), + + MagicAssert(Int(2) == Btoi(Extract(Txn.application_args[1], off.load(), Int(1)))), + Address.store( Extract(Txn.application_args[1], off.load() + Int(1), Int(32))), + + FromChain.store( Btoi(Extract(Txn.application_args[1], off.load() + Int(33), Int(2)))), + Decimals.store( Btoi(Extract(Txn.application_args[1], off.load() + Int(35), Int(1)))), + Symbol.store( Extract(Txn.application_args[1], off.load() + Int(36), Int(32))), + Name.store( Extract(Txn.application_args[1], off.load() + Int(68), Int(32))), + + # Lets trim this... seems these are limited to 7 characters + Symbol.store(trim_bytes(Symbol.load())), + If (Len(Symbol.load()) > Int(7), Symbol.store(Extract(Symbol.load(), Int(0), Int(7)))), + Name.store(trim_bytes(Name.load())), + + # Due to constrains on some supported chains, all token + # amounts passed through the token bridge are truncated to + # a maximum of 8 decimals. + # + # Any chains implementation must make sure that of any + # token only ever MaxUint64 units (post-shifting) are + # bridged into the wormhole network at any given time (all + # target chains combined), even tough the slot is 32 bytes + # long (theoretically fitting uint256). + If(Decimals.load() > Int(8), Decimals.store(Int(8))), + + # This confirms the user gave us access to the correct memory for this asset.. + MagicAssert(Txn.accounts[3] == get_sig_address(FromChain.load(), Address.load())), + + # Lets see if we've seen this asset before + asset.store(blob.read(Int(3), Int(0), Int(8))), + + # The # offset to the digest + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(6)), + + # New asset + If(asset.load() == Itob(Int(0))).Then(Seq([ + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Txn.accounts[3], + TxnField.type_enum: TxnType.AssetConfig, + TxnField.config_asset_name: Name.load(), + TxnField.config_asset_unit_name: Symbol.load(), + TxnField.config_asset_total: Int(18446744073709551614), + TxnField.config_asset_decimals: Decimals.load(), + TxnField.config_asset_manager: me, + TxnField.config_asset_reserve: me, + + # We cannot freeze or clawback assets... per the spirit of + TxnField.config_asset_freeze: Global.zero_address(), + TxnField.config_asset_clawback: Global.zero_address(), + + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + + asset.store(Itob(InnerTxn.created_asset_id())), + Pop(blob.write(Int(3), Int(0), asset.load())), + blob.meta(Int(3), Bytes("asset")) + ])), + + # We save away the entire digest that created this asset in case we ever need to reproduce it while sending this + # coin to another chain + + buf.store(Txn.application_args[1]), + Pop(blob.write(Int(3), Int(8), Extract(buf.load(), off.load(), Len(buf.load()) - off.load()))), + + Approve() + ]) + + def completeTransfer(): + me = Global.current_application_address() + off = ScratchVar() + + Chain = ScratchVar() + Emitter = ScratchVar() + + Amount = ScratchVar() + Origin = ScratchVar() + OriginChain = ScratchVar() + Destination = ScratchVar() + DestChain = ScratchVar() + Fee = ScratchVar() + asset = ScratchVar() + + factor = ScratchVar() + d = ScratchVar() + zb = ScratchVar() + action = ScratchVar() + + return Seq([ + checkForDuplicate(), + + zb.store(BytesZero(Int(32))), + + tidx.store(Txn.group_index() - Int(1)), + + MagicAssert(And( + # Lets see if the vaa we are about to process was actually verified by the core + Gtxn[tidx.load()].type_enum() == TxnType.ApplicationCall, + Gtxn[tidx.load()].application_id() == App.globalGet(Bytes("coreid")), + Gtxn[tidx.load()].application_args[0] == Bytes("verifyVAA"), + Gtxn[tidx.load()].sender() == Txn.sender(), + + # Lets see if the vaa we are about to process was actually verified by the core + Gtxn[tidx.load()].application_args[1] == Txn.application_args[1], + + # We all opted into the same accounts? + Gtxn[tidx.load()].accounts[0] == Txn.accounts[0], + Gtxn[tidx.load()].accounts[1] == Txn.accounts[1], + Gtxn[tidx.load()].accounts[2] == Txn.accounts[2] + )), + assert_common_checks(Gtxn[tidx.load()]), + assert_common_checks(Txn), + + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(6) + Int(8)), # The offset of the chain + + Chain.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(2)))), + Emitter.store(Extract(Txn.application_args[1], off.load() + Int(2), Int(32))), + + # We coming from the correct emitter on the sending chain for the token bridge + # ... This is 90% of the security... + If(Chain.load() == Int(8), + MagicAssert(Global.current_application_address() == Emitter.load()), # This came from us? + MagicAssert(App.globalGet(Concat(Bytes("Chain"), Extract(Txn.application_args[1], off.load(), Int(2)))) == Emitter.load())), + + off.store(off.load()+Int(43)), + + # This is a transfer message... right? + action.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(1)))), + + MagicAssert(Or(action.load() == Int(1), action.load() == Int(3))), + + MagicAssert(Extract(Txn.application_args[1], off.load() + Int(1), Int(24)) == Extract(zb.load(), Int(0), Int(24))), + Amount.store( Btoi(Extract(Txn.application_args[1], off.load() + Int(25), Int(8)))), # uint256 + + Origin.store( Extract(Txn.application_args[1], off.load() + Int(33), Int(32))), + OriginChain.store( Btoi(Extract(Txn.application_args[1], off.load() + Int(65), Int(2)))), + Destination.store( Extract(Txn.application_args[1], off.load() + Int(67), Int(32))), + DestChain.store( Btoi(Extract(Txn.application_args[1], off.load() + Int(99), Int(2)))), + + MagicAssert(Extract(Txn.application_args[1], off.load() + Int(101),Int(24)) == Extract(zb.load(), Int(0), Int(24))), + Fee.store( Btoi(Extract(Txn.application_args[1], off.load() + Int(125),Int(8)))), # uint256 + + # This directed at us? + MagicAssert(DestChain.load() == Int(8)), + + MagicAssert(Fee.load() <= Amount.load()), + + If (action.load() == Int(3), Seq([ + tidx.store(Txn.group_index() + Int(1)), + MagicAssert(And( + Gtxn[tidx.load()].type_enum() == TxnType.ApplicationCall, + Gtxn[tidx.load()].application_args[0] == Txn.application_args[0], + Gtxn[tidx.load()].application_args[1] == Txn.application_args[1] + )), + MagicAssert(getNextAddress() == Destination.load()) + ])), + + If(OriginChain.load() == Int(8), + Seq([ + asset.store(Btoi(Extract(Origin.load(), Int(24), Int(8)))), + MagicAssert(Txn.accounts[3] == get_sig_address(asset.load(), Bytes("native"))), + # Now, the horrible part... we have to scale the amount back out to compensate for the "dedusting" + # when this was sent... + + If(asset.load() == Int(0), + Seq([ + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Txn.accounts[3], + TxnField.type_enum: TxnType.Payment, + TxnField.receiver: Destination.load(), + TxnField.amount: Amount.load(), + TxnField.fee: Int(0), + } + ), + If(Fee.load() > Int(0), Seq([ + InnerTxnBuilder.Next(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Txn.accounts[3], + TxnField.type_enum: TxnType.Payment, + TxnField.receiver: Txn.sender(), + TxnField.amount: Fee.load(), + TxnField.fee: Int(0), + } + ), + ])), + InnerTxnBuilder.Submit(), + + Approve() + ]), # End of special case for algo + Seq([ # Start of handling code for algorand tokens + factor.store(getFactor(Btoi(extract_decimal(asset.load())))), + If(factor.load() != Int(1), + Seq([ + Amount.store(Amount.load() * factor.load()), + Fee.store(Fee.load() * factor.load()) + ]) + ), # If(factor.load() != Int(1), + ]) # End of handling code for algorand tokens + ), # If(asset.load() == Int(0), + ]), # If(OriginChain.load() == Int(8), + + # OriginChain.load() != Int(8), + Seq([ + # Lets see if we've seen this asset before + asset.store(Btoi(blob.read(Int(3), Int(0), Int(8)))), + MagicAssert(And( + asset.load() != Int(0), + Txn.accounts[3] == get_sig_address(OriginChain.load(), Origin.load()) + ) + ), + ]) # OriginChain.load() != Int(8), + ), # If(OriginChain.load() == Int(8) + + + # Actually send the coins... +# Log(Bytes("Main")), + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Txn.accounts[3], + TxnField.type_enum: TxnType.AssetTransfer, + TxnField.xfer_asset: asset.load(), + TxnField.asset_amount: Amount.load(), + TxnField.asset_receiver: Destination.load(), + TxnField.fee: Int(0), + } + ), + + If(Fee.load() > Int(0), Seq([ +# Log(Bytes("Fees")), + InnerTxnBuilder.Next(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Txn.accounts[3], + TxnField.type_enum: TxnType.AssetTransfer, + TxnField.xfer_asset: asset.load(), + TxnField.asset_amount: Fee.load(), + TxnField.asset_receiver: Txn.sender(), + TxnField.fee: Int(0), + } + ), + ])), + InnerTxnBuilder.Submit(), + + Approve() + ]) + + METHOD = Txn.application_args[0] + + on_delete = Seq([Reject()]) + + @Subroutine(TealType.bytes) + def auth_addr(id) -> Expr: + maybe = AccountParam.authAddr(id) + return Seq(maybe, If(maybe.hasValue(), maybe.value(), Bytes(""))) + + @Subroutine(TealType.bytes) + def extract_name(id) -> Expr: + maybe = AssetParam.name(id) + return Seq(maybe, If(maybe.hasValue(), maybe.value(), Bytes(""))) + + @Subroutine(TealType.bytes) + def extract_creator(id) -> Expr: + maybe = AssetParam.creator(id) + return Seq(maybe, If(maybe.hasValue(), maybe.value(), Bytes(""))) + + @Subroutine(TealType.bytes) + def extract_unit_name(id) -> Expr: + maybe = AssetParam.unitName(id) + return Seq(maybe, If(maybe.hasValue(), maybe.value(), Bytes(""))) + + @Subroutine(TealType.bytes) + def extract_decimal(id) -> Expr: + maybe = AssetParam.decimals(id) + return Seq(maybe, If(maybe.hasValue(), Extract(Itob(maybe.value()), Int(7), Int(1)), Bytes("base16", "00"))) + + + def sendTransfer(): + aid = ScratchVar() + amount = ScratchVar() + d = ScratchVar() + p = ScratchVar() + asset = ScratchVar() + aaddr = ScratchVar() + Address = ScratchVar() + FromChain = ScratchVar() + zb = ScratchVar() + factor = ScratchVar() + fee = ScratchVar() + + return Seq([ + mfee.store(getMessageFee()), + + zb.store(BytesZero(Int(32))), + + aid.store(Btoi(Txn.application_args[1])), + + # what should we pass as a fee... + fee.store(Btoi(Txn.application_args[5])), + + checkFeePmt(Int(2)), + + tidx.store(Txn.group_index() - Int(1)), + + If(aid.load() == Int(0), + Seq([ + MagicAssert(And( + # The previous txn is the asset transfer itself + Gtxn[tidx.load()].type_enum() == TxnType.Payment, + Gtxn[tidx.load()].sender() == Txn.sender(), + Gtxn[tidx.load()].receiver() == Txn.accounts[2], + )), + assert_common_checks(Gtxn[tidx.load()]), + + amount.store(Gtxn[tidx.load()].amount()), + + MagicAssert(fee.load() < amount.load()), + amount.store(amount.load() - fee.load()) + ]), + Seq([ + + MagicAssert(And( + # The previous txn is the asset transfer itself + Gtxn[tidx.load()].type_enum() == TxnType.AssetTransfer, + Gtxn[tidx.load()].sender() == Txn.sender(), + Gtxn[tidx.load()].xfer_asset() == aid.load(), + Gtxn[tidx.load()].asset_receiver() == Txn.accounts[2], + )), + assert_common_checks(Gtxn[tidx.load()]), + + amount.store(Gtxn[tidx.load()].asset_amount()), + + + # peal the fee off the amount + MagicAssert(fee.load() <= amount.load()), + amount.store(amount.load() - fee.load()), + + factor.store(getFactor(Btoi(extract_decimal(aid.load())))), + + If(factor.load() != Int(1), + Seq([ + amount.store(amount.load() / factor.load()), + fee.store(fee.load() / factor.load()), + ]) + ), # If(factor.load() != Int(1), + ]), + ), + + + # If it is nothing but dust lets just abort the whole transaction and save + MagicAssert(And(amount.load() > Int(0), fee.load() >= Int(0))), + + If(aid.load() != Int(0), + aaddr.store(auth_addr(extract_creator(aid.load()))), + aaddr.store(Bytes(""))), + + # Is the authorizing signature of the creator of the asset the address of the token_bridge app itself? + If(aaddr.load() == Global.current_application_address(), + Seq([ +# Log(Bytes("Wormhole wrapped")), + + asset.store(blob.read(Int(2), Int(0), Int(8))), + # This the correct asset? + MagicAssert(Txn.application_args[1] == asset.load()), + + # Pull the address and chain out of the original vaa + Address.store(blob.read(Int(2), Int(60), Int(92))), + FromChain.store(blob.read(Int(2), Int(92), Int(94))), + + # This the correct page given the chain and the address + MagicAssert(Txn.accounts[2] == get_sig_address(Btoi(FromChain.load()), Address.load())), + ]), + Seq([ +# Log(Bytes("Non Wormhole wrapped")), + MagicAssert(Txn.accounts[2] == get_sig_address(aid.load(), Bytes("native"))), + FromChain.store(Bytes("base16", "0008")), + Address.store(Txn.application_args[1]), + ]) + ), + + # Correct address len? + MagicAssert(And( + Len(Address.load()) <= Int(32), + Len(FromChain.load()) == Int(2), + Len(Txn.application_args[3]) <= Int(32) + )), + + p.store(Concat( + If(Txn.application_args.length() == Int(6), + Bytes("base16", "01"), + Bytes("base16", "03")), + Extract(zb.load(), Int(0), Int(24)), + Itob(amount.load()), # 8 bytes + Extract(zb.load(), Int(0), Int(32) - Len(Address.load())), + Address.load(), + FromChain.load(), + Extract(zb.load(), Int(0), Int(32) - Len(Txn.application_args[3])), + Txn.application_args[3], + Extract(Txn.application_args[4], Int(6), Int(2)), + Extract(zb.load(), Int(0), Int(24)), + Itob(fee.load()), # 8 bytes + If(Txn.application_args.length() == Int(7), Txn.application_args[6], Bytes("")) + )), + + # This one magic line should protect us from overruns/underruns and trickery.. + If(Txn.application_args.length() == Int(7), + MagicAssert(Len(p.load()) == Int(133) + Len(Txn.application_args[6])), + MagicAssert(Len(p.load()) == Int(133))), + + InnerTxnBuilder.Begin(), + sendMfee(), + InnerTxnBuilder.SetFields( + { + TxnField.type_enum: TxnType.ApplicationCall, + TxnField.application_id: App.globalGet(Bytes("coreid")), + TxnField.application_args: [Bytes("publishMessage"), p.load(), Itob(Int(0))], + TxnField.accounts: [Txn.accounts[1]], + TxnField.note: Bytes("publishMessage"), + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + + Approve() + ]) + + def do_optin(): + return Seq([ + MagicAssert(Txn.accounts[1] == get_sig_address(Btoi(Txn.application_args[1]), Bytes("native"))), + assert_common_checks(Txn), + + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.sender: Txn.accounts[1], + TxnField.type_enum: TxnType.AssetTransfer, + TxnField.xfer_asset: Btoi(Txn.application_args[1]), + TxnField.asset_amount: Int(0), + TxnField.asset_receiver: Txn.accounts[1], + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + + Approve() + ]) + + # This is for attesting + def attestToken(): + asset = ScratchVar() + p = ScratchVar() + zb = ScratchVar() + d = ScratchVar() + uname = ScratchVar() + name = ScratchVar() + aid = ScratchVar() + + Address = ScratchVar() + FromChain = ScratchVar() + + return Seq([ + mfee.store(getMessageFee()), + + checkFeePmt(Int(1)), + + aid.store(Btoi(Txn.application_args[1])), + # Is the authorizing signature of the creator of the asset the address of the token_bridge app itself? + If(If(aid.load() != Int(0), auth_addr(extract_creator(aid.load())) == Global.current_application_address(), Int(0)), + Seq([ +# Log(Bytes("Wormhole wrapped")), + # Wormhole wrapped asset + asset.store(blob.read(Int(2), Int(0), Int(8))), + # This the correct asset? + MagicAssert(Txn.application_args[1] == asset.load()), + + # Pull the address and chain out of the original vaa + Address.store(blob.read(Int(2), Int(60), Int(92))), + FromChain.store(Btoi(blob.read(Int(2), Int(92), Int(94)))), + + # This the correct page given the chain and the address + MagicAssert(Txn.accounts[2] == get_sig_address(FromChain.load(), Address.load())), + + # this is wormhole wrapped... it shouldn't be busting 8 + MagicAssert(Btoi(extract_decimal(aid.load())) <= Int(8)), + + # Lets just hand back the previously generated vaa payload + p.store(blob.read(Int(2), Int(8), Int(108))) + ]), + Seq([ +# Log(Bytes("Non Wormhole wrapped")), + MagicAssert(Txn.accounts[2] == get_sig_address(aid.load(), Bytes("native"))), + + zb.store(BytesZero(Int(32))), + + aid.store(Btoi(Txn.application_args[1])), + + If(aid.load() == Int(0), + Seq([ + d.store(Bytes("base16", "06")), + uname.store(Bytes("ALGO")), + name.store(Bytes("ALGO")) + ]), + Seq([ + d.store(extract_decimal(aid.load())), + If(Btoi(d.load()) > Int(8), d.store(Bytes("base16", "08"))), + uname.store(extract_unit_name(aid.load())), + name.store(extract_name(aid.load())), + ]) + ), + + p.store( + Concat( + #PayloadID uint8 = 2 + Bytes("base16", "02"), + #TokenAddress [32]uint8 + Extract(zb.load(),Int(0), Int(24)), + Itob(aid.load()), + #TokenChain uint16 + Bytes("base16", "0008"), + #Decimals uint8 + d.load(), + #Symbol [32]uint8 + uname.load(), + Extract(zb.load(), Int(0), Int(32) - Len(uname.load())), + #Name [32]uint8 + name.load(), + Extract(zb.load(), Int(0), Int(32) - Len(name.load())), + ) + ), + ]) + ), + + MagicAssert(Len(p.load()) == Int(100)), + + InnerTxnBuilder.Begin(), + sendMfee(), + InnerTxnBuilder.SetFields( + { + TxnField.type_enum: TxnType.ApplicationCall, + TxnField.application_id: App.globalGet(Bytes("coreid")), + TxnField.application_args: [Bytes("publishMessage"), p.load(), Itob(Int(0))], + TxnField.accounts: [Txn.accounts[1]], + TxnField.note: Bytes("publishMessage"), + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + + Approve() + ]) + + @Subroutine(TealType.none) + def checkForDuplicate(): + off = ScratchVar() + emitter = ScratchVar() + sequence = ScratchVar() + b = ScratchVar() + byte_offset = ScratchVar() + + return Seq( + # VM only is version 1 + MagicAssert(Btoi(Extract(Txn.application_args[1], Int(0), Int(1))) == Int(1)), + + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(14)), # The offset of the emitter + + # emitter is chain/contract-address + emitter.store(Extract(Txn.application_args[1], off.load(), Int(34))), + sequence.store(Btoi(Extract(Txn.application_args[1], off.load() + Int(34), Int(8)))), + + # They passed us the correct account? In this case, byte_offset points at the whole block + byte_offset.store(sequence.load() / Int(max_bits)), + MagicAssert(Txn.accounts[1] == get_sig_address(byte_offset.load(), emitter.load())), + + # Now, lets go grab the raw byte + byte_offset.store((sequence.load() / Int(8)) % Int(max_bytes)), + b.store(blob.get_byte(Int(1), byte_offset.load())), + + # I would hope we've never seen this packet before... throw an exception if we have + MagicAssert(GetBit(b.load(), sequence.load() % Int(8)) == Int(0)), + + # Lets mark this bit so that we never see it again + blob.set_byte(Int(1), byte_offset.load(), SetBit(b.load(), sequence.load() % Int(8), Int(1))) + ) + + def nop(): + return Seq([Approve()]) + + router = Cond( + [METHOD == Bytes("nop"), nop()], + [METHOD == Bytes("receiveAttest"), receiveAttest()], + [METHOD == Bytes("attestToken"), attestToken()], + [METHOD == Bytes("completeTransfer"), completeTransfer()], + [METHOD == Bytes("sendTransfer"), sendTransfer()], + [METHOD == Bytes("optin"), do_optin()], + [METHOD == Bytes("governance"), governance()] + ) + + on_create = Seq( [ + App.globalPut(Bytes("coreid"), Btoi(Txn.application_args[0])), + App.globalPut(Bytes("coreAddr"), Txn.application_args[1]), + App.globalPut(Bytes("validUpdateApproveHash"), Bytes("")), + App.globalPut(Bytes("validUpdateClearHash"), Bytes("base16", "73be5fd7cd378289177bf4a7ca5433ab30d91b417381bba8bd704aff2dec424f")), # empty clear state program + Return(Int(1)) + ]) + + def getOnUpdate(): + if devMode: + return Seq( [ + Return(Txn.sender() == Global.creator_address()), + ]) + else: + return Seq( [ + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.approval_program())) == App.globalGet(Bytes("validUpdateApproveHash"))), + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.clear_state_program())) == App.globalGet(Bytes("validUpdateClearHash"))), + Return(Int(1)) + ] ) + + on_update = getOnUpdate() + + @Subroutine(TealType.uint64) + def optin(): + # Alias for readability + algo_seed = Gtxn[0] + optin = Gtxn[1] + + well_formed_optin = And( + # Check that we're paying it + algo_seed.type_enum() == TxnType.Payment, + algo_seed.amount() == Int(seed_amt), + # Check that its an opt in to us + optin.type_enum() == TxnType.ApplicationCall, + optin.on_completion() == OnComplete.OptIn + ) + + return Seq( + # Make sure its a valid optin + MagicAssert(well_formed_optin), + # Init by writing to the full space available for the sender (Int(0)) + blob.zero(Int(0)), + # we gucci + Int(1) + ) + + on_optin = Seq( [ + Return(optin()) + ]) + + return Cond( + [Txn.application_id() == Int(0), on_create], + [Txn.on_completion() == OnComplete.UpdateApplication, on_update], + [Txn.on_completion() == OnComplete.DeleteApplication, on_delete], + [Txn.on_completion() == OnComplete.OptIn, on_optin], + [Txn.on_completion() == OnComplete.NoOp, router] + ) + +def get_token_bridge(genTeal, approve_name, clear_name, client: AlgodClient, seed_amt: int, tmpl_sig: TmplSig, devMode: bool) -> Tuple[bytes, bytes]: + if not devMode: + client = AlgodClient("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "https://testnet-api.algonode.cloud") + APPROVAL_PROGRAM = fullyCompileContract(genTeal, client, approve_token_bridge(seed_amt, tmpl_sig, devMode), approve_name) + CLEAR_STATE_PROGRAM = fullyCompileContract(genTeal, client, clear_token_bridge(), clear_name) + + return APPROVAL_PROGRAM, CLEAR_STATE_PROGRAM diff --git a/algorand/vaa_verify.py b/algorand/vaa_verify.py new file mode 100644 index 000000000..e3522f3f5 --- /dev/null +++ b/algorand/vaa_verify.py @@ -0,0 +1,126 @@ +#!/usr/bin/python3 +""" +================================================================================================ + +The VAA Signature Verify Stateless Program + +Copyright 2022 Wormhole Project Contributors + +Licensed under the Apache License, Version 2.0 (the "License"); + +you may not use this file except in compliance with the License. + +You may obtain a copy of the License at +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +------------------------------------------------------------------------------------------------ + +This program verifies a subset of the signatures in a VAA against the guardian set. This +program works in tandem with the VAA Processor stateful program. + +The difference between this version and the Randlabs version is I removed most of the asserts +since we are going to have to completely validate the arguments again in the +TokenBridge contract. + +We also cannot retroactively see/verify what arguments were passed into this +function unless all the arguments are in the Txn.application_args so +everything has to get moved out of the lsig args and into the txn_args + +================================================================================================ + +""" +from pyteal.ast import * +from pyteal.types import * +from pyteal.compiler import * +from pyteal.ir import * +from globals import * +from inlineasm import * + +import sys + +SLOTID_RECOVERED_PK_X = 240 +SLOTID_RECOVERED_PK_Y = 241 + +@Subroutine(TealType.uint64) +def sig_check(signatures, dhash, keys): + """ + Verifies some signatures of a VAA. Due to computation budget limitations, + this can't verify all signatures in one go. Instead, it just makes sure that + whatever signatures it's given correspond to the given keys. + + In addition, none of the arguments are validated here beyond the fact that + the signatures are valid given the keys and the message hash. In particular, + the message hash is also not validated here. Thus, the proper way to use + this function is by calling it (by the client) before the token bridge + program. Then the token bridge program verify each input + that the right + program was called. If it failed to verify any of these, then signature + verification could be bypaseed. + """ + si = ScratchVar(TealType.uint64) # signature index (zero-based) + ki = ScratchVar(TealType.uint64) # key index + slen = ScratchVar(TealType.uint64) # signature length + rec_pk_x = ScratchVar(TealType.bytes, SLOTID_RECOVERED_PK_X) + rec_pk_y = ScratchVar(TealType.bytes, SLOTID_RECOVERED_PK_Y) + + return Seq( + [ + rec_pk_x.store(Bytes("")), + rec_pk_y.store(Bytes("")), + slen.store(Len(signatures)), + For(Seq([ + si.store(Int(0)), + ki.store(Int(0)) + ]), + si.load() < slen.load(), + Seq([ + si.store(si.load() + Int(66)), + ki.store(ki.load() + Int(20)) + ])).Do( + Seq([ + InlineAssembly( + "ecdsa_pk_recover Secp256k1", + dhash, + Btoi(Extract(signatures, si.load() + Int(65), Int(1))), + Extract(signatures, si.load() + Int(1), Int(32)), # R + Extract(signatures, si.load() + Int(33), Int(32)), # S + type=TealType.none), + + # returned values in stack, pass to scratch-vars + + InlineAssembly("store " + str(SLOTID_RECOVERED_PK_Y)), + InlineAssembly("store " + str(SLOTID_RECOVERED_PK_X)), + + # Generate Ethereum-type public key, compare with guardian key. + + Assert(Extract(keys, ki.load(), Int(20)) == Substring(Keccak256(Concat(rec_pk_x.load(), rec_pk_y.load())), Int(12), Int(32))) + ]) + ), + Return(Int(1)) + ] + ) + +def vaa_verify_program(): + signatures = Txn.application_args[1] + keys = Txn.application_args[2] + dhash = Txn.application_args[3] + + return Seq([ + Assert(Txn.rekey_to() == Global.zero_address()), + Assert(Txn.fee() == Int(0)), + Assert(Txn.type_enum() == TxnType.ApplicationCall), + Assert(sig_check(signatures, dhash, keys)), + Approve()] + ) + +def get_vaa_verify(): + teal = compileTeal(vaa_verify_program(), mode=Mode.Signature, version=6) + + with open("teal/vaa_verify.teal", "w") as f: + f.write(teal) + + return teal diff --git a/algorand/wormhole_core.py b/algorand/wormhole_core.py new file mode 100644 index 000000000..156d13ced --- /dev/null +++ b/algorand/wormhole_core.py @@ -0,0 +1,592 @@ +from time import time, sleep +from typing import List, Tuple, Dict, Any, Optional, Union +from base64 import b64decode +import base64 +import random +import hashlib +import uuid +import sys +import json +import uvarint + +from local_blob import LocalBlob +from TmplSig import TmplSig + +from algosdk.v2client.algod import AlgodClient +from algosdk.kmd import KMDClient +from algosdk import account, mnemonic +from algosdk.encoding import decode_address +from algosdk.future import transaction +from pyteal import compileTeal, Mode, Expr +from pyteal import * +from algosdk.logic import get_application_address + +from algosdk.future.transaction import LogicSigAccount +from inspect import currentframe + +import pprint + +max_keys = 15 +max_bytes_per_key = 127 +bits_per_byte = 8 + +bits_per_key = max_bytes_per_key * bits_per_byte +max_bytes = max_bytes_per_key * max_keys +max_bits = bits_per_byte * max_bytes + +def fullyCompileContract(genTeal, client: AlgodClient, contract: Expr, name) -> bytes: + if genTeal: + teal = compileTeal(contract, mode=Mode.Application, version=6, assembleConstants=True, optimize=OptimizeOptions(scratch_slots=True)) + + with open(name, "w") as f: + print("Writing " + name) + f.write(teal) + else: + with open(name, "r") as f: + print("Reading " + name) + teal = f.read() + + response = client.compile(teal) + return response + +def getCoreContracts( genTeal, approve_name, clear_name, + client: AlgodClient, + seed_amt: int, + tmpl_sig: TmplSig, + devMode: bool + ) -> Tuple[bytes, bytes]: + + def vaa_processor_program(seed_amt: int, tmpl_sig: TmplSig): + blob = LocalBlob() + + def MagicAssert(a) -> Expr: + if devMode: + return Assert(And(a, Int(currentframe().f_back.f_lineno))) + else: + return Assert(a) + + @Subroutine(TealType.bytes) + def encode_uvarint(val: Expr, b: Expr): + buff = ScratchVar() + return Seq( + buff.store(b), + Concat( + buff.load(), + If( + val >= Int(128), + encode_uvarint( + val >> Int(7), + Extract(Itob((val & Int(255)) | Int(128)), Int(7), Int(1)), + ), + Extract(Itob(val & Int(255)), Int(7), Int(1)), + ), + ), + ) + + @Subroutine(TealType.bytes) + def get_sig_address(acct_seq_start: Expr, emitter: Expr): + # We could iterate over N items and encode them for a more general interface + # but we inline them directly here + + return Sha512_256( + Concat( + Bytes("Program"), + # ADDR_IDX aka sequence start + tmpl_sig.get_bytecode_chunk(0), + encode_uvarint(acct_seq_start, Bytes("")), + + # EMMITTER_ID + tmpl_sig.get_bytecode_chunk(1), + encode_uvarint(Len(emitter), Bytes("")), + emitter, + + # APP_ID + tmpl_sig.get_bytecode_chunk(2), + encode_uvarint(Global.current_application_id(), Bytes("")), + + # TMPL_APP_ADDRESS + tmpl_sig.get_bytecode_chunk(3), + encode_uvarint(Len(Global.current_application_address()), Bytes("")), + Global.current_application_address(), + + + tmpl_sig.get_bytecode_chunk(4), + ) + ) + + @Subroutine(TealType.uint64) + def optin(): + # Alias for readability + algo_seed = Gtxn[0] + optin = Gtxn[1] + + well_formed_optin = And( + # Check that we're paying it + algo_seed.type_enum() == TxnType.Payment, + algo_seed.amount() == Int(seed_amt), + # Check that its an opt in to us + optin.type_enum() == TxnType.ApplicationCall, + optin.on_completion() == OnComplete.OptIn, + # Not strictly necessary since we wouldn't be seeing this unless it was us, but... + optin.application_id() == Global.current_application_id(), + ) + + return Seq( + # Make sure its a valid optin + MagicAssert(well_formed_optin), + # Init by writing to the full space available for the sender (Int(0)) + blob.zero(Int(0)), + # we gucci + Int(1) + ) + + def nop(): + return Seq([Approve()]) + + def publishMessage(): + seq = ScratchVar() + fee = ScratchVar() + + pmt = Gtxn[Txn.group_index() - Int(1)] + + return Seq([ + # Lets see if we were handed the correct account to store the sequence number in + MagicAssert(Txn.accounts[1] == get_sig_address(Int(0), Txn.sender())), + + fee.store(App.globalGet(Bytes("MessageFee"))), + If(fee.load() > Int(0), Seq([ + MagicAssert(And( + pmt.type_enum() == TxnType.Payment, + pmt.amount() >= fee.load(), + pmt.receiver() == Global.current_application_address(), + pmt.rekey_to() == Global.zero_address() + )), + ])), + + # emitter sequence number + seq.store(Itob(Btoi(blob.read(Int(1), Int(0), Int(8))) + Int(1))), + Pop(blob.write(Int(1), Int(0), seq.load())), + + # Log it so that we can look for this on the guardian network + Log(seq.load()), + + blob.meta(Int(1), Bytes("publishMessage")), + + Approve() + ]) + + def hdlGovernance(isBoot: Expr): + off = ScratchVar() + a = ScratchVar() + emitter = ScratchVar() + dest = ScratchVar() + fee = ScratchVar() + idx = ScratchVar() + set = ScratchVar() + len = ScratchVar() + v = ScratchVar() + tchain = ScratchVar() + + return Seq([ + + # All governance must be done with the most recent guardian set + set.store(App.globalGet(Bytes("currentGuardianSetIndex"))), + If(set.load() != Int(0), Seq([ + idx.store(Extract(Txn.application_args[1], Int(1), Int(4))), + MagicAssert(Btoi(idx.load()) == set.load()), + ])), + + # The offset of the chain + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(14)), + # Correct source chain? + MagicAssert(Extract(Txn.application_args[1], off.load(), Int(2)) == Bytes("base16", "0001")), + # Correct emitter? + MagicAssert(Extract(Txn.application_args[1], off.load() + Int(2), Int(32)) == Bytes("base16", "0000000000000000000000000000000000000000000000000000000000000004")), + # Get us to the payload + off.store(off.load() + Int(43)), + # Is this a governance message? + MagicAssert(Extract(Txn.application_args[1], off.load(), Int(32)) == Bytes("base16", "00000000000000000000000000000000000000000000000000000000436f7265")), + off.store(off.load() + Int(32)), + # What is the target of this governance message? + tchain.store(Extract(Txn.application_args[1], off.load() + Int(1), Int(2))), + # Needs to point at us or to all chains + MagicAssert(Or(tchain.load() == Bytes("base16", "0008"), tchain.load() == Bytes("base16", "0000"))), + + a.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(1)))), + Cond( + [a.load() == Int(1), Seq([ + # ContractUpgrade is a VAA that instructs an implementation on a specific chain to upgrade itself + # + # In the case of Algorand, it contains the hash of the program that we are allowed to upgrade ourselves to. We would then run the upgrade program itself + # to perform the actual upgrade + off.store(off.load() + Int(3)), + + App.globalPut(Bytes("validUpdateApproveHash"), Extract(Txn.application_args[1], off.load(), Int(32))) + ])], + [a.load() == Int(2), Seq([ + # We are updating the guardian set + + # This should point at all chains + + # move off to point at the NewGuardianSetIndex and grab it + off.store(off.load() + Int(3)), + v.store(Extract(Txn.application_args[1], off.load(), Int(4))), + idx.store(Btoi(v.load())), + + # Lets see if the user handed us the correct memory... no hacky hacky + MagicAssert(Txn.accounts[3] == get_sig_address(idx.load(), Bytes("guardian"))), + + # Make sure it is different and we can only walk forward + If(isBoot == Int(0), Seq( + MagicAssert(Txn.accounts[3] != Txn.accounts[2]), + MagicAssert(idx.load() > (set.load())) + )), + + # Write this away till the next time + App.globalPut(Bytes("currentGuardianSetIndex"), idx.load()), + + # Write everything out to the auxilliary storage + off.store(off.load() + Int(4)), + len.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(1)))), + + # Lets not let us get bricked by somebody submitting a stupid guardian set... + MagicAssert(len.load() > Int(0)), + + Pop(blob.write(Int(3), Int(0), Extract(Txn.application_args[1], off.load(), Int(1) + (Int(20) * len.load())))), + # Make this block expire.. as long as it is + # not being used to sign itself. We stick the + # expiration 1000 bytes into the account... + # + # 19200 is approx 24 hours assuming a 4.5 seconds per block (24 * 3600 / 4.5) = 19200 + If(Txn.accounts[3] != Txn.accounts[2], + Pop(blob.write(Int(2), Int(1000), Itob(Txn.first_valid() + Int(19200))))), + blob.meta(Int(3), Bytes("guardian")) + ])], + [a.load() == Int(3), Seq([ + off.store(off.load() + Int(1)), + MagicAssert(tchain.load() == Bytes("base16", "0008")), + off.store(off.load() + Int(2) + Int(24)), + fee.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(8)))), + App.globalPut(Bytes("MessageFee"), fee.load()), + ])], + [a.load() == Int(4), Seq([ + off.store(off.load() + Int(1)), + MagicAssert(tchain.load() == Bytes("base16", "0008")), + off.store(off.load() + Int(26)), + fee.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(8)))), + off.store(off.load() + Int(8)), + dest.store(Extract(Txn.application_args[1], off.load(), Int(32))), + + InnerTxnBuilder.Begin(), + InnerTxnBuilder.SetFields( + { + TxnField.type_enum: TxnType.Payment, + TxnField.receiver: dest.load(), + TxnField.amount: fee.load(), + TxnField.fee: Int(0), + } + ), + InnerTxnBuilder.Submit(), + ])] + ), + Approve() + ]) + + def init(): + return Seq([ + # You better lose yourself in the music, the moment + App.globalPut(Bytes("vphash"), Txn.application_args[2]), + + # You own it, you better never let it go + MagicAssert(Txn.sender() == Global.creator_address()), + + # You only get one shot, do not miss your chance to blow + MagicAssert(App.globalGet(Bytes("booted")) == Int(0)), + App.globalPut(Bytes("booted"), Bytes("true")), + + # This opportunity comes once in a lifetime + checkForDuplicate(), + + # You can do anything you set your mind to... + hdlGovernance(Int(1)) + ]) + + def verifySigs(): + return Seq([ + Approve(), + ]) + + + @Subroutine(TealType.none) + def checkForDuplicate(): + off = ScratchVar() + emitter = ScratchVar() + sequence = ScratchVar() + b = ScratchVar() + byte_offset = ScratchVar() + + return Seq( + # VM only is version 1 + MagicAssert(Btoi(Extract(Txn.application_args[1], Int(0), Int(1))) == Int(1)), + + off.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1))) * Int(66) + Int(14)), # The offset of the emitter + + # emitter is chain/contract-address + emitter.store(Extract(Txn.application_args[1], off.load(), Int(34))), + sequence.store(Btoi(Extract(Txn.application_args[1], off.load() + Int(34), Int(8)))), + + # They passed us the correct account? In this case, byte_offset points at the whole block + byte_offset.store(sequence.load() / Int(max_bits)), + MagicAssert(Txn.accounts[1] == get_sig_address(byte_offset.load(), emitter.load())), + + # Now, lets go grab the raw byte + byte_offset.store((sequence.load() / Int(8)) % Int(max_bytes)), + b.store(blob.get_byte(Int(1), byte_offset.load())), + + # I would hope we've never seen this packet before... throw an exception if we have + MagicAssert(GetBit(b.load(), sequence.load() % Int(8)) == Int(0)), + + # Lets mark this bit so that we never see it again + blob.set_byte(Int(1), byte_offset.load(), SetBit(b.load(), sequence.load() % Int(8), Int(1))), + + blob.meta(Int(1), Bytes("duplicate")) + ) + + STATELESS_LOGIC_HASH = App.globalGet(Bytes("vphash")) + + def verifyVAA(): + i = ScratchVar() + a = ScratchVar() + total_guardians = ScratchVar() + guardian_keys = ScratchVar() + num_sigs = ScratchVar() + off = ScratchVar() + digest = ScratchVar() + hits = ScratchVar() + s = ScratchVar() + eoff = ScratchVar() + guardian = ScratchVar() + + return Seq([ + # We have a guardian set? We have OUR guardian set? + MagicAssert(Txn.accounts[2] == get_sig_address(Btoi(Extract(Txn.application_args[1], Int(1), Int(4))), Bytes("guardian"))), + blob.checkMeta(Int(2), Bytes("guardian")), + # Lets grab the total keyset + total_guardians.store(blob.get_byte(Int(2), Int(0))), + guardian_keys.store(blob.read(Int(2), Int(1), Int(1) + Int(20) * total_guardians.load())), + + # I wonder if this is an expired guardian set + s.store(Btoi(blob.read(Int(2), Int(1000), Int(1008)))), + If(s.load() != Int(0), + MagicAssert(Txn.first_valid() < s.load())), + + hits.store(Bytes("base16", "0x00000000")), + + # How many signatures are in this vaa? + num_sigs.store(Btoi(Extract(Txn.application_args[1], Int(5), Int(1)))), + + # Lets create a digest of THIS vaa... + off.store(Int(6) + (num_sigs.load() * Int(66))), + digest.store(Keccak256(Keccak256(Extract(Txn.application_args[1], off.load(), Len(Txn.application_args[1]) - off.load())))), + + # We have enough signatures? + MagicAssert(And( + total_guardians.load() > Int(0), + num_sigs.load() <= total_guardians.load(), + num_sigs.load() > ((total_guardians.load() * Int(2)) / Int(3)), + )), + + + # Point it at the start of the signatures in the VAA + off.store(Int(6)), + + # We'll check that the preceding transactions properly verify + # all of the signatures. Due to size limitations, there will be + # multiple 'verifySigs' calls to achieve this. First we walk + # backwards from the current instruction to find all the + # 'verifySigs' calls. We do it this way because it's possible + # that the VAA transactions are composed with some other + # contracts calls, so we do not rely in absolute transaction + # indices. + # + # | | ... | + # | | something else | + # | |----------------| + # | | verifySigs | + # | | verifySigs | + # | | verifySigs | + # | | verifyVAA | <- we are here now + # | |----------------| + # v | ... | + + MagicAssert(Txn.group_index() > Int(0)), + # the first 'verifySigs' tx is the one before us + i.store(Txn.group_index() - Int(1)), + MagicAssert(Gtxn[i.load()].application_args.length() > Int(0)), + a.store(Gtxn[i.load()].application_args[0]), + + # Go back until we hit 'something else' or run out of + # transactions (we allow nops too) + While (And(i.load() > Int(0), Or(a.load() == Bytes("verifySigs"), a.load() == Bytes("nop")))).Do(Seq([ + i.store(i.load() - Int(1)), + If (Gtxn[i.load()].application_args.length() > Int(0), + a.store(Gtxn[i.load()].application_args[0]), + Seq([ + a.store(Bytes("")), + Break() + ])) + ])), + + If(And(a.load() != Bytes("verifySigs"), a.load() != Bytes("nop")), i.store(i.load() + Int(1))), + + # Now look through the whole group of 'verifySigs' + While(i.load() <= Txn.group_index()).Do(Seq([ + MagicAssert(And( + Gtxn[i.load()].type_enum() == TxnType.ApplicationCall, + Gtxn[i.load()].rekey_to() == Global.zero_address(), + Gtxn[i.load()].application_id() == Txn.application_id(), + Gtxn[i.load()].accounts[1] == Txn.accounts[1], + Gtxn[i.load()].accounts[2] == Txn.accounts[2], + )), + a.store(Gtxn[i.load()].application_args[0]), + Cond( + [a.load() == Bytes("verifySigs"), Seq([ + # Lets see if they are actually verifying the correct signatures! + + # What signatures did this verifySigs check? + s.store(Gtxn[i.load()].application_args[1]), + + # Look at the vaa and confirm those were the expected signatures we should have been checking + # at this point in the process + MagicAssert(Extract(Txn.application_args[1], off.load(), Len(s.load())) == s.load()), + + # Where is the end pointer... + eoff.store(off.load() + Len(s.load())), + + # Now we will reset s and collect the keys + s.store(Bytes("")), + + While(off.load() < eoff.load()).Do(Seq( [ + # Lets see if we ever reuse the same signature more then once (same guardian over and over) + guardian.store(Btoi(Extract(Txn.application_args[1], off.load(), Int(1)))), + MagicAssert(GetBit(hits.load(), guardian.load()) == Int(0)), + hits.store(SetBit(hits.load(), guardian.load(), Int(1))), + + # This extracts out of the keys THIS guardian's public key + s.store(Concat(s.load(), Extract(guardian_keys.load(), guardian.load() * Int(20), Int(20)))), + + off.store(off.load() + Int(66)) + ])), + + MagicAssert(And( + Gtxn[i.load()].application_args[2] == s.load(), # Does the keyset passed into the verify routines match what it should be? + Gtxn[i.load()].sender() == STATELESS_LOGIC_HASH, # Was it signed with our code? + Gtxn[i.load()].application_args[3] == digest.load() # Was it verifying the same vaa? + )), + + ])], + [a.load() == Bytes("nop"), Seq([])], # if there is a function call not listed here, it will throw an error + [a.load() == Bytes("verifyVAA"), Seq([])], + [Int(1) == Int(1), Seq([Reject()])] # Nothing should get snuck in between... + ), + i.store(i.load() + Int(1)) + ]) + ), + + # Did we verify all the signatures? If the answer is no, something is sus + MagicAssert(off.load() == Int(6) + (num_sigs.load() * Int(66))), + + Approve(), + ]) + + def governance(): + return Seq([ + checkForDuplicate(), # Verify this is not a duplicate message and then make sure we never see it again + + MagicAssert(And( + Gtxn[Txn.group_index() - Int(1)].type_enum() == TxnType.ApplicationCall, + Gtxn[Txn.group_index() - Int(1)].application_id() == Txn.application_id(), + Gtxn[Txn.group_index() - Int(1)].application_args[0] == Bytes("verifyVAA"), + Gtxn[Txn.group_index() - Int(1)].sender() == Txn.sender(), + Gtxn[Txn.group_index() - Int(1)].rekey_to() == Global.zero_address(), + + # Lets see if the vaa we are about to process was actually verified by the core + Gtxn[Txn.group_index() - Int(1)].application_args[1] == Txn.application_args[1], + + # What checks should I give myself + Gtxn[Txn.group_index()].rekey_to() == Global.zero_address(), + Gtxn[Txn.group_index()].sender() == Txn.sender(), + + # We all opted into the same accounts? + Gtxn[Txn.group_index() - Int(1)].accounts[0] == Txn.accounts[0], + Gtxn[Txn.group_index() - Int(1)].accounts[1] == Txn.accounts[1], + Gtxn[Txn.group_index() - Int(1)].accounts[2] == Txn.accounts[2], + )), + + hdlGovernance(Int(0)), + Approve(), + ]) + + METHOD = Txn.application_args[0] + + on_delete = Seq([Reject()]) + + router = Cond( + [METHOD == Bytes("publishMessage"), publishMessage()], + [METHOD == Bytes("nop"), nop()], + [METHOD == Bytes("init"), init()], + [METHOD == Bytes("verifySigs"), verifySigs()], + [METHOD == Bytes("verifyVAA"), verifyVAA()], + [METHOD == Bytes("governance"), governance()], + ) + + on_create = Seq( [ + App.globalPut(Bytes("MessageFee"), Int(0)), + App.globalPut(Bytes("vphash"), Bytes("")), + App.globalPut(Bytes("currentGuardianSetIndex"), Int(0)), + App.globalPut(Bytes("validUpdateApproveHash"), Bytes("")), + App.globalPut(Bytes("validUpdateClearHash"), Bytes("base16", "73be5fd7cd378289177bf4a7ca5433ab30d91b417381bba8bd704aff2dec424f")), # empty clear state program + Return(Int(1)) + ]) + + progHash = ScratchVar() + progSet = ScratchVar() + clearHash = ScratchVar() + clearSet = ScratchVar() + + def getOnUpdate(): + if devMode: + return Seq( [ + Return(Txn.sender() == Global.creator_address()), + ]) + else: + return Seq( [ + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.approval_program())) == App.globalGet(Bytes("validUpdateApproveHash"))), + MagicAssert(Sha512_256(Concat(Bytes("Program"), Txn.clear_state_program())) == App.globalGet(Bytes("validUpdateClearHash"))), + Return(Int(1)) + ] ) + + on_update = getOnUpdate() + + on_optin = Seq( [ + Return(optin()) + ]) + + return Cond( + [Txn.application_id() == Int(0), on_create], + [Txn.on_completion() == OnComplete.UpdateApplication, on_update], + [Txn.on_completion() == OnComplete.DeleteApplication, on_delete], + [Txn.on_completion() == OnComplete.OptIn, on_optin], + [Txn.on_completion() == OnComplete.NoOp, router] + ) + + def clear_state_program(): + return Int(1) + + if not devMode: + client = AlgodClient("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "https://testnet-api.algonode.cloud") + APPROVAL_PROGRAM = fullyCompileContract(genTeal, client, vaa_processor_program(seed_amt, tmpl_sig), approve_name) + CLEAR_STATE_PROGRAM = fullyCompileContract(genTeal, client, clear_state_program(), clear_name) + + return APPROVAL_PROGRAM, CLEAR_STATE_PROGRAM + diff --git a/devnet/algorand-devnet.yaml b/devnet/algorand-devnet.yaml new file mode 100644 index 000000000..0b0457946 --- /dev/null +++ b/devnet/algorand-devnet.yaml @@ -0,0 +1,97 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: algorand + name: algorand +spec: + ports: + - name: postgres + port: 5432 + protocol: TCP + - name: algod + port: 4001 + targetPort: algod + - name: kmd + port: 4002 + targetPort: kmd + - name: indexer + port: 8980 + targetPort: indexer + selector: + app: algorand +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: algorand + name: algorand +spec: + replicas: 1 + selector: + matchLabels: + app: algorand + serviceName: algorand + template: + metadata: + labels: + app: algorand + spec: + containers: + - image: postgres:13-alpine + name: algorand-postgres + ports: + - containerPort: 5432 + resources: {} + env: + - name: POSTGRES_USER + value: algorand + - name: POSTGRES_PASSWORD + value: algorand + - name: POSTGRES_DB + value: indexer_db + - name: algorand-algod + image: algorand-algod + command: + - /bin/sh + - -c + - /opt/start_algod.sh + ports: + - containerPort: 4001 + name: algod + protocol: TCP + - containerPort: 4002 + name: kmd + protocol: TCP + readinessProbe: + tcpSocket: + port: 4001 + - name: algorand-indexer + image: algorand-indexer + command: + - /bin/sh + - -c + - /tmp/start.sh + ports: + - containerPort: 8980 + name: indexer + protocol: TCP + readinessProbe: + tcpSocket: + port: 8980 + - name: algorand-contracts + image: algorand-contracts + command: + - /bin/sh + - -c + - "sh deploy.sh && touch success && sleep infinity" + readinessProbe: + exec: + command: + - test + - -e + - "success" + initialDelaySeconds: 5 + periodSeconds: 5 + restartPolicy: Always diff --git a/devnet/algorand.yaml b/devnet/algorand.yaml deleted file mode 100644 index c924e94f9..000000000 --- a/devnet/algorand.yaml +++ /dev/null @@ -1,62 +0,0 @@ ---- -apiVersion: v1 -kind: Service -metadata: - name: algorand - labels: - app: algorand -spec: - clusterIP: None - selector: - app: algorand - ports: - - name: algod - port: 4001 - targetPort: algod - - name: kmd - port: 4002 - targetPort: kmd ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: algorand -spec: - selector: - matchLabels: - app: algorand - serviceName: algorand - template: - metadata: - labels: - app: algorand - spec: - restartPolicy: Always - terminationGracePeriodSeconds: 0 - containers: - - name: algod - image: algorand - command: - - /bin/sh - - -c - - ./goal network start -r /network && sleep infinity - ports: - - containerPort: 4001 - name: algod - protocol: TCP - readinessProbe: - tcpSocket: - port: 4001 - - name: goal-kmd - image: algorand - command: - - /bin/sh - - -c - - ./goal kmd start -d /network/Node && ./goal account list && /setup/setup.sh && sleep infinity - ports: - - containerPort: 4002 - name: kmd - protocol: TCP - readinessProbe: - tcpSocket: - port: 4002 diff --git a/devnet/eth-devnet.yaml b/devnet/eth-devnet.yaml index 30cfb894d..3f1a4fb66 100644 --- a/devnet/eth-devnet.yaml +++ b/devnet/eth-devnet.yaml @@ -69,7 +69,7 @@ spec: command: - /bin/sh - -c - - "npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_bsc_chain.js && nc -lkp 2000 0.0.0.0" + - "npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_bsc_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0" readinessProbe: periodSeconds: 1 failureThreshold: 300 @@ -122,7 +122,7 @@ spec: command: - /bin/sh - -c - - "sed -i 's/CHAIN_ID=0x2/CHAIN_ID=0x4/g' .env && npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_eth_chain.js && nc -lkp 2000 0.0.0.0" + - "sed -i 's/CHAIN_ID=0x2/CHAIN_ID=0x4/g' .env && npm run migrate && npx truffle exec scripts/deploy_test_token.js && npx truffle exec scripts/register_solana_chain.js && npx truffle exec scripts/register_terra_chain.js && npx truffle exec scripts/register_eth_chain.js && npx truffle exec scripts/register_algo_chain.js && nc -lkp 2000 0.0.0.0" readinessProbe: periodSeconds: 1 failureThreshold: 300 diff --git a/ethereum/scripts/register_algo_chain.js b/ethereum/scripts/register_algo_chain.js new file mode 100644 index 000000000..492434db8 --- /dev/null +++ b/ethereum/scripts/register_algo_chain.js @@ -0,0 +1,32 @@ +// run this script with truffle exec + +const jsonfile = require("jsonfile"); +const TokenBridge = artifacts.require("TokenBridge"); +const TokenImplementation = artifacts.require("TokenImplementation"); +const BridgeImplementationFullABI = jsonfile.readFileSync( + "../build/contracts/BridgeImplementation.json" +).abi; +const algoTokenBridgeVAA = process.env.REGISTER_ALGO_TOKEN_BRIDGE_VAA; + +module.exports = async function(callback) { + try { + const accounts = await web3.eth.getAccounts(); + const initialized = new web3.eth.Contract( + BridgeImplementationFullABI, + TokenBridge.address + ); + + // Register the ALGO endpoint + await initialized.methods + .registerChain("0x" + algoTokenBridgeVAA) + .send({ + value: 0, + from: accounts[0], + gasLimit: 2000000, + }); + + callback(); + } catch (e) { + callback(e); + } +}; diff --git a/scripts/devnet-consts.json b/scripts/devnet-consts.json index de9b7eaf2..0aa413f79 100644 --- a/scripts/devnet-consts.json +++ b/scripts/devnet-consts.json @@ -197,6 +197,11 @@ "nftBridgeEmitterAddress": "00000000000000000000000026b4afb60d6c903165150c6f0aa14f8016be4aec", "nftBridgeAddress": "0x26b4afb60d6c903165150c6f0aa14f8016be4aec" } + }, + "8": { + "contracts": { + "tokenBridgeEmitterAddress": "8edf5b0e108c3a1a0a4b704cc89591f2ad8d50df24e991567e640ed720a94be2" + } } }, "gancheDefaults": [ diff --git a/scripts/guardian-set-init.sh b/scripts/guardian-set-init.sh index f41b590a5..6e91ba97e 100755 --- a/scripts/guardian-set-init.sh +++ b/scripts/guardian-set-init.sh @@ -75,6 +75,7 @@ solTokenBridge=$(jq --raw-output '.chains."1".contracts.tokenBridgeEmitterAddres ethTokenBridge=$(jq --raw-output '.chains."2".contracts.tokenBridgeEmitterAddress' $addressesJson) terraTokenBridge=$(jq --raw-output '.chains."3".contracts.tokenBridgeEmitterAddress' $addressesJson) bscTokenBridge=$(jq --raw-output '.chains."4".contracts.tokenBridgeEmitterAddress' $addressesJson) +algoTokenBridge=$(jq --raw-output '.chains."8".contracts.tokenBridgeEmitterAddress' $addressesJson) solNFTBridge=$(jq --raw-output '.chains."1".contracts.nftBridgeEmitterAddress' $addressesJson) ethNFTBridge=$(jq --raw-output '.chains."2".contracts.nftBridgeEmitterAddress' $addressesJson) @@ -93,6 +94,7 @@ solTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- gener ethTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 2 0x${ethTokenBridge} --guardian_secret ${guardiansPrivateCSV} ) terraTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 3 0x${terraTokenBridge} --guardian_secret ${guardiansPrivateCSV}) bscTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 4 0x${bscTokenBridge} --guardian_secret ${guardiansPrivateCSV}) +algoTokenBridgeVAA=$(npm --prefix clients/token_bridge run --silent main -- generate_register_chain_vaa 8 0x${algoTokenBridge} --guardian_secret ${guardiansPrivateCSV}) # 5) create nft bridge registration VAAs @@ -115,6 +117,7 @@ solTokenBridge="REGISTER_SOL_TOKEN_BRIDGE_VAA" ethTokenBridge="REGISTER_ETH_TOKEN_BRIDGE_VAA" terraTokenBridge="REGISTER_TERRA_TOKEN_BRIDGE_VAA" bscTokenBridge="REGISTER_BSC_TOKEN_BRIDGE_VAA" +algoTokenBridge="REGISTER_ALGO_TOKEN_BRIDGE_VAA" solNFTBridge="REGISTER_SOL_NFT_BRIDGE_VAA" ethNFTBridge="REGISTER_ETH_NFT_BRIDGE_VAA" @@ -149,6 +152,10 @@ upsert_env_file $envFile $terraNFTBridge $terraNFTBridgeVAA upsert_env_file $ethFile $bscTokenBridge $bscTokenBridgeVAA upsert_env_file $envFile $bscTokenBridge $bscTokenBridgeVAA +# algo token bridge +upsert_env_file $ethFile $algoTokenBridge $algoTokenBridgeVAA +upsert_env_file $envFile $algoTokenBridge $algoTokenBridgeVAA + # 7) copy the local .env file to the solana & terra dirs, if the script is running on the host machine # chain dirs will not exist if running in docker for Tilt, only if running locally. check before copying. @@ -159,7 +166,7 @@ if [[ -d ./ethereum ]]; then fi # copy the hex envFile to each of the non-EVM chains -for envDest in ./solana/.env ./terra/tools/.env; do +for envDest in ./solana/.env ./terra/tools/.env ./algorand/.env; do dirname=$(dirname $envDest) if [[ -d "$dirname" ]]; then echo "copying $envFile to $envDest" diff --git a/solana/devnet_setup.sh b/solana/devnet_setup.sh index ce78c4367..c7da570e6 100755 --- a/solana/devnet_setup.sh +++ b/solana/devnet_setup.sh @@ -98,6 +98,7 @@ pushd /usr/src/clients/token_bridge node main.js solana execute_governance_vaa "$REGISTER_ETH_TOKEN_BRIDGE_VAA" node main.js solana execute_governance_vaa "$REGISTER_TERRA_TOKEN_BRIDGE_VAA" node main.js solana execute_governance_vaa "$REGISTER_BSC_TOKEN_BRIDGE_VAA" +node main.js solana execute_governance_vaa "$REGISTER_ALGO_TOKEN_BRIDGE_VAA" popd pushd /usr/src/clients/nft_bridge diff --git a/staging/algorand/.eslintrc.js b/staging/algorand/.eslintrc.js deleted file mode 100644 index 137056bac..000000000 --- a/staging/algorand/.eslintrc.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = { - env: { - browser: true, - commonjs: true, - es2021: true, - mocha: true - }, - extends: [ - 'standard' - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 12 - }, - plugins: [ - '@typescript-eslint' - ], - rules: { - } -} diff --git a/staging/algorand/.gitignore b/staging/algorand/.gitignore deleted file mode 100644 index 83ccf386c..000000000 --- a/staging/algorand/.gitignore +++ /dev/null @@ -1,108 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -teal/wormhole/pyteal/__pycache__/* -teal/wormhole/build/*.teal -test/temp/*.teal diff --git a/staging/algorand/README.md b/staging/algorand/README.md deleted file mode 100644 index e32a18fa1..000000000 --- a/staging/algorand/README.md +++ /dev/null @@ -1,341 +0,0 @@ - -# Pricecaster Service V2 - -## Introduction - -This service consumes prices from "price fetchers" and feeds blockchain publishers. - -The current implementation is a Wormhole client that uses the JS SDK to get VAAs from Pyth network and feed the payload and cryptographic verification data to a transaction group for validation. Subsequently, the data is optionally processed and stored, either price or metrics. For details regarding Wormhole VAAs see design documents: - - https://github.com/certusone/wormhole/tree/dev.v2/whitepapers - -## System Overview - -**The objective is to receive signed messages -named as Verifiable Attestments (VAAs) in Wormhole jargon- from our relayer backend (Pricecaster) , verify them against a fixed (and upgradeable) set of "guardian public keys" and process them, publishing on-chain price information or doing governance chores depending on the VAA payload.** - - -The design is based in two contracts that work in tandem, a **Stateful contract (VAA_Processor)** that accepts calls for verifying and commiting VAAs, and also mantains the global guardian set; and a **verifier stateless contract** that does the computational work of ECDSA signature verification. - -Due to computation and space limits, the validation of the 19 guardian signatures against the payload is partitioned so each stateless contract validates a subset of the guardian signatures. If ECDSA decompress and validation opcodes are used, that yields 650+1750 = 2400 computation units * 7 = 16800, leaving 3200 free units for remaining opcodes. -In our design, We call **verification step** to each of the app calls + stateless logic involved in verifying a block of signatures. - -Keep in mind that *not all* the 19 signatures must be present in a VAA verification, but at least 1 + (2/3) of the current guardian set. - -The maximum number of signatures in each verification step is fixed at contract compilation stage, so with this in mind and example values: - -* let $N_S$ be the total signatures to verify $(19)$ -* let $N_V$ be the number of signatures per verification step $(7)$, -* the required number of transactions $N_T = \lceil{N_S/N_V}\rceil = \lceil{19/7}\rceil = 3$ -* Each transaction-step $T_i$ will verify signatures $[j..k]$ where $j = i \times N_V$, $k = min(N_S-1, j+N_V-1)$, so for $T_0 = [0..6]$, $T_1 = [7..13]$, $T_2 = [14..18]$. - -The verification process inputs consist of: -1. the set of current guardian public keys, -2. the signed message digest (VAA information fields + generic payload), -3. the set of signatures in the VAA header. - -With the above in mind, and considering the space and computation limits in the current Algorand protocol, the typical flow for verifying a VAA for 19 guardians using step-size of 7, would be based on the following transaction group: - - -| TX# | App calls | Stateless logic | -| --- | --------- | --------------- | -| 0 | _args_: guardian_pk[0..6], _txnote_: signed_digest | _args_: sig[0..6] | -| 1 | _args_: guardian_pk[7..13], _txnote_: signed_digest | _args_: sig[7..13] | -| 2 | _args_: guardian_pk[14..18], _txnote_: signed_digest | _args_: sig[14..18] | -| 3 | VAA consume call | N/A | - -The current design requires the last call to be a call to an authorized application. This is intended to process VAA price data. The authorized appid must be set accordingly using the `setauthid` call in the VAA Processor contract after deployment. -If no call is going to be made, a dummy app call must be inserted in group for the transaction group to succeed. - -To mantain the long-term transaction costs predictable, when not all signatures are provided but > TRUNC(N_S*2/3)+1, the number of transactions in the group does not change, but a transaction may have zero signatures as input, e.g for a VAA with 14 signatures: - -| TX# | App calls | Stateless logic | -| --- | --------- | --------------- | -| 0 | _args_: guardian_pk[0..6], _txnote_: signed_digest | _args_: sig[0..6] | -| 1 | _args_: guardian_pk[7..13], _txnote_: signed_digest | _args_: sig[7..13] | -| 2 | _args_: guardian_pk[14..18], _txnote_: signed_digest | _args_: **empty** | -| 3 | VAA consume call | N/A | - -The backend will currently **call the Pricekeeper V2 contract to store data** as the last TX group. See below for details on how Pricekeeper works. - -Regarding stateless logic we can say that, - -* Its code is constant and it's known program hash is validated by the stateful program. -* Asserts that the appropiate stateful program is called using known AppId embedded at compile stage. -* Passing signature subset through arguments does not pose any higher risk since any tampered signature will make the operation to fail; -* The signed digest and public keys are retrieved through transaction note field and argument. This limits for the current design the maximum digest size to 1000 bytes and the maximum number of public keys -and guardians to ~64. -* Verification is performed using TEAL5 ECDSA opcodes. If any signature do not verify, transaction fails and subsequently, the entire transaction group aborts. - -For the stateful app-calls we consider, - -* Global state stores guardian public-keys, entry count (set size) and guardian set expiration time. -* Initial state after deployment could be set through a bootstrap call, using last guardian-set-change governance VAA if available. -* Sender must be stateless logic -* Argument 1 must contain guardian public keys for guardians $[k..j]$ -* Argument 2 must contain current guardian size set -* Note field must contain signed digest. -* Passed guardian keys $[k..j]$ must match the current global state. -* Passed guardian size set must match the current global state. -* Last TX in the verification step (total group size-1) triggers VAA processing according to fields (e.g: do governance chores, unpack Pyth price ticker, etc). Last TX in the entire group must be an authorized application call. - -**VAA Structure** - -VAA structure is defined in: - https://github.com/certusone/wormhole/blob/dev.v2/whitepapers/0001_generic_message_passing.md - - Governance VAAs: - https://github.com/certusone/wormhole/blob/dev.v2/whitepapers/0002_governance_messaging.md - - Sample Ethereum Struct Reference: - https://github.com/certusone/wormhole/blob/dev.v2/ethereum/contracts/Structs.sol - -``` - VAA - i Bytes Field - 0 1 Version - 1 4 GuardianSetIndex - 5 1 LenSignatures (LN) - 6 66*LN Signatures where each S = { guardianIndex (1),r(32),s(32),v(1) } - -------------------------------------< hashed/signed body starts here. - 4 timestamp - 4 Nonce - 2 emitterChainId - 32 emitterAddress - 8 sequence - 1 consistencyLevel - N payload - --------------------------------------< hashed/signed body ends here. -``` -**VAA Commitment** - -Each VAA is uniquely identified by tuple (emitter_chain_id, emitter_address, sequence). We are currently interested in VAAs for: - -* Governance operations: - * Upgrade guardian set - * Upgrade contract [this is necessary for non-publishers?] - -* Pyth Ticker Data - -## Pricekeeper V2 App - -The Pricekeeper V2 App mantains a record of product/asset symbols (e.g ALGO/USD, BTC/USDT) and the price and metrics information associated. As the original Pyth Payload is 150-bytes long and it wouldn't fit in the key-value entry of the global state, the Pricekeeper contract slices the Pyth fields to a more compact format, discarding unneeded information. - -The Pricekeeper V2 App will allow storage to succeed only if: - -* Sender is the contract owner. -* Call is part of a group where all application calls are from the expected VAA processor Appid, -* Call is part of a group where the verification slot has all bits set. - -At deployment, the priceKeeper V2 contract must have the "vaapid" global field set accordingly. - -Consumers must interpret the stored bytes as fields organized as: - -``` -Bytes -32 productId -32 priceId -8 price -1 price_type -4 exponent -8 twap value -8 twac value -8 confidence -8 timestamp (based on Solana contract call time) -``` - -## Installation - -Prepare all Node packages with: - -``` -npm install -``` - -## Deployment of Applications - -Use the deployment tools in `tools` subdirectory. - -* To deploy the VAA processor and Pricekeeper V2 app to use with Wormhole, make sure you have Python environment running (preferably >=3.7.0), and `pyteal` installed with `pip3`. -* The deployment program will: generate all TEAL files from PyTEAL sources, deploy the VAA Processor application, deploy the Pricekeeper V2 contract, compile the stateless program and set the correct parameters for the contracts: authid, vphash in VAA Processor and vaapid in the Pricekeeper app. - -For example, using `deploy-wh` with sample output: - -``` -$ node tools\deploy-wh.js tools\gkeys.test 1000 OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU testnet keys\owner.key - -Pricecaster v2 Apps Deployment Tool - -Copyright 2022 Wormhole Project Contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Parameters for deployment: -From: OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU -Network: testnet -Guardian expiration time: 1000 -Guardian Keys: (1) 13947Bd48b18E53fdAeEe77F3473391aC727C638 - -Enter YES to confirm parameters, anything else to abort. YES -Compiling programs ... - -,VAA Processor Program -Compiling approval program... -Written to teal/wormhole/build/vaa-processor-approval.teal -Compiling clear state program... -Written to teal/wormhole/build/vaa-processor-clear.teal -, -,Pricekeeper V2 Program -Compiling approval program... -Written to teal/wormhole/build/pricekeeper-v2-approval.teal -Compiling clear state program... -Written to teal/wormhole/build/pricekeeper-v2-clear.teal -, -Creating VAA Processor... -txId: WS7GE5A6YAADHVNH5OU337MK7T325AE2GML5S3RWK2VTNCQ23HWA -Deployment App Id: 52438261 -Creating Pricekeeper V2... -txId: FICS3HFALLJTMFGEVC65IQ67NCYRJATR32QWZS5VMKGEXHBJJUVA -Deployment App Id: 52438280 -Setting VAA Processor authid parameter... -txId: 5NVJGG32DRWAURD3LUHPELJAZTFMM6HLAJPPGNPXNDC5FJFDNVUQ -Compiling verify VAA stateless code... -,VAA Verify Stateless Program -Compiling... -Written to teal/wormhole/build/vaa-verify.teal -, -Stateless program address: KRNYKVVWZDCNOPLL63ZHFOKG2IIY7REBYTPVR5TJLD67JR6FMRJXYW63TI -Setting VAA Processor stateless code... -txId: 5NVJGG32DRWAURD3LUHPELJAZTFMM6HLAJPPGNPXNDC5FJFDNVUQ -Writing deployment results file DEPLOY-1639769594911... -Writing stateless code binary file VAA-VERIFY-1639769594911.BIN... -Bye. -``` - -* To operate, the stateless contract address must be supplied with funds to pay fees when submitting transactions. -* Use the generated `DEPLOY-XXX` file to set values in the `settings-worm.ts` file (or your current one): app ids and stateless hash. -* Copy the generated `VAA-VERIFY-xxx` file as `vaa-verify.bin` under the `bin` directory. - -## Backend Configuration - -The backend will read configuration from a `settings.ts` file pointed by the `PRICECASTER_SETTINGS` environment variable. - -### Diagnosing failed transactions - -If a transaction fails, a diagnostic system is available where the group TX is dumped in a directory. To use this, set the relevant settings file: - -``` - algo: { - ... - dumpFailedTx: true, - dumpFailedTxDirectory: './dump' - }, -``` - -The dump directory will be filled with files named `failed-xxxx.stxn`. You can use this file and `goal clerk` to trigger the stateless logic checks: - -``` -root@47d99e4cfffc:~/testnetwork/Node# goal clerk dryrun -t failed-1641324602942.stxn -tx[0] trace: - 1 intcblock 1 8 0 32 66 20 => - 9 bytecblock 0x => - 12 txn Fee => (1000 0x3e8) - 14 pushint 1000 => (1000 0x3e8) - . - . - . - 47 txn ApplicationID => (622608992 0x251c4260) - 49 pushint 596576475 => (596576475 0x238f08db) - 55 == => (0 0x0) - 56 assert => - 56 assert failed pc=56 - -REJECT -ERROR: assert failed pc=56 -``` - -In this example output, this means the logic failed due to mismatched stateful application id. - - -For a stateful run, you must do a remote dryrun. This is done by: - -``` -goal clerk dryrun -t failed-1641324602942.stxn --dryrun-dump -o dump.dr -goal clerk dryrun-remote -D dump.dr -v - -``` - -## Running the system - -Check the `package.json` file for `npm run tart-xxx` automated commands. - -## Tests - -Tests can be run for the old `Pricekeeper` contract, and for the new set of Wormhole client contracts: - -`npm run pkeeper-sc-test` - -`npm run wormhole-sc-test` - -Backend tests will come shortly. - -## Appendix - -### Common errors - -**TransactionPool.Remember: transaction XMGXHGC4GVEHQD2T7MZDKTFJWFRY5TFXX2WECCXBWTOZVHC7QLAA: overspend, account X** - -If account X is the stateless program address, this means that this account is without enough balance to pay the fees for each TX group. - - -### Sample Pyth VAA - -This is a sample signed VAA from Pyth that we process. - -**Base64** -``` -AQAAAAABAFv4FwzmQ+mPX0PYbc4TC5rX/z0B5OxZSJ80YZyjJN+CZLespNQSyq/qJHqvqjbM09AoCYQCzFv5oz9Sv8hnwaYBYaX/mgAACFkAATr9qEHB9D3X1UbIpYG6H5KhOfQTP59qsJVVj2o1nfXUAAAAAAAAABIgUDJXSAABASMKv+DsO0YL1V/E+zY1ZxYymRUUVJcgK464vxr2oKO5/mUPA2fUp++YFaWT6hXTZZPwZDqq8BSbsEvmerhR3s0BAAAALxclQ4j////3AAAALu1z2QAAAAAAcNO0PwAAAAA3+qA9AAAAAA6eVVEAAAAAiUrxHAAAAAA3+qA9AAAAAA3abrgBAAAAAABhpf+a -``` - -**Hex-Decoded** -``` -010000000001005bf8170ce643e98f5f43d86dce130b9ad7ff3d01e4ec59489f34619ca324df8264b7aca4d412caafea247aafaa36ccd3d028098402cc5bf9a33f52bfc867c1a60161a5ff9a0000085900013afda841c1f43dd7d546c8a581ba1f92a139f4133f9f6ab095558f6a359df5d400000000000000122050325748000101230abfe0ec3b460bd55fc4fb36356716329915145497202b8eb8bf1af6a0a3b9fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd010000002f17254388fffffff70000002eed73d9000000000070d3b43f0000000037faa03d000000000e9e555100000000894af11c0000000037faa03d000000000dda6eb801000000000061a5ff9a -``` - -**Field-Decoded** -``` -01 version -00000000 guardian-set-index -01 signature-count -00 sig index 0 -5bf8170ce643e98f5f43d86dce130b9ad7ff3d01e4ec59489f34619ca324df8264b7aca4d412caafea247aafaa36ccd3d028098402cc5bf9a33f52bfc867c1a601 sig 0 -61a5ff9a timestamp -00000859 nonce -0001 chain-id -3afda841c1f43dd7d546c8a581ba1f92a139f4133f9f6ab095558f6a359df5d4 emitter-address -0000000000000012 sequence -20 consistency-level - -payload: - -503257480001 header -01 payload-id -230abfe0ec3b460bd55fc4fb36356716329915145497202b8eb8bf1af6a0a3b9 product_id -fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd price_id -01 price_type -0000002f17254388 price -fffffff7 exponent -0000002eed73d900 twap value -0000000070d3b43f twap numerator for next upd -0000000037faa03d twap denom for next upd -000000000e9e5551 twac value -00000000894af11c twac numerator for next upd -0000000037faa03d twac denom for next upd -000000000dda6eb8 confidence -01 status -00 corporate_act -0000000061a5ff9a timestamp (based on Solana contract call time) -``` - diff --git a/staging/algorand/backend/common/basetypes.ts b/staging/algorand/backend/common/basetypes.ts deleted file mode 100644 index dc7959f81..000000000 --- a/staging/algorand/backend/common/basetypes.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable no-unused-vars */ -/* eslint-disable camelcase */ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export type Symbol = { - name: string, - productId: string, - priceId: string, - publishIntervalSecs: number, - pubCount: number -} - -export type VAA = { - version: number, - guardian_set_index: number, - signatures: [], - timestamp: number, - nonce: number, - emitter_chain: number, - emitter_address: [], - sequence: number, - consistency_level: number, - payload: [] - } - -export type PythData = { - vaaBody: Buffer, - signatures: Buffer, - - // Informational fields. - - symbol?: string, - price_type?: number, - price?: BigInt, - exponent?: number, - twap?: BigInt, - twap_num_upd?: BigInt, - twap_denom_upd?: BigInt, - twac?: BigInt, - twac_num_upd?: BigInt, - twac_denom_upd?: BigInt, - confidence?: BigInt, - status?: number, - corporate_act?: number, - timestamp?: BigInt -} diff --git a/staging/algorand/backend/common/priceTicker.ts b/staging/algorand/backend/common/priceTicker.ts deleted file mode 100644 index 64b23654b..000000000 --- a/staging/algorand/backend/common/priceTicker.ts +++ /dev/null @@ -1,132 +0,0 @@ -/* eslint-disable camelcase */ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * A generic Price ticker information class - */ -export class PriceTicker { - constructor ( - symbol: string, - price: BigInt, - price_type: number, - confidence: BigInt, - exponent: number, - twap: BigInt, - twac: BigInt, - timestamp: BigInt, - user_data?: any) { - this._symbol = symbol - this._price = price - this._price_type = price_type - this._confidence = confidence - this._exponent = exponent - this._timestamp = timestamp - this._twap = twap - this._twac = twac - this._user_data = user_data - } - - private _symbol: string - public get symbol (): string { - return this._symbol - } - - public set symbol (value: string) { - this._symbol = value - } - - /** price */ - private _price: BigInt; - public get price (): BigInt { - return this._price - } - - public set price (value: BigInt) { - this._price = value - } - - /** price_type */ - private _price_type: number - public get price_type (): number { - return this._price_type - } - - public set price_type (value: number) { - this._price_type = value - } - - /** a confidence interval */ - private _confidence: BigInt; - public get confidence (): BigInt { - return this._confidence - } - - public set confidence (value: BigInt) { - this._confidence = value - } - - /** exponent (fixed point) */ - private _exponent: number; - public get exponent (): number { - return this._exponent - } - - public set exponent (value: number) { - this._exponent = value - } - - /** time in blockchain network units */ - private _timestamp: BigInt; - public get timestamp (): BigInt { - return this._timestamp - } - - public set timestamp (value: BigInt) { - this._timestamp = value - } - - private _twac: BigInt - public get twac (): BigInt { - return this._twac - } - - public set twac (value: BigInt) { - this._twac = value - } - - private _twap: BigInt - public get twap (): BigInt { - return this._twap - } - - public set twap (value: BigInt) { - this._twap = value - } - - private _user_data: any - public get user_data (): any { - return this._user_data - } - - public set user_data (value: any) { - this._user_data = value - } -} diff --git a/staging/algorand/backend/common/settings-schema.json b/staging/algorand/backend/common/settings-schema.json deleted file mode 100644 index e69de29bb..000000000 diff --git a/staging/algorand/backend/common/settings.ts b/staging/algorand/backend/common/settings.ts deleted file mode 100644 index 89f5c2086..000000000 --- a/staging/algorand/backend/common/settings.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Options } from '@randlabs/js-logger' -import { Symbol } from './basetypes' - -export interface IAppSettings extends Record { - log: Options, - algo: { - token: string, - api: string, - port: string, - dumpFailedTx: boolean, - dumpFailedTxDirectory?: string - }, - apps: { - priceKeeperV2AppId: number, - ownerAddress: string, - ownerKeyFile: string, - vaaVerifyProgramBinFile: string, - vaaVerifyProgramHash: string, - vaaProcessorAppId: number, - }, - pyth: { - chainId: number, - emitterAddress: string, - }, - debug?: { - logAllVaa?: boolean, - } - wormhole: { - spyServiceHost: string - }, - strategy: { - bufferSize: number - }, - symbols: Symbol[] -} diff --git a/staging/algorand/backend/common/sleep.ts b/staging/algorand/backend/common/sleep.ts deleted file mode 100644 index e1824ca0c..000000000 --- a/staging/algorand/backend/common/sleep.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export function sleep (ms: number) { - return new Promise((resolve) => { - setTimeout(resolve, ms) - }) -} diff --git a/staging/algorand/backend/common/statusCodes.ts b/staging/algorand/backend/common/statusCodes.ts deleted file mode 100644 index f991c94e4..000000000 --- a/staging/algorand/backend/common/statusCodes.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* eslint-disable no-unused-vars */ -export enum StatusCode { - OK, - NO_TICKER, - ERROR_CREATE_MESSAGE, - ERROR_SUBMIT_MESSAGE, - GENERAL_ERROR -} - -// export const StatusToString = { -// StatusCode.OK: 'Operation successful' - -// } diff --git a/staging/algorand/backend/engine/IEngine.ts b/staging/algorand/backend/engine/IEngine.ts deleted file mode 100644 index dff33cf16..000000000 --- a/staging/algorand/backend/engine/IEngine.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface IEngine { - start(): Promise - } diff --git a/staging/algorand/backend/engine/WormholeEngine.ts b/staging/algorand/backend/engine/WormholeEngine.ts deleted file mode 100644 index 7d2499593..000000000 --- a/staging/algorand/backend/engine/WormholeEngine.ts +++ /dev/null @@ -1,124 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { IEngine } from './IEngine' -import { StrategyLastPrice } from '../strategy/strategyLastPrice' -import { IAppSettings } from '../common/settings' -import { IPriceFetcher } from '../fetcher/IPriceFetcher' -import { IPublisher, PublishInfo } from '../publisher/IPublisher' -import { PriceTicker } from '../common/priceTicker' -import { StatusCode } from '../common/statusCodes' -import { WormholePythPriceFetcher } from '../fetcher/WormholePythPriceFetcher' -import { Symbol } from 'backend/common/basetypes' -import { Pricekeeper2Publisher } from '../publisher/Pricekeeper2Publisher' -import * as Logger from '@randlabs/js-logger' -import { sleep } from '../common/sleep' -const fs = require('fs') -const algosdk = require('algosdk') - -type WorkerRoutineStatus = { - status: StatusCode, - reason?: string, - tick?: PriceTicker, - pub?: PublishInfo -} - -async function workerRoutine (sym: Symbol, fetcher: IPriceFetcher, publisher: IPublisher): Promise { - const tick = fetcher.queryData(sym.productId + sym.priceId) - if (tick === undefined) { - return { status: StatusCode.NO_TICKER } - } - const pub = await publisher.publish(tick) - return { status: pub.status, reason: pub.reason, tick, pub } -} - -export class WormholeClientEngine implements IEngine { - private settings: IAppSettings - private shouldQuit: boolean - constructor (settings: IAppSettings) { - this.settings = settings - this.shouldQuit = false - } - - async start () { - process.on('SIGINT', () => { - console.log('Received SIGINT') - Logger.finalize() - this.shouldQuit = true - }) - - let mnemo, verifyProgramBinary - try { - mnemo = fs.readFileSync(this.settings.apps.ownerKeyFile) - verifyProgramBinary = Uint8Array.from(fs.readFileSync(this.settings.apps.vaaVerifyProgramBinFile)) - } catch (e) { - throw new Error('Cannot read account and/or verify program source: ' + e) - } - - const publisher = new Pricekeeper2Publisher(this.settings.apps.vaaProcessorAppId, - this.settings.apps.priceKeeperV2AppId, - this.settings.apps.ownerAddress, - verifyProgramBinary, - this.settings.apps.vaaVerifyProgramHash, - algosdk.mnemonicToSecretKey(mnemo.toString()), - this.settings.algo.token, - this.settings.algo.api, - this.settings.algo.port, - this.settings.algo.dumpFailedTx, - this.settings.algo.dumpFailedTxDirectory - ) - const fetcher = new WormholePythPriceFetcher(this.settings.wormhole.spyServiceHost, - this.settings.pyth.chainId, - this.settings.pyth.emitterAddress, - this.settings.symbols, - new StrategyLastPrice(this.settings.strategy.bufferSize)) - - Logger.info('Waiting for fetcher to boot...') - await fetcher.start() - - Logger.info('Waiting for publisher to boot...') - await publisher.start() - - for (const sym of this.settings.symbols) { - sym.pubCount = 0 - Logger.info(`Starting worker for symbol ${sym.name}, interval ${sym.publishIntervalSecs}s`) - setInterval(this.callWorkerRoutine, sym.publishIntervalSecs * 1000, sym, fetcher, publisher) - } - - while (!this.shouldQuit) { - await sleep(1000) - } - } - - async callWorkerRoutine (sym: Symbol, fetcher: IPriceFetcher, publisher: IPublisher) { - const wrs = await workerRoutine(sym, fetcher, publisher) - switch (wrs.status) { - case StatusCode.OK: { - Logger.info(`${sym.name} [#${sym.pubCount++}] price: ${wrs.tick!.price} ± ${wrs.tick!.confidence} exp: ${wrs.tick!.exponent} t: ${wrs.tick!.timestamp} TxID: ${wrs.pub!.txid}`) - break - } - case StatusCode.NO_TICKER: - Logger.warn(`${sym.name}: No ticker available from fetcher data source`) - break - default: - Logger.error(`${sym.name}: Error. Reason: ` + wrs.reason) - } - } -} diff --git a/staging/algorand/backend/fetcher/IPriceFetcher.ts b/staging/algorand/backend/fetcher/IPriceFetcher.ts deleted file mode 100644 index 3c15e12d9..000000000 --- a/staging/algorand/backend/fetcher/IPriceFetcher.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { IStrategy } from '../strategy/strategy' - -export interface IPriceFetcher { - start(): void - stop(): void - hasData(): boolean - - /** - * Set price aggregation strategy for this fetcher. - * @param IStrategy The local price aggregation strategy - */ - setStrategy(s: IStrategy): void - - /** - * Get the current price of a symbol, according to running strategy. - */ - queryData(id: string): any | undefined -} diff --git a/staging/algorand/backend/fetcher/WormholePythPriceFetcher.ts b/staging/algorand/backend/fetcher/WormholePythPriceFetcher.ts deleted file mode 100644 index a79d4520d..000000000 --- a/staging/algorand/backend/fetcher/WormholePythPriceFetcher.ts +++ /dev/null @@ -1,152 +0,0 @@ -/* eslint-disable camelcase */ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - importCoreWasm, - setDefaultWasm -} from '@certusone/wormhole-sdk/lib/cjs/solana/wasm' -import { - createSpyRPCServiceClient, subscribeSignedVAA -} from '@certusone/wormhole-spydk' -import { SpyRPCServiceClient } from '@certusone/wormhole-spydk/lib/cjs/proto/spy/v1/spy' -import { PythData, Symbol, VAA } from 'backend/common/basetypes' -import { IStrategy } from '../strategy/strategy' -import { IPriceFetcher } from './IPriceFetcher' -import * as Logger from '@randlabs/js-logger' - -export class WormholePythPriceFetcher implements IPriceFetcher { - private symbolMap: Map - - private client: SpyRPCServiceClient - private pythEmitterAddress: { s: string, data: number[] } - private pythChainId: number - private strategy: IStrategy - private stream: any - private _hasData: boolean - private coreWasm: any - - constructor (spyRpcServiceHost: string, pythChainId: number, pythEmitterAddress: string, symbols: Symbol[], strategy: IStrategy) { - setDefaultWasm('node') - this._hasData = false - this.client = createSpyRPCServiceClient(spyRpcServiceHost) - this.pythChainId = pythChainId - this.pythEmitterAddress = { - data: Buffer.from(pythEmitterAddress, 'hex').toJSON().data, - s: pythEmitterAddress - } - this.strategy = strategy - this.symbolMap = new Map() - - symbols.forEach((sym) => { - this.symbolMap.set(sym.productId + sym.priceId, { - name: sym.name, - publishIntervalSecs: sym.publishIntervalSecs, - pythData: undefined - }) - }) - } - - async start () { - this.coreWasm = await importCoreWasm() - // eslint-disable-next-line camelcase - this.stream = await subscribeSignedVAA(this.client, - { - filters: - [{ - emitterFilter: { - chainId: this.pythChainId, - emitterAddress: this.pythEmitterAddress.s - } - }] - }) - - this.stream.on('data', (data: { vaaBytes: Buffer }) => { - try { - this._hasData = true - this.onPythData(data.vaaBytes) - } catch (e) { - Logger.error(`Failed to parse VAA data. \nReason: ${e}\nData: ${data}`) - } - }) - - this.stream.on('error', (e: Error) => { - Logger.error('Stream error: ' + e) - }) - } - - stop (): void { - this._hasData = false - } - - setStrategy (s: IStrategy) { - this.strategy = s - } - - hasData (): boolean { - // Return when any price is ready - return this._hasData - } - - queryData (id: string): any | undefined { - const v = this.symbolMap.get(id) - if (v === undefined) { - Logger.error(`Unsupported symbol with identifier ${id}`) - } else { - return v.pythData - } - } - - private async onPythData (vaaBytes: Buffer) { - // console.log(vaaBytes.toString('hex')) - const v: VAA = this.coreWasm.parse_vaa(new Uint8Array(vaaBytes)) - const payload = Buffer.from(v.payload) - const productId = payload.slice(7, 7 + 32) - const priceId = payload.slice(7 + 32, 7 + 32 + 32) - // console.log(productId.toString('hex'), priceId.toString('hex')) - - const k = productId.toString('hex') + priceId.toString('hex') - const sym = this.symbolMap.get(k) - - if (sym !== undefined) { - sym.pythData = { - symbol: sym.name, - vaaBody: vaaBytes.slice(6 + v.signatures.length * 66), - signatures: vaaBytes.slice(6, 6 + v.signatures.length * 66), - price_type: payload.readInt8(71), - price: payload.readBigUInt64BE(72), - exponent: payload.readInt32BE(80), - confidence: payload.readBigUInt64BE(132), - status: payload.readInt8(140), - corporate_act: payload.readInt8(141), - timestamp: payload.readBigUInt64BE(142) - } - } - - // if (pythPayload.status === 0) { - // console.log('WARNING: Symbol trading status currently halted (0). Publication will be skipped.') - // } else - // eslint-disable-next-line no-lone-blocks - } -} diff --git a/staging/algorand/backend/main.ts b/staging/algorand/backend/main.ts deleted file mode 100644 index 64c08d5da..000000000 --- a/staging/algorand/backend/main.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* eslint-disable func-call-spacing */ -/* eslint-disable no-unused-vars */ -/** - * Pricecaster Service. - * - * Main program file. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import * as Config from '@randlabs/js-config-reader' -import { IAppSettings } from './common/settings' -import { exit } from 'process' -import { WormholeClientEngine } from './engine/WormholeEngine' -import * as Logger from '@randlabs/js-logger' -const charm = require('charm')(); - -(async () => { - charm.pipe(process.stdout) - charm.reset() - charm.foreground('cyan').display('bright') - console.log('Pricecaster Service Backend -- (c) 2022 Wormhole Project Contributors\n') - charm.foreground('white') - - let settings: IAppSettings - try { - await Config.initialize({ envVar: 'PRICECASTER_SETTINGS' }) - settings = Config.get() - await Logger.initialize(settings.log) - } catch (e: any) { - console.error('Cannot initialize configuration: ' + e.toString()) - exit(1) - } - - const engine = new WormholeClientEngine(settings) - await engine.start() -})() diff --git a/staging/algorand/backend/publisher/IPublisher.ts b/staging/algorand/backend/publisher/IPublisher.ts deleted file mode 100644 index f1ef8160c..000000000 --- a/staging/algorand/backend/publisher/IPublisher.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-unused-vars */ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { PriceTicker } from '../common/priceTicker' -import { StatusCode } from '../common/statusCodes' - -export type PublishInfo = { - status: StatusCode, - reason?: '', - msgb64?: '', - block?: BigInt - txid?: string -} - -export interface IPublisher { - start(): void - stop(): void - publish(data: any): Promise -} diff --git a/staging/algorand/backend/publisher/NullPublisher.ts b/staging/algorand/backend/publisher/NullPublisher.ts deleted file mode 100644 index b2dc14252..000000000 --- a/staging/algorand/backend/publisher/NullPublisher.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { IPublisher, PublishInfo } from '../publisher/IPublisher' -import { PriceTicker } from '../common/priceTicker' - -export class NullPublisher implements IPublisher { - start (): void { - throw new Error('Method not implemented.') - } - - stop (): void { - throw new Error('Method not implemented.') - } - - publish (tick: PriceTicker): Promise { - throw new Error('Method not implemented.') - } -} diff --git a/staging/algorand/backend/publisher/Pricekeeper2Publisher.ts b/staging/algorand/backend/publisher/Pricekeeper2Publisher.ts deleted file mode 100644 index dc7b53129..000000000 --- a/staging/algorand/backend/publisher/Pricekeeper2Publisher.ts +++ /dev/null @@ -1,112 +0,0 @@ -import algosdk from 'algosdk' -import { IPublisher, PublishInfo } from './IPublisher' -import { StatusCode } from '../common/statusCodes' -import { PythData } from 'backend/common/basetypes' -const PricecasterLib = require('../../lib/pricecaster') -const tools = require('../../tools/app-tools') - -export class Pricekeeper2Publisher implements IPublisher { - private algodClient: algosdk.Algodv2 - private pclib: any - private account: algosdk.Account - private vaaProcessorAppId: number - private vaaProcessorOwner: string - private numOfVerifySteps: number = 0 - private guardianCount: number = 0 - private stepSize: number = 0 - private dumpFailedTx: boolean - private dumpFailedTxDirectory: string | undefined - private compiledVerifyProgram: { bytes: Uint8Array, hash: string } = { bytes: new Uint8Array(), hash: '' } - constructor (vaaProcessorAppId: number, - priceKeeperAppId: number, - vaaProcessorOwner: string, - verifyProgramBinary: Uint8Array, - verifyProgramHash: string, - signKey: algosdk.Account, - algoClientToken: string, - algoClientServer: string, - algoClientPort: string, - dumpFailedTx: boolean = false, - dumpFailedTxDirectory: string = './') { - this.account = signKey - this.compiledVerifyProgram.bytes = verifyProgramBinary - this.compiledVerifyProgram.hash = verifyProgramHash - this.vaaProcessorAppId = vaaProcessorAppId - this.vaaProcessorOwner = vaaProcessorOwner - this.dumpFailedTx = dumpFailedTx - this.dumpFailedTxDirectory = dumpFailedTxDirectory - this.algodClient = new algosdk.Algodv2(algoClientToken, algoClientServer, algoClientPort) - this.pclib = new PricecasterLib.PricecasterLib(this.algodClient) - this.pclib.setAppId('vaaProcessor', vaaProcessorAppId) - this.pclib.setAppId('pricekeeper', priceKeeperAppId) - this.pclib.enableDumpFailedTx(this.dumpFailedTx) - this.pclib.setDumpFailedTxDirectory(this.dumpFailedTxDirectory) - } - - async start () { - } - - stop () { - } - - signCallback (sender: string, tx: algosdk.Transaction) { - const txSigned = tx.signTxn(this.account.sk) - return txSigned - } - - async publish (data: PythData): Promise { - const publishInfo: PublishInfo = { status: StatusCode.OK } - - const txParams = await this.algodClient.getTransactionParams().do() - txParams.fee = 1000 - txParams.flatFee = true - - this.guardianCount = await tools.readAppGlobalStateByKey(this.algodClient, this.vaaProcessorAppId, this.vaaProcessorOwner, 'gscount') - this.stepSize = await tools.readAppGlobalStateByKey(this.algodClient, this.vaaProcessorAppId, this.vaaProcessorOwner, 'vssize') - this.numOfVerifySteps = Math.ceil(this.guardianCount / this.stepSize) - if (this.guardianCount === 0 || this.stepSize === 0) { - throw new Error('cannot get guardian count and/or step-size from global state') - } - // - // (!) - // Stateless programs cannot access state nor stack from stateful programs, so - // for the VAA Verify program to use the guardian set, we pass the global state as TX argument, - // (and check it against the current global list to be sure it's ok). This way it can be read by - // VAA verifier as a stateless program CAN DO READS of call transaction arguments in a group. - // The same technique is used for the note field, where the payload is set. - // - - try { - const guardianKeys = [] - const buf = Buffer.alloc(8) - for (let i = 0; i < this.guardianCount; i++) { - buf.writeBigUInt64BE(BigInt(i++)) - const gk = await tools.readAppGlobalStateByKey(this.algodClient, this.vaaProcessorAppId, this.vaaProcessorOwner, buf.toString()) - guardianKeys.push(Buffer.from(gk, 'base64').toString('hex')) - } - - const strSig = data.signatures.toString('hex') - - const gid = this.pclib.beginTxGroup() - const sigSubsets = [] - for (let i = 0; i < this.numOfVerifySteps; i++) { - const st = this.stepSize * i - const sigSetLen = 132 * this.stepSize - - const keySubset = guardianKeys.slice(st, i < this.numOfVerifySteps - 1 ? st + this.stepSize : undefined) - - sigSubsets.push(strSig.slice(i * sigSetLen, i < this.numOfVerifySteps - 1 ? ((i * sigSetLen) + sigSetLen) : undefined)) - this.pclib.addVerifyTx(gid, this.compiledVerifyProgram.hash, txParams, data.vaaBody, keySubset, this.guardianCount) - } - this.pclib.addPriceStoreTx(gid, this.vaaProcessorOwner, txParams, data.symbol, data.vaaBody.slice(51)) - const txId = await this.pclib.commitVerifyTxGroup(gid, this.compiledVerifyProgram.bytes, sigSubsets, this.vaaProcessorOwner, this.signCallback.bind(this)) - publishInfo.txid = txId - } catch (e: any) { - publishInfo.status = StatusCode.ERROR_SUBMIT_MESSAGE - publishInfo.reason = e.response.text ? e.response.text : e.toString() - return publishInfo - } - - return publishInfo - } -} diff --git a/staging/algorand/backend/strategy/strategy.ts b/staging/algorand/backend/strategy/strategy.ts deleted file mode 100644 index 92f4503f9..000000000 --- a/staging/algorand/backend/strategy/strategy.ts +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { PriceTicker } from '../common/priceTicker' - -/** - * Implements a strategy for obtaining an asset price from - * a set of received prices in a buffer. - */ -export interface IStrategy { - /** - * - * @param size The size of the buffer - */ - createBuffer(size: number): void - - /** - * Clear price buffer - */ - clearBuffer(): void - - /** - * Returns the current number of items in buffer - */ - bufferCount(): number - - /** - * Put a new price in buffer. - * @param priceData The price data to put - * @returns true if successful. - */ - put(ticker: PriceTicker): boolean - - /** - * Get the calculated price according to selected strategy. - */ - getPrice(): PriceTicker | undefined -} diff --git a/staging/algorand/backend/strategy/strategyBase.ts b/staging/algorand/backend/strategy/strategyBase.ts deleted file mode 100644 index e47d23f04..000000000 --- a/staging/algorand/backend/strategy/strategyBase.ts +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { PriceTicker } from '../common/priceTicker' -import { IStrategy } from './strategy' - -/** - * A base class for queue-based buffer strategies - */ -export abstract class StrategyBase implements IStrategy { - protected buffer!: PriceTicker[] - protected bufSize!: number - - constructor (bufSize: number = 10) { - this.createBuffer(bufSize) - } - - createBuffer (maxSize: number): void { - this.buffer = [] - this.bufSize = maxSize - } - - clearBuffer (): void { - this.buffer.length = 0 - } - - bufferCount (): number { - return this.buffer.length - } - - put (ticker: PriceTicker): boolean { - if (this.buffer.length === this.bufSize) { - this.buffer.shift() - } - this.buffer.push(ticker) - return true - } - - abstract getPrice(): PriceTicker | undefined -} diff --git a/staging/algorand/backend/strategy/strategyLastPrice.ts b/staging/algorand/backend/strategy/strategyLastPrice.ts deleted file mode 100644 index a22074a62..000000000 --- a/staging/algorand/backend/strategy/strategyLastPrice.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { PriceTicker } from '../common/priceTicker' -import { StrategyBase } from './strategyBase' -/** - * Pricecaster Service. - * - * Fetcher backend component. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This strategy just caches the last provided price, - * acting as a single-item buffer. - */ -export class StrategyLastPrice extends StrategyBase { - getPrice (): PriceTicker | undefined { - const ret = this.buffer[this.buffer.length - 1] - this.clearBuffer() - return ret - } -} diff --git a/staging/algorand/dump/dummy.txt b/staging/algorand/dump/dummy.txt deleted file mode 100644 index 16bbac596..000000000 --- a/staging/algorand/dump/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Output Failed transaction dumps here. \ No newline at end of file diff --git a/staging/algorand/keys/owner.key.sample b/staging/algorand/keys/owner.key.sample deleted file mode 100644 index 951a319dc..000000000 --- a/staging/algorand/keys/owner.key.sample +++ /dev/null @@ -1 +0,0 @@ -REPLACE WITH MNEMONIC WORDS. diff --git a/staging/algorand/lib/pricecaster.d.ts b/staging/algorand/lib/pricecaster.d.ts deleted file mode 100644 index c231e58d5..000000000 --- a/staging/algorand/lib/pricecaster.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'PricecasterLib'; \ No newline at end of file diff --git a/staging/algorand/lib/pricecaster.js b/staging/algorand/lib/pricecaster.js deleted file mode 100644 index a8b429da4..000000000 --- a/staging/algorand/lib/pricecaster.js +++ /dev/null @@ -1,587 +0,0 @@ -/** - * - * Pricecaster Service Utility Library. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -const algosdk = require('algosdk') -const fs = require('fs') -// eslint-disable-next-line camelcase -const tools = require('../tools/app-tools') -const crypto = require('crypto') - -const ContractInfo = { - pricekeeper: { - approvalProgramFile: 'teal/wormhole/build/pricekeeper-v2-approval.teal', - clearStateProgramFile: 'teal/wormhole/build/pricekeeper-v2-clear.teal', - compiledApproval: { - bytes: undefined, - hash: undefined - }, - compiledClearState: { - bytes: undefined, - hash: undefined - }, - appId: 0 - }, - vaaProcessor: { - approvalProgramFile: 'teal/wormhole/build/vaa-processor-approval.teal', - clearStateProgramFile: 'teal/wormhole/build/vaa-processor-clear.teal', - approvalProgramHash: '', - compiledApproval: { - bytes: undefined, - hash: undefined - }, - compiledClearState: { - bytes: undefined, - hash: undefined - }, - appId: 0 - } -} - -// -------------------------------------------------------------------------------------- - -class PricecasterLib { - constructor(algodClient, ownerAddr = undefined) { - this.algodClient = algodClient - this.ownerAddr = ownerAddr - this.minFee = 1000 - this.groupTxSet = {} - this.lsigs = {} - this.dumpFailedTx = false - this.dumpFailedTxDirectory = './' - - /** Set the file dumping feature on failed group transactions - * @param {boolean} f Set to true to enable function, false to disable. - */ - this.enableDumpFailedTx = function (f) { - this.dumpFailedTx = f - } - - /** Set the file dumping feature output directory - * @param {string} dir The output directory. - */ - this.setDumpFailedTxDirectory = function (dir) { - this.dumpFailedTxDirectory = dir - } - - /** Sets a contract approval program filename - * @param {string} filename New file name to use. - */ - this.setApprovalProgramFile = function (contract, filename) { - ContractInfo[contract].approvalProgramFile = filename - } - - /** Sets a contract clear state program filename - * @param {string} filename New file name to use. - */ - this.setClearStateProgramFile = function (contract, filename) { - ContractInfo[contract].clearStateProgramFile = filename - } - - /** - * Set Application Id for a contract. - * @param {number} applicationId application id - * @returns {void} - */ - this.setAppId = function (contract, applicationId) { - ContractInfo[contract].appId = applicationId - } - - /** - * Get the Application id for a specific contract - * @returns The requested application Id - */ - this.getAppId = function (contract) { - return ContractInfo[contract].appId - } - - /** - * Get minimum fee to pay for transactions. - * @return {Number} minimum transaction fee - */ - this.minTransactionFee = function () { - return this.minFee - } - - /** - * Internal function. - * Read application local state related to the account. - * @param {String} accountAddr account to retrieve local state - * @return {Array} an array containing all the {key: value} pairs of the local state - */ - this.readLocalState = function (accountAddr) { - return tools.readAppLocalState(this.algodClient, this.appId, accountAddr) - } - - /** - * Internal function. - * Read application global state. - * @return {Array} an array containing all the {key: value} pairs of the global state - * @returns {void} - */ - this.readGlobalState = function () { - return tools.readAppGlobalState(this.algodClient, this.appId, this.ownerAddr) - } - - /** - * Print local state of accountAddr on stdout. - * @param {String} accountAddr account to retrieve local state - * @returns {void} - */ - this.printLocalState = async function (accountAddr) { - await tools.printAppLocalState(this.algodClient, this.appId, accountAddr) - } - - /** - * Print application global state on stdout. - * @returns {void} - */ - this.printGlobalState = async function () { - await tools.printAppGlobalState(this.algodClient, this.appId, this.ownerAddr) - } - - /** - * Internal function. - * Read application local state variable related to accountAddr. - * @param {String} accountAddr account to retrieve local state - * @param {String} key variable key to get the value associated - * @return {String/Number} it returns the value associated to the key that could be an address, a number or a - * base64 string containing a ByteArray - */ - this.readLocalStateByKey = function (accountAddr, key) { - return tools.readAppLocalStateByKey(this.algodClient, this.appId, accountAddr, key) - } - - /** - * Internal function. - * Read application global state variable. - * @param {String} key variable key to get the value associated - * @return {String/Number} it returns the value associated to the key that could be an address, - * a number or a base64 string containing a ByteArray - */ - this.readGlobalStateByKey = function (key) { - return tools.readAppGlobalStateByKey(this.algodClient, this.appId, this.ownerAddr, key) - } - - /** - * Compile program that programFilename contains. - * @param {String} programFilename filepath to the program to compile - * @return {String} base64 string containing the compiled program - */ - this.compileProgram = async function (programBytes) { - const compileResponse = await this.algodClient.compile(programBytes).do() - const compiledBytes = new Uint8Array(Buffer.from(compileResponse.result, 'base64')) - return { bytes: compiledBytes, hash: compileResponse.hash } - } - - /** - * Compile clear state program. - */ - this.compileClearProgram = async function (contract) { - const program = fs.readFileSync(ContractInfo[contract].clearStateProgramFile, 'utf8') - ContractInfo[contract].compiledClearState = await this.compileProgram(program) - } - - /** - * Compile approval program. - */ - this.compileApprovalProgram = async function (contract) { - const program = fs.readFileSync(ContractInfo[contract].approvalProgramFile, 'utf8') - ContractInfo[contract].compiledApproval = await this.compileProgram(program) - } - - /** - * Helper function to retrieve the application id from a createApp transaction response. - * @param {Object} txResponse object containig the transactionResponse of the createApp call - * @return {Number} application id of the created application - */ - this.appIdFromCreateAppResponse = function (txResponse) { - return txResponse['application-index'] - } - - /** - * Create an application based on the default approval and clearState programs or based on the specified files. - * @param {String} sender account used to sign the createApp transaction - * @param {Function} signCallback callback with prototype signCallback(sender, tx) used to sign transactions - * @return {String} transaction id of the created application - */ - this.createApp = async function (sender, contract, localInts, localBytes, globalInts, globalBytes, appArgs, signCallback) { - const onComplete = algosdk.OnApplicationComplete.NoOpOC - - // get node suggested parameters - const params = await algodClient.getTransactionParams().do() - params.fee = this.minFee - params.flatFee = true - - await this.compileApprovalProgram(contract) - await this.compileClearProgram(contract) - - // create unsigned transaction - const txApp = algosdk.makeApplicationCreateTxn( - sender, params, onComplete, - ContractInfo[contract].compiledApproval.bytes, - ContractInfo[contract].compiledClearState.bytes, - localInts, localBytes, globalInts, globalBytes, appArgs - ) - const txId = txApp.txID().toString() - - // Sign the transaction - const txAppSigned = signCallback(sender, txApp) - - // Submit the transaction - await algodClient.sendRawTransaction(txAppSigned).do() - return txId - } - - /** - * Create the VAA Processor application based on the default approval and clearState programs or based on the specified files. - * @param {String} sender account used to sign the createApp transaction - * @param {String} gexpTime Guardian key set expiration time - * @param {String} gsindex Index of the guardian key set - * @param {String} gkeys Guardian keys listed as a single array - * @param {Function} signCallback callback with prototype signCallback(sender, tx) used to sign transactions - * @return {String} transaction id of the created application - */ - this.createVaaProcessorApp = async function (sender, gexpTime, gsindex, gkeys, signCallback) { - return await this.createApp(sender, 'vaaProcessor', 0, 0, 5, 20, - [new Uint8Array(Buffer.from(gkeys, 'hex')), - algosdk.encodeUint64(parseInt(gexpTime)), - algosdk.encodeUint64(parseInt(gsindex))], signCallback) - } - - /** - * Create the Pricekeeper application based on the default approval and clearState programs or based on the specified files. - * @param {String} sender account used to sign the createApp transaction - * @param {String} vaaProcessorAppId The application id of the VAA Processor program associated. - * @param {Function} signCallback callback with prototype signCallback(sender, tx) used to sign transactions - * @return {String} transaction id of the created application - */ - this.createPricekeeperApp = async function (sender, vaaProcessorAppId, signCallback) { - return await this.createApp(sender, 'pricekeeper', 0, 0, 1, 63, - [algosdk.encodeUint64(parseInt(vaaProcessorAppId))], signCallback) - } - - /** - * Internal function. - * Call application specifying args and accounts. - * @param {String} sender caller address - * @param {Array} appArgs array of arguments to pass to application call - * @param {Array} appAccounts array of accounts to pass to application call - * @param {Function} signCallback callback with prototype signCallback(sender, tx) used to sign transactions - * @return {String} transaction id of the transaction - */ - this.callApp = async function (sender, contract, appArgs, appAccounts, signCallback) { - // get node suggested parameters - const params = await this.algodClient.getTransactionParams().do() - - params.fee = this.minFee - params.flatFee = true - - // create unsigned transaction - const txApp = algosdk.makeApplicationNoOpTxn(sender, params, ContractInfo[contract].appId, appArgs, appAccounts.length === 0 ? undefined : appAccounts) - const txId = txApp.txID().toString() - - // Sign the transaction - const txAppSigned = signCallback(sender, txApp) - - // Submit the transaction - await this.algodClient.sendRawTransaction(txAppSigned).do() - - return txId - } - - /** - * ClearState sender. Remove all the sender associated local data. - * @param {String} sender account to ClearState - * @param {Function} signCallback callback with prototype signCallback(sender, tx) used to sign transactions - * @return {[String]} transaction id of one of the transactions of the group - */ - this.clearApp = async function (sender, signCallback, forcedAppId) { - // get node suggested parameters - const params = await this.algodClient.getTransactionParams().do() - - params.fee = this.minFee - params.flatFee = true - - let appId = this.appId - if (forcedAppId) { - appId = forcedAppId - } - - // create unsigned transaction - const txApp = algosdk.makeApplicationClearStateTxn(sender, params, appId) - const txId = txApp.txID().toString() - - // Sign the transaction - const txAppSigned = signCallback(sender, txApp) - - // Submit the transaction - await this.algodClient.sendRawTransaction(txAppSigned).do() - - return txId - } - - /** - * Permanent delete the application. - * @param {String} sender owner account - * @param {Function} signCallback callback with prototype signCallback(sender, tx) used to sign transactions - * @param {Function} applicationId use this application id instead of the one set - * @return {String} transaction id of one of the transactions of the group - */ - this.deleteApp = async function (sender, signCallback, applicationId) { - // get node suggested parameters - const params = await this.algodClient.getTransactionParams().do() - - params.fee = this.minFee - params.flatFee = true - - if (!applicationId) { - applicationId = this.appId - } - - // create unsigned transaction - const txApp = algosdk.makeApplicationDeleteTxn(sender, params, applicationId) - const txId = txApp.txID().toString() - - // Sign the transaction - const txAppSigned = signCallback(sender, txApp) - - // Submit the transaction - await this.algodClient.sendRawTransaction(txAppSigned).do() - - return txId - } - - /** - * Helper function to wait until transaction txId is included in a block/round. - * @param {String} txId transaction id to wait for - * @return {VOID} VOID - */ - this.waitForConfirmation = async function (txId) { - const status = (await this.algodClient.status().do()) - let lastRound = status['last-round'] - // eslint-disable-next-line no-constant-condition - while (true) { - const pendingInfo = await this.algodClient.pendingTransactionInformation(txId).do() - if (pendingInfo['confirmed-round'] !== null && pendingInfo['confirmed-round'] > 0) { - // Got the completed Transaction - - return pendingInfo['confirmed-round'] - } - lastRound += 1 - await this.algodClient.statusAfterBlock(lastRound).do() - } - } - - /** - * Helper function to wait until transaction txId is included in a block/round - * and returns the transaction response associated to the transaction. - * @param {String} txId transaction id to get transaction response - * @return {Object} returns an object containing response information - */ - this.waitForTransactionResponse = async function (txId) { - // Wait for confirmation - await this.waitForConfirmation(txId) - - // display results - return this.algodClient.pendingTransactionInformation(txId).do() - } - - /** - * VAA Processor: Sets the stateless logic program hash - * @param {*} sender Sender account - * @param {*} hash The stateless logic program hash - * @returns Transaction identifier. - */ - this.setVAAVerifyProgramHash = async function (sender, hash, signCallback) { - if (!algosdk.isValidAddress(sender)) { - throw new Error('Invalid sender address: ' + sender) - } - const appArgs = [] - appArgs.push(new Uint8Array(Buffer.from('setvphash')), - algosdk.decodeAddress(hash).publicKey) - return await this.callApp(sender, 'vaaProcessor', appArgs, [], signCallback) - } - - /** - * VAA Processor: Sets the authorized application id for last call - * @param {*} sender Sender account - * @param {*} appId The assigned appId - * @returns Transaction identifier. - */ - this.setAuthorizedAppId = async function (sender, appId, signCallback) { - if (!algosdk.isValidAddress(sender)) { - throw new Error('Invalid sender address: ' + sender) - } - const appArgs = [] - appArgs.push(new Uint8Array(Buffer.from('setauthid')), - algosdk.encodeUint64(appId)) - return await this.callApp(sender, 'vaaProcessor', appArgs, [], signCallback) - } - - /** - * Starts a begin...commit section for commiting grouped transactions. - */ - this.beginTxGroup = function () { - const gid = crypto.randomBytes(16).toString('hex') - this.groupTxSet[gid] = [] - return gid - } - - /** - * Adds a transaction to the group. - * @param {} tx Transaction to add. - */ - this.addTxToGroup = function (gid, tx) { - if (this.groupTxSet[gid] === undefined) { - throw new Error('unknown tx group id') - } - this.groupTxSet[gid].push(tx) - } - - /** - * @param {*} sender The sender account. - * @param {function} signCallback The sign callback routine. - * @returns Transaction id. - */ - this.commitTxGroup = async function (gid, sender, signCallback) { - if (this.groupTxSet[gid] === undefined) { - throw new Error('unknown tx group id') - } - algosdk.assignGroupID(this.groupTxSet[gid]) - - // Sign the transactions - const signedTxns = [] - for (const tx of this.groupTxSet[gid]) { - signedTxns.push(signCallback(sender, tx)) - } - - // Submit the transaction - const tx = await this.algodClient.sendRawTransaction(signedTxns).do() - delete this.groupTxSet[gid] - return tx.txId - } - - /** - * @param {*} sender The sender account. - * @param {*} programBytes Compiled program bytes. - * @param {*} totalSignatureCount Total signatures present in the VAA. - * @param {*} sigSubsets An hex string with the signature subsets i..j for logicsig arguments. - * @param {*} lastTxSender The sender of the last TX in the group. - * @param {*} signCallback The signing callback function to use in the last TX of the group. - * @returns Transaction id. - */ - this.commitVerifyTxGroup = async function (gid, programBytes, totalSignatureCount, sigSubsets, lastTxSender, signCallback) { - if (this.groupTxSet[gid] === undefined) { - throw new Error('unknown group id') - } - algosdk.assignGroupID(this.groupTxSet[gid]) - const signedGroup = [] - let i = 0 - for (const tx of this.groupTxSet[gid]) { - // All transactions except last must be signed by stateless code. - - // console.log(`sigSubsets[${i}]: ${sigSubsets[i]) - - if (i === this.groupTxSet[gid].length - 1) { - signedGroup.push(signCallback(lastTxSender, tx)) - } else { - const lsig = new algosdk.LogicSigAccount(programBytes, [Buffer.from(sigSubsets[i], 'hex'), algosdk.encodeUint64(totalSignatureCount)]) - const stxn = algosdk.signLogicSigTransaction(tx, lsig) - signedGroup.push(stxn.blob) - } - i++ - } - - // Submit the transaction - let tx - try { - tx = await this.algodClient.sendRawTransaction(signedGroup).do() - } catch (e) { - if (this.dumpFailedTx) { - const id = tx ? tx.txId : Date.now().toString() - const filename = `${this.dumpFailedTxDirectory}/failed-${id}.stxn` - if (fs.existsSync(filename)) { - fs.unlinkSync(filename) - } - for (let i = 0; i < signedGroup.length; ++i) { - fs.appendFileSync(filename, signedGroup[i]) - } - } - throw e - } - delete this.groupTxSet[gid] - return tx.txId - } - - /** - * VAA Processor: Add a verification step to a transaction group. - * @param {*} sender The sender account (typically the VAA verification stateless program) - * @param {*} payload The VAA payload. - * @param {*} gksubset An hex string containing the keys for the guardian subset in this step. - * @param {*} totalguardians The total number of known guardians. - */ - this.addVerifyTx = function (gid, sender, params, payload, gksubset, totalguardians) { - if (this.groupTxSet[gid] === undefined) { - throw new Error('unknown group id') - } - const appArgs = [] - appArgs.push(new Uint8Array(Buffer.from('verify')), - new Uint8Array(Buffer.from(gksubset.join(''), 'hex')), - algosdk.encodeUint64(parseInt(totalguardians))) - - const tx = algosdk.makeApplicationNoOpTxn(sender, - params, - ContractInfo.vaaProcessor.appId, - appArgs, undefined, undefined, undefined, - new Uint8Array(payload)) - this.groupTxSet[gid].push(tx) - - return tx.txID() - } - - /** - * Pricekeeper-V2: Add store price transaction to TX Group. - * @param {*} sender The sender account (typically the VAA verification stateless program) - * @param {*} sym The symbol identifying the product to store price for. - * @param {*} payload The VAA payload. - */ - this.addPriceStoreTx = function (gid, sender, params, sym, payload) { - if (this.groupTxSet[gid] === undefined) { - throw new Error('unknown group id') - } - const appArgs = [] - appArgs.push(new Uint8Array(Buffer.from('store')), - new Uint8Array(Buffer.from(sym)), - new Uint8Array(payload)) - - const tx = algosdk.makeApplicationNoOpTxn(sender, - params, - ContractInfo.pricekeeper.appId, - appArgs) - this.groupTxSet[gid].push(tx) - - return tx.txID() - } - } -} - -module.exports = { - PricecasterLib -} diff --git a/staging/algorand/log/dummy.txt b/staging/algorand/log/dummy.txt deleted file mode 100644 index 3bca94ed3..000000000 --- a/staging/algorand/log/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Log file output in this directory. \ No newline at end of file diff --git a/staging/algorand/package-lock.json b/staging/algorand/package-lock.json deleted file mode 100644 index 6416faf09..000000000 --- a/staging/algorand/package-lock.json +++ /dev/null @@ -1,11935 +0,0 @@ -{ - "name": "pricecaster", - "version": "2.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "pricecaster", - "version": "2.0.0", - "license": "ISC", - "dependencies": { - "@certusone/wormhole-sdk": "^0.1.3", - "@certusone/wormhole-spydk": "^0.0.1", - "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", - "@pythnetwork/client": "^2.3.1", - "@randlabs/js-config-reader": "^1.1.0", - "@randlabs/js-logger": "^1.2.0", - "algosdk": "^1.12.0", - "base58-universal": "^1.0.0", - "charm": "^1.0.2", - "elliptic": "^6.5.4", - "esm": "^3.2.25", - "ethers": "^5.5.1", - "js-sha512": "^0.8.0", - "threads": "^1.7.0", - "web3-eth-abi": "^1.6.1", - "web3-utils": "^1.6.1" - }, - "devDependencies": { - "@types/superagent": "^4.1.13", - "@typescript-eslint/eslint-plugin": "^4.32.0", - "@typescript-eslint/parser": "^4.32.0", - "chai": "^4.3.4", - "chai-as-promised": "^7.1.1", - "cross-env": "^7.0.3", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.24.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.0", - "mocha": "^9.1.2", - "rimraf": "^3.0.2" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "node_modules/@babel/generator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz", - "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", - "dependencies": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", - "dependencies": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", - "dependencies": { - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.3.tgz", - "integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", - "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "dependencies": { - "@babel/highlight": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz", - "integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==", - "dependencies": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.3", - "@babel/types": "^7.16.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "dependencies": { - "@babel/highlight": "^7.16.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.15.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@certusone/wormhole-sdk": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.1.3.tgz", - "integrity": "sha512-rVUnxwqzF1mpG2YFZGBjUr4jCisyuU7nD4YzmzY6zO+F4ZyRKcq8NDDcdShMohm9ae9x9GwwgVx/g/JRp8VK3Q==", - "dependencies": { - "@improbable-eng/grpc-web": "^0.14.0", - "@solana/spl-token": "^0.1.8", - "@solana/web3.js": "^1.24.0", - "@terra-money/terra.js": "^2.0.14", - "@terra-money/wallet-provider": "^2.2.0", - "axios": "^0.24.0", - "bech32": "^2.0.0", - "js-base64": "^3.6.1", - "protobufjs": "^6.11.2", - "rxjs": "^7.3.0" - } - }, - "node_modules/@certusone/wormhole-spydk": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-spydk/-/wormhole-spydk-0.0.1.tgz", - "integrity": "sha512-iBQoY3UnmGoWHcbn0FypA6hKsANhdHKi03UN0GPoDAeMY12j8ly+7r462TfLl5f4hOJVQd3UZ2qviohEmdicmg==", - "dependencies": { - "@grpc/grpc-js": "^1.4.4", - "protobufjs": "^6.11.2" - } - }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "dependencies": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "node_modules/@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "dependencies": { - "@emotion/memoize": "0.7.4" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" - }, - "node_modules/@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", - "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", - "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", - "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", - "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/rlp": "^5.5.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", - "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0" - } - }, - "node_modules/@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", - "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "bn.js": "^4.11.9" - } - }, - "node_modules/@ethersproject/bignumber/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", - "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0" - } - }, - "node_modules/@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", - "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "node_modules/@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - } - }, - "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", - "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.0.tgz", - "integrity": "sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", - "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/providers": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.0.tgz", - "integrity": "sha512-xqMbDnS/FPy+J/9mBLKddzyLLAQFjrVff5g00efqxPzcAwXiR+SiCGVy6eJ5iAIirBOATjx7QLhDNPGV+AEQsw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - } - }, - "node_modules/@ethersproject/providers/node_modules/bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@ethersproject/random": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz", - "integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", - "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", - "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/signing-key/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", - "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/transactions": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", - "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "node_modules/@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.0.tgz", - "integrity": "sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "node_modules/@grpc/grpc-js": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.4.tgz", - "integrity": "sha512-a6222b7Dl6fIlMgzVl7e+NiRoLiZFbpcwvBH2Oli56Bn7W4/3Ld+86hK4ffPn5rx2DlDidmIcvIJiOQXyhv9gA==", - "dependencies": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - }, - "engines": { - "node": "^8.13.0 || >=10.10.0" - } - }, - "node_modules/@grpc/proto-loader": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.7.tgz", - "integrity": "sha512-QzTPIyJxU0u+r2qGe8VMl3j/W2ryhEvBv7hc42OjYfthSj370fUrb7na65rG6w3YLZS/fb8p89iTBobfWGDgdw==", - "dependencies": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "node_modules/@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "dependencies": { - "browser-headers": "^0.4.1" - }, - "peerDependencies": { - "google-protobuf": "^3.14.0" - } - }, - "node_modules/@improbable-eng/grpc-web-node-http-transport": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.15.0.tgz", - "integrity": "sha512-HLgJfVolGGpjc9DWPhmMmXJx8YGzkek7jcCFO1YYkSOoO81MWRZentPOd/JiKiZuU08wtc4BG+WNuGzsQB5jZA==", - "peerDependencies": { - "@improbable-eng/grpc-web": ">=0.13.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "node_modules/@pythnetwork/client": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@pythnetwork/client/-/client-2.5.1.tgz", - "integrity": "sha512-QXt31aWuVi02yvjmNEFDKurTkeTL/BEM4Ney4uixUbkxZDSrYRUuYNXPTrylRLdT3C3DlbF858/Jt7DwtLMR2w==", - "dependencies": { - "@solana/web3.js": "^1.30.2", - "assert": "^2.0.0", - "buffer": "^6.0.1" - } - }, - "node_modules/@randlabs/js-config-reader": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@randlabs/js-config-reader/-/js-config-reader-1.1.0.tgz", - "integrity": "sha512-/Jz+3+i9Hz1Z5us8SoRZNJtH9ZwSnYta2iRDRric3IxVQUpcxXoihNv+8tlauzmPXT3iSlM+QzjGIBudGqzKcw==", - "dependencies": { - "ajv": "^6.12.5", - "ajv-formats-draft2019": "^1.4.3", - "json5": "^2.1.3" - } - }, - "node_modules/@randlabs/js-logger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@randlabs/js-logger/-/js-logger-1.2.0.tgz", - "integrity": "sha512-WB0oQ7KDrJwDGeHhdE45v6XGZYn4lm2LO2phP+QoaIlbv+GVVm79yuWuSuqmUZ52a3TAqnxoTpfCPdzHr8IGxw==", - "dependencies": { - "colors": "^1.4.0", - "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0", - "winston-syslog": "^2.4.4" - } - }, - "node_modules/@solana/buffer-layout": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", - "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", - "dependencies": { - "buffer": "~6.0.3" - }, - "engines": { - "node": ">=5.10" - } - }, - "node_modules/@solana/spl-token": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", - "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", - "dependencies": { - "@babel/runtime": "^7.10.5", - "@solana/web3.js": "^1.21.0", - "bn.js": "^5.1.0", - "buffer": "6.0.3", - "buffer-layout": "^1.2.0", - "dotenv": "10.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@solana/web3.js": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.30.2.tgz", - "integrity": "sha512-hznCj+rkfvM5taRP3Z+l5lumB7IQnDrB4l55Wpsg4kDU9Zds8pE5YOH5Z9bbF/pUzZJKQjyBjnY/6kScBm3Ugg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "@ethersproject/sha2": "^5.5.0", - "@solana/buffer-layout": "^3.0.0", - "bn.js": "^5.0.0", - "borsh": "^0.4.0", - "bs58": "^4.0.1", - "buffer": "6.0.1", - "cross-fetch": "^3.1.4", - "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/@solana/web3.js/node_modules/buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/@terra-dev/browser-check": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/browser-check/-/browser-check-2.3.0.tgz", - "integrity": "sha512-dHSrk1f6UbA2PQ6OjZo4w66/QyfbTr/OGeTKGarsaFgPCK3SJ4H3wM3sWfJqG7yn/DYpclWmnHvnRUbVHQdcog==", - "dependencies": { - "bowser": "^2.11.0", - "mobile-detect": "^1.4.5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-dev/chrome-extension": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/chrome-extension/-/chrome-extension-2.3.0.tgz", - "integrity": "sha512-R+SWvc4DLECKp7aHS1pwQ0gK4XuhsqaInTGNf/NOXg6vxlFsl3bg1Yj5vVS9ro4HaG7zH+/WP0wCn8WZ+7Ulgw==", - "dependencies": { - "@terra-dev/browser-check": "^2.3.0", - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0", - "rxjs": "^7.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-dev/readonly-wallet": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/readonly-wallet/-/readonly-wallet-2.3.0.tgz", - "integrity": "sha512-oBUy8U598ly/LWE+sKb45fqAFB/CQvJbRBYzeUJZUKUdQUP50xG4fMyga/ANoUpDNd3GEwkl41uG3JSYTctRKw==", - "dependencies": { - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-dev/readonly-wallet-modal": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/readonly-wallet-modal/-/readonly-wallet-modal-2.3.0.tgz", - "integrity": "sha512-UcHigWCPZdYjsQ7GbCg65+yKgUEUvstweJiMnV82ihM2nqOTRSNlLjd0rlJ1t3IZQFrBnELF5jXDhGMsOLExLA==", - "dependencies": { - "@terra-dev/readonly-wallet": "^2.3.0", - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0", - "styled-components": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^17.0.0", - "react-dom": "^17.0.0" - } - }, - "node_modules/@terra-dev/use-wallet": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/use-wallet/-/use-wallet-2.3.0.tgz", - "integrity": "sha512-F3YZmVKD1EancUGO8In845pqiqEbk5UEu8Or32xHPywJ7Qa+5LYS5fiX6NKgz1BB7MZ5iW2gIWjwo93eejvqNw==", - "dependencies": { - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^17.0.0" - } - }, - "node_modules/@terra-dev/wallet-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/wallet-types/-/wallet-types-2.3.0.tgz", - "integrity": "sha512-WpuEuiqXlCHVWomE9nnkpWUDtWiaKLB9iCLsfGqUyU8AInqDyALydtAGpGtIj8SykqX/6wGRDeK67DBCqVdd3w==", - "dependencies": { - "@terra-money/terra.js": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-dev/walletconnect": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/walletconnect/-/walletconnect-2.3.0.tgz", - "integrity": "sha512-eodXfTwD/EYNjejwJW4c5IMFjWT/Tgde70c4BexpMrAif3OXkFwZyNVEATLaqsisHzdq5vJ7oOTaWCHxu03uRg==", - "dependencies": { - "@terra-dev/browser-check": "^2.3.0", - "@terra-dev/walletconnect-qrcode-modal": "^2.3.0", - "@terra-money/terra.js": "^2.0.0", - "@walletconnect/core": "^1.6.1", - "@walletconnect/iso-crypto": "^1.6.1", - "@walletconnect/types": "^1.6.1", - "@walletconnect/utils": "^1.6.1", - "rxjs": "^7.3.0", - "ws": "^7.5.3" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-dev/walletconnect-qrcode-modal": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/walletconnect-qrcode-modal/-/walletconnect-qrcode-modal-2.3.0.tgz", - "integrity": "sha512-S1jokcgValyGrTvcyOHRwTKFYxhnAROYp5cPglywD4YYMZEXmw85+9AULFUIDDL87Wv0hrJXyznXSNdpAoZ9pA==", - "dependencies": { - "@terra-dev/browser-check": "^2.3.0", - "@walletconnect/types": "^1.6.1", - "qrcode.react": "^1.0.1", - "styled-components": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^17.0.0", - "react-dom": "^17.0.0" - } - }, - "node_modules/@terra-dev/web-connector-controller": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@terra-dev/web-connector-controller/-/web-connector-controller-0.7.0.tgz", - "integrity": "sha512-hH27gma1Mb04bMIf/x/Rza2uiWDv18xcdLtx5s+3111ycL1REeIU6RyGAsiXVUy0HWf8YGODLscJVxSK7Kn30g==", - "dependencies": { - "@terra-dev/web-connector-interface": "^0.7.0", - "@terra-money/terra.js": "^2.0.14", - "bowser": "^2.11.0", - "rxjs": "^7.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-dev/web-connector-interface": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@terra-dev/web-connector-interface/-/web-connector-interface-0.7.0.tgz", - "integrity": "sha512-bYyMk18lFTzEccsWjqg2UbgA7olkHKerl0JD9MgGRqVvAJAbkXQ4hWBFu6EfrmFAdCwHDT4xgu41WtbEmjBNqQ==", - "dependencies": { - "@terra-money/terra.js": "^2.0.14", - "rxjs": "^7.3.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-money/terra.js": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-2.0.16.tgz", - "integrity": "sha512-kPW45vIeAbTgHRimoCzsJS9B9XfDI+5OzHhhLCqHUJpZwL5bEhA+wDu216VcHrq1R0fMBmsGlIq3ugrX5HTG+A==", - "dependencies": { - "axios": "^0.24.0", - "bech32": "^2.0.0", - "bip32": "^2.0.6", - "bip39": "^3.0.3", - "bufferutil": "^4.0.3", - "decimal.js": "^10.2.1", - "jscrypto": "^1.0.1", - "readable-stream": "^3.6.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.5", - "ws": "^7.5.5" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@terra-money/wallet-provider": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.3.0.tgz", - "integrity": "sha512-ee1iK5cxffOlgPSxO1vzPdGB01u1uvq+VP+74KPY1k+GpqOCYezOZGbLVMWXOuu861GxMuMl90K9Eu0n32mwQg==", - "dependencies": { - "@terra-dev/browser-check": "^2.3.0", - "@terra-dev/chrome-extension": "^2.3.0", - "@terra-dev/readonly-wallet": "^2.3.0", - "@terra-dev/readonly-wallet-modal": "^2.3.0", - "@terra-dev/use-wallet": "^2.3.0", - "@terra-dev/wallet-types": "^2.3.0", - "@terra-dev/walletconnect": "^2.3.0", - "@terra-dev/web-connector-controller": "^0.7.0", - "@terra-dev/web-connector-interface": "^0.7.0", - "@terra-money/terra.js": "^2.0.0", - "fast-deep-equal": "^3.1.3", - "rxjs": "^7.3.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^17.0.0" - }, - "peerDependenciesMeta": { - "react-router-dom": { - "optional": true - } - } - }, - "node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", - "dev": true - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.25.tgz", - "integrity": "sha512-OUJIVfRMFijZukGGwTpKNFprqCCXk5WjNGvUgB/CxxBR40QWSjsNK86+yvGKlCOGc7sbwfHLaXhkG+NsytwBaQ==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.176", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", - "integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==" - }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "node_modules/@types/node": { - "version": "16.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz", - "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==" - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "node_modules/@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/superagent": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.13.tgz", - "integrity": "sha512-YIGelp3ZyMiH0/A09PMAORO0EBGlF5xIKfDpK74wdYvWUs2o96b5CItJcWPdH409b7SAXIIG6p8NdU/4U2Maww==", - "dev": true, - "dependencies": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "node_modules/@walletconnect/browser-utils": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.6.6.tgz", - "integrity": "sha512-E29xSHU7Akd4jaPehWVGx7ct+SsUzZbxcGc0fz+Pw6/j4Gh5tlfYZ9XuVixuYI4WPdQ2CmOraj8RrVOu5vba4w==", - "dependencies": { - "@walletconnect/safe-json": "1.0.0", - "@walletconnect/types": "^1.6.6", - "@walletconnect/window-getters": "1.0.0", - "@walletconnect/window-metadata": "1.0.0", - "detect-browser": "5.2.0" - } - }, - "node_modules/@walletconnect/core": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.6.6.tgz", - "integrity": "sha512-pSftIVPY6mYz2koZPBEYmeFeAjVf2MSnRHOM6+vx+iAsUEcfMZHkgeXX6GtM6Fjza+zSZu1qnmdgURVXpmKwtQ==", - "dependencies": { - "@walletconnect/socket-transport": "^1.6.6", - "@walletconnect/types": "^1.6.6", - "@walletconnect/utils": "^1.6.6" - } - }, - "node_modules/@walletconnect/crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@walletconnect/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-IgUReNrycIFxkGgq8YT9HsosCkhutakWD9Q411PR0aJfxpEa/VKJeaLRtoz6DvJpztWStwhIHnAbBoOVR72a6g==", - "dependencies": { - "@walletconnect/encoding": "^1.0.0", - "@walletconnect/environment": "^1.0.0", - "@walletconnect/randombytes": "^1.0.1", - "aes-js": "^3.1.2", - "hash.js": "^1.1.7" - } - }, - "node_modules/@walletconnect/encoding": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/encoding/-/encoding-1.0.0.tgz", - "integrity": "sha512-4nkJFnS0QF5JdieG/3VPD1/iEWkLSZ14EBInLZ00RWxmC6EMZrzAeHNAWIgm+xP3NK0lqz+7lEsmWGtcl5gYnQ==", - "dependencies": { - "is-typedarray": "1.0.0", - "typedarray-to-buffer": "3.1.5" - } - }, - "node_modules/@walletconnect/environment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/environment/-/environment-1.0.0.tgz", - "integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ==" - }, - "node_modules/@walletconnect/iso-crypto": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.6.6.tgz", - "integrity": "sha512-wRYgKvd8K3A9FVLn2c0cDh4+9OUHkqibKtwQJTJsz+ibPGgd+n5j1/FjnzDDRGb9T1+TtlwYF3ZswKyys3diVQ==", - "dependencies": { - "@walletconnect/crypto": "^1.0.1", - "@walletconnect/types": "^1.6.6", - "@walletconnect/utils": "^1.6.6" - } - }, - "node_modules/@walletconnect/jsonrpc-types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.0.tgz", - "integrity": "sha512-11QXNq5H1PKZk7bP8SxgmCw3HRaDuPOVE+wObqEvmhc7OWYUZqfuaaMb+OXGRSOHL3sbC+XHfdeCxFTMXSFyng==", - "dependencies": { - "keyvaluestorage-interface": "^1.0.0" - } - }, - "node_modules/@walletconnect/jsonrpc-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.0.tgz", - "integrity": "sha512-qUHbKUK6sHeHn67qtHZoLoYk5hS6x1arTPjKDRkY93/6Fx+ZmNIpdm1owX3l6aYueyegJ7mz43FpvYHUqJ8xcw==", - "dependencies": { - "@walletconnect/environment": "^1.0.0", - "@walletconnect/jsonrpc-types": "^1.0.0" - } - }, - "node_modules/@walletconnect/randombytes": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@walletconnect/randombytes/-/randombytes-1.0.1.tgz", - "integrity": "sha512-YJTyq69i0PtxVg7osEpKfvjTaWuAsR49QEcqGKZRKVQWMbGXBZ65fovemK/SRgtiFRv0V8PwsrlKSheqzfPNcg==", - "dependencies": { - "@walletconnect/encoding": "^1.0.0", - "@walletconnect/environment": "^1.0.0", - "randombytes": "^2.1.0" - } - }, - "node_modules/@walletconnect/safe-json": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/safe-json/-/safe-json-1.0.0.tgz", - "integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg==" - }, - "node_modules/@walletconnect/socket-transport": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.6.6.tgz", - "integrity": "sha512-mugCEoeKTx75ogb5ROg/+LA3yGTsuRNcrYgrApceo7WNU9Z4dG8l6ycMPqrrFcODcrasq3NmXVWUYDv/CvrzSw==", - "dependencies": { - "@walletconnect/types": "^1.6.6", - "@walletconnect/utils": "^1.6.6", - "ws": "7.5.3" - } - }, - "node_modules/@walletconnect/socket-transport/node_modules/ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@walletconnect/types": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.6.6.tgz", - "integrity": "sha512-op77cxexOmQQN36XB1sYouNTlBRV0Rup/2NYK8A1ffdwXa3a6HLHHdhBM7I/I9BVmRXoZ4+XoOnPKGGrYtlS3g==" - }, - "node_modules/@walletconnect/utils": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.6.6.tgz", - "integrity": "sha512-s2X/cVXiMDSEoWV6i7HPMbP1obXlzP7KLMrBo9OMabiJKnQEh6HSZ39WLswB2PHnl8Hp1Sr4BdRvhM5kCcYWRw==", - "dependencies": { - "@walletconnect/browser-utils": "^1.6.6", - "@walletconnect/encoding": "^1.0.0", - "@walletconnect/jsonrpc-utils": "^1.0.0", - "@walletconnect/types": "^1.6.6", - "bn.js": "4.11.8", - "js-sha3": "0.8.0", - "query-string": "6.13.5" - } - }, - "node_modules/@walletconnect/utils/node_modules/bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - }, - "node_modules/@walletconnect/window-getters": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/window-getters/-/window-getters-1.0.0.tgz", - "integrity": "sha512-xB0SQsLaleIYIkSsl43vm8EwETpBzJ2gnzk7e0wMF3ktqiTGS6TFHxcprMl5R44KKh4tCcHCJwolMCaDSwtAaA==" - }, - "node_modules/@walletconnect/window-metadata": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/window-metadata/-/window-metadata-1.0.0.tgz", - "integrity": "sha512-9eFvmJxIKCC3YWOL97SgRkKhlyGXkrHwamfechmqszbypFspaSk+t2jQXAEU7YClHF6Qjw5eYOmy1//zFi9/GA==", - "dependencies": { - "@walletconnect/window-getters": "^1.0.0" - } - }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats-draft2019": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ajv-formats-draft2019/-/ajv-formats-draft2019-1.6.1.tgz", - "integrity": "sha512-JQPvavpkWDvIsBp2Z33UkYCtXCSpW4HD3tAZ+oL4iEFOk9obQZffx0yANwECt6vzr6ET+7HN5czRyqXbnq/u0Q==", - "dependencies": { - "punycode": "^2.1.1", - "schemes": "^1.4.0", - "smtp-address-parser": "^1.0.3", - "uri-js": "^4.4.1" - }, - "peerDependencies": { - "ajv": "*" - } - }, - "node_modules/algo-msgpack-with-bigint": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", - "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/algosdk": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.12.0.tgz", - "integrity": "sha512-Iqek0AwcCeXLywVg4E8gWWjmuPZ10P7PUmpZrlR71FSNyEtX4Ie+UgrNHWhkYnhyykRU5mjtvD4Hrb2eOepsGA==", - "dependencies": { - "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.2", - "hi-base32": "^0.5.1", - "js-sha256": "^0.9.0", - "js-sha3": "^0.8.0", - "js-sha512": "^0.8.0", - "json-bigint": "^1.0.0", - "superagent": "^6.1.0", - "tweetnacl": "^1.0.3", - "url-parse": "^1.5.1" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", - "dependencies": { - "follow-redirects": "^1.14.4" - } - }, - "node_modules/babel-plugin-styled-components": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz", - "integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-module-imports": "^7.15.4", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - }, - "peerDependencies": { - "styled-components": ">= 2" - } - }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/base58-universal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base58-universal/-/base58-universal-1.0.0.tgz", - "integrity": "sha512-v0Ja4jwaQP8gBZPNXpfaXlLht2ed/Gp3AsVUZXtlZgY1qbKS0CjxvYs43U0Gh00zbVc1neMe+q/ULJ7ubVyB+w==", - "dependencies": { - "esm": "^3.2.25" - }, - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "node_modules/bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "dependencies": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/bip32/node_modules/@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" - }, - "node_modules/bip39": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", - "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", - "dependencies": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" - } - }, - "node_modules/bip39/node_modules/@types/node": { - "version": "11.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" - }, - "node_modules/blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "node_modules/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "node_modules/borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", - "dependencies": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "node_modules/browser-headers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", - "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==" - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dependencies": { - "base-x": "^3.0.2" - } - }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-layout": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", - "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==", - "engines": { - "node": ">=4.5" - } - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "node_modules/bufferutil": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", - "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "node_modules/chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "dependencies": { - "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 5" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/charm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", - "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", - "dependencies": { - "inherits": "^2.0.1" - } - }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", - "deprecated": "CircularJSON is in maintenance only, flatted is its successor." - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dependencies": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "node_modules/color/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "dependencies": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "dependencies": { - "node-fetch": "2.6.1" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", - "engines": { - "node": ">=4" - } - }, - "node_modules/css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.0.tgz", - "integrity": "sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA==" - }, - "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", - "engines": { - "node": ">=10" - } - }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "peerDependencies": { - "eslint": "^7.12.1", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^4.2.1 || ^5.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "dependencies": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "peerDependencies": { - "eslint": ">=5.16.0" - } - }, - "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "dependencies": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=4.19.1" - } - }, - "node_modules/eslint-plugin-node/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-promise": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", - "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", - "dev": true, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "dependencies": { - "js-sha3": "^0.8.0" - } - }, - "node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "node_modules/ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/ethereumjs-util/node_modules/@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethers": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.1.tgz", - "integrity": "sha512-RodEvUFZI+EmFcE6bwkuJqpCYHazdzeR1nMzg+YWQSmQEsNtfl1KHGfp/FWZYl48bI/g7cgBeP2IlPthjiVngw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.0", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.0", - "@ethersproject/random": "5.5.0", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.0", - "@ethersproject/wordlists": "5.5.0" - } - }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", - "engines": { - "node": "> 0.1.90" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fecha": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", - "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-stream-rotator": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz", - "integrity": "sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ==", - "dependencies": { - "moment": "^2.11.2" - } - }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", - "dev": true - }, - "node_modules/fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "node_modules/follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", - "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glossy": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/glossy/-/glossy-0.1.7.tgz", - "integrity": "sha1-dptZhKlvYGarnqdYIkgl7mwhDws=", - "engines": { - "node": ">= 0.2.5" - } - }, - "node_modules/google-protobuf": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.1.tgz", - "integrity": "sha512-Isv1RlNC+IzZzilcxnlVSf+JvuhxmY7DaxYCBy+zPS9XVuJRtlTTIXR9hnZ1YL1MMusJn/7eSy2swCzZIomQSg==", - "peer": true - }, - "node_modules/growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true, - "engines": { - "node": ">=4.x" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/hi-base32": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", - "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", - "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-observable": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", - "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dependencies": { - "call-bind": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "peerDependencies": { - "ws": "*" - } - }, - "node_modules/jayson": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.5.tgz", - "integrity": "sha512-wmOjX+eQcnCDyPF4KORomaIj9wj3h0B5VEbeD0+2VHfTfErB+h1zpR7oBkgCZp36AFjp3+a4CLz6U72BYpFHAw==", - "dependencies": { - "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "lodash": "^4.17.20", - "uuid": "^3.4.0", - "ws": "^7.4.5" - }, - "bin": { - "jayson": "bin/jayson.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jayson/node_modules/@types/node": { - "version": "12.20.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", - "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==" - }, - "node_modules/js-base64": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", - "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" - }, - "node_modules/js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" - }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "node_modules/js-sha512": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", - "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jscrypto": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.2.tgz", - "integrity": "sha512-r+oNJLGTv1nkNMBBq3c70xYrFDgJOYVgs2OHijz5Ht+0KJ0yObD0oYxC9mN72KLzVfXw+osspg6t27IZvuTUxw==", - "bin": { - "jscrypto": "bin/cli.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "dependencies": { - "bignumber.js": "^9.0.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/keyvaluestorage-interface": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz", - "integrity": "sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==" - }, - "node_modules/kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/logform": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", - "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", - "dependencies": { - "colors": "^1.2.1", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^1.1.0", - "triple-beam": "^1.3.0" - } - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "dependencies": { - "mime-db": "1.51.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "node_modules/mobile-detect": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/mobile-detect/-/mobile-detect-1.4.5.tgz", - "integrity": "sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g==" - }, - "node_modules/mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "dependencies": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", - "engines": { - "node": "*" - } - }, - "node_modules/moo": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", - "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==" - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, - "node_modules/nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/nearley": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", - "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", - "dependencies": { - "commander": "^2.19.0", - "moo": "^0.5.0", - "railroad-diagrams": "^1.0.0", - "randexp": "0.4.6" - }, - "bin": { - "nearley-railroad": "bin/nearley-railroad.js", - "nearley-test": "bin/nearley-test.js", - "nearley-unparse": "bin/nearley-unparse.js", - "nearleyc": "bin/nearleyc.js" - }, - "funding": { - "type": "individual", - "url": "https://nearley.js.org/#give-to-nearley" - } - }, - "node_modules/node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "engines": { - "node": "4.x || >=6.0.0" - } - }, - "node_modules/node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/observable-fns": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/observable-fns/-/observable-fns-0.6.1.tgz", - "integrity": "sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==" - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qr.js": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", - "integrity": "sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=" - }, - "node_modules/qrcode.react": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-1.0.1.tgz", - "integrity": "sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg==", - "dependencies": { - "loose-envify": "^1.4.0", - "prop-types": "^15.6.0", - "qr.js": "0.0.0" - }, - "peerDependencies": { - "react": "^15.5.3 || ^16.0.0 || ^17.0.0" - } - }, - "node_modules/qs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", - "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/query-string": { - "version": "6.13.5", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.5.tgz", - "integrity": "sha512-svk3xg9qHR39P3JlHuD7g3nRnyay5mHbrPctEBDUxUkHRifPHXJDhBUycdCC0NBjXoDf44Gb+IsOZL1Uwn8M/Q==", - "dependencies": { - "decode-uri-component": "^0.2.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/railroad-diagrams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", - "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" - }, - "node_modules/randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "dependencies": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - }, - "peerDependencies": { - "react": "17.0.2" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "peer": true - }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "engines": { - "node": ">=0.12" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "node_modules/rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "dependencies": { - "bn.js": "^5.2.0" - }, - "bin": { - "rlp": "bin/rlp" - } - }, - "node_modules/rpc-websockets": { - "version": "7.4.16", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", - "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", - "dependencies": { - "@babel/runtime": "^7.11.2", - "circular-json": "^0.5.9", - "eventemitter3": "^4.0.7", - "uuid": "^8.3.0", - "ws": "^7.4.5" - }, - "funding": { - "type": "paypal", - "url": "https://paypal.me/kozjak" - }, - "optionalDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - } - }, - "node_modules/rpc-websockets/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", - "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", - "dependencies": { - "tslib": "~2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" - }, - "node_modules/scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/schemes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/schemes/-/schemes-1.4.0.tgz", - "integrity": "sha512-ImFy9FbCsQlVgnE3TCWmLPCFnVzx0lHL/l+umHplDqAKd0dzFpnS6lFZIpagBlYhKwzVmlV36ec0Y1XTu8JBAQ==", - "dependencies": { - "extend": "^3.0.0" - } - }, - "node_modules/scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "node_modules/secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "hasInstallScript": true, - "dependencies": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/smtp-address-parser": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/smtp-address-parser/-/smtp-address-parser-1.0.7.tgz", - "integrity": "sha512-QmmaQ99AtWTUtPXmUiwRXZN7IFLGS/SstKUyjsdqkQvGOwhTCMJw/Z+l9F3ImcZ5rLDj9y1mvwZ/+GAvMoa9Wg==", - "dependencies": { - "nearley": "^2.20.1" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "engines": { - "node": "*" - } - }, - "node_modules/strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", - "engines": { - "node": ">=4" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/styled-components": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz", - "integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/styled-components" - }, - "peerDependencies": { - "react": ">= 16.8.0", - "react-dom": ">= 16.8.0", - "react-is": ">= 16.8.0" - } - }, - "node_modules/styled-components/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/styled-components/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/superagent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", - "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", - "dependencies": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.2", - "debug": "^4.1.1", - "fast-safe-stringify": "^2.0.7", - "form-data": "^3.0.0", - "formidable": "^1.2.2", - "methods": "^1.1.2", - "mime": "^2.4.6", - "qs": "^6.9.4", - "readable-stream": "^3.6.0", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 7.0.0" - } - }, - "node_modules/superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/table": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz", - "integrity": "sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.7.1.tgz", - "integrity": "sha512-gPpOObTO1QjbnN1sVMjJcp1TF9nggMfO4MBR5uQl6ZVTOaEPq5i4oq/6R9q2alMMPB3eg53wFv1RuJBLuxf3Hw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, - "node_modules/text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/threads": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/threads/-/threads-1.7.0.tgz", - "integrity": "sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==", - "dependencies": { - "callsites": "^3.1.0", - "debug": "^4.2.0", - "is-observable": "^2.1.0", - "observable-fns": "^0.6.1" - }, - "funding": { - "url": "https://github.com/andywer/threads.js?sponsor=1" - }, - "optionalDependencies": { - "tiny-worker": ">= 2" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "node_modules/tiny-secp256k1": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", - "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", - "hasInstallScript": true, - "dependencies": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/tiny-secp256k1/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/tiny-worker": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.3.0.tgz", - "integrity": "sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==", - "optional": true, - "dependencies": { - "esm": "^3.2.25" - } - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "node_modules/tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" - }, - "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unix-dgram": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unix-dgram/-/unix-dgram-2.0.3.tgz", - "integrity": "sha512-Bay5CkSLcdypcBCsxvHEvaG3mftzT5FlUnRToPWEAVxwYI8NI/8zSJ/Gknlp86MPhV6hBA8I8TBsETj2tssoHQ==", - "hasInstallScript": true, - "optional": true, - "dependencies": { - "bindings": "^1.3.0", - "nan": "^2.13.2" - }, - "engines": { - "node": ">=0.10.48" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/utf-8-validate": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", - "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^4.3.0" - }, - "engines": { - "node": ">=6.14.2" - } - }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "node_modules/util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/web3-eth-abi": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.1.tgz", - "integrity": "sha512-svhYrAlXP9XQtV7poWKydwDJq2CaNLMtmKydNXoOBLcQec6yGMP+v20pgrxF2H6wyTK+Qy0E3/5ciPOqC/VuoQ==", - "dependencies": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-eth-abi/node_modules/@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "dependencies": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - }, - "node_modules/web3-utils": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", - "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", - "dependencies": { - "bn.js": "^4.11.9", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", - "dependencies": { - "bs58check": "<3.0.0" - } - }, - "node_modules/winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "dependencies": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/winston-daily-rotate-file": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.5.tgz", - "integrity": "sha512-ds0WahIjiDhKCiMXmY799pDBW+58ByqIBtUcsqr4oDoXrAI3Zn+hbgFdUxzMfqA93OG0mPLYVMiotqTgE/WeWQ==", - "dependencies": { - "file-stream-rotator": "^0.5.7", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "winston": "^3" - } - }, - "node_modules/winston-syslog": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/winston-syslog/-/winston-syslog-2.4.4.tgz", - "integrity": "sha512-zDjoKO932Yszvzq8WtbIFMXHwAT2MOxpWC9s6djw2tvjdRESWw3au6l+0xDMatMhNWVoVaVNkDXF+r/eyoBUVA==", - "dependencies": { - "glossy": "^0.1.7" - }, - "engines": { - "node": ">= 8" - }, - "optionalDependencies": { - "unix-dgram": "2.0.3" - }, - "peerDependencies": { - "winston": "^3.0.0" - } - }, - "node_modules/winston-transport": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.1.tgz", - "integrity": "sha512-ciZRlU4CSjHqHe8RQG1iPxKMRVwv6ZJ0RC7DxStKWd0KjpAhPDy5gVYSCpIUq+5CUsP+IyNOTZy1X0tO2QZqjg==", - "dependencies": { - "logform": "^2.2.0", - "readable-stream": "^3.4.0", - "triple-beam": "^1.2.0" - }, - "engines": { - "node": ">= 6.4.0" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/generator": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz", - "integrity": "sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==", - "requires": { - "@babel/types": "^7.16.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz", - "integrity": "sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-function-name": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz", - "integrity": "sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==", - "requires": { - "@babel/helper-get-function-arity": "^7.16.0", - "@babel/template": "^7.16.0", - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz", - "integrity": "sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz", - "integrity": "sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz", - "integrity": "sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz", - "integrity": "sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==", - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==" - }, - "@babel/highlight": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz", - "integrity": "sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==", - "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.16.3.tgz", - "integrity": "sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw==" - }, - "@babel/runtime": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.3.tgz", - "integrity": "sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz", - "integrity": "sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==", - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/parser": "^7.16.0", - "@babel/types": "^7.16.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "requires": { - "@babel/highlight": "^7.16.0" - } - } - } - }, - "@babel/traverse": { - "version": "7.16.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.3.tgz", - "integrity": "sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag==", - "requires": { - "@babel/code-frame": "^7.16.0", - "@babel/generator": "^7.16.0", - "@babel/helper-function-name": "^7.16.0", - "@babel/helper-hoist-variables": "^7.16.0", - "@babel/helper-split-export-declaration": "^7.16.0", - "@babel/parser": "^7.16.3", - "@babel/types": "^7.16.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz", - "integrity": "sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==", - "requires": { - "@babel/highlight": "^7.16.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - } - } - }, - "@babel/types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz", - "integrity": "sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg==", - "requires": { - "@babel/helper-validator-identifier": "^7.15.7", - "to-fast-properties": "^2.0.0" - } - }, - "@certusone/wormhole-sdk": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-sdk/-/wormhole-sdk-0.1.3.tgz", - "integrity": "sha512-rVUnxwqzF1mpG2YFZGBjUr4jCisyuU7nD4YzmzY6zO+F4ZyRKcq8NDDcdShMohm9ae9x9GwwgVx/g/JRp8VK3Q==", - "requires": { - "@improbable-eng/grpc-web": "^0.14.0", - "@solana/spl-token": "^0.1.8", - "@solana/web3.js": "^1.24.0", - "@terra-money/terra.js": "^2.0.14", - "@terra-money/wallet-provider": "^2.2.0", - "axios": "^0.24.0", - "bech32": "^2.0.0", - "js-base64": "^3.6.1", - "protobufjs": "^6.11.2", - "rxjs": "^7.3.0" - } - }, - "@certusone/wormhole-spydk": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@certusone/wormhole-spydk/-/wormhole-spydk-0.0.1.tgz", - "integrity": "sha512-iBQoY3UnmGoWHcbn0FypA6hKsANhdHKi03UN0GPoDAeMY12j8ly+7r462TfLl5f4hOJVQd3UZ2qviohEmdicmg==", - "requires": { - "@grpc/grpc-js": "^1.4.4", - "protobufjs": "^6.11.2" - } - }, - "@dabh/diagnostics": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.2.tgz", - "integrity": "sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q==", - "requires": { - "colorspace": "1.1.x", - "enabled": "2.0.x", - "kuler": "^2.0.0" - } - }, - "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "requires": { - "@emotion/memoize": "0.7.4" - } - }, - "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" - }, - "@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "@ethersproject/abi": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.5.0.tgz", - "integrity": "sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==", - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/abstract-provider": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz", - "integrity": "sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0" - } - }, - "@ethersproject/abstract-signer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz", - "integrity": "sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/address": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.5.0.tgz", - "integrity": "sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/rlp": "^5.5.0" - } - }, - "@ethersproject/base64": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.5.0.tgz", - "integrity": "sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==", - "requires": { - "@ethersproject/bytes": "^5.5.0" - } - }, - "@ethersproject/basex": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.5.0.tgz", - "integrity": "sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/properties": "^5.5.0" - } - }, - "@ethersproject/bignumber": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.5.0.tgz", - "integrity": "sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "bn.js": "^4.11.9" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "@ethersproject/bytes": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.5.0.tgz", - "integrity": "sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/constants": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.5.0.tgz", - "integrity": "sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==", - "requires": { - "@ethersproject/bignumber": "^5.5.0" - } - }, - "@ethersproject/contracts": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.5.0.tgz", - "integrity": "sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==", - "requires": { - "@ethersproject/abi": "^5.5.0", - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/transactions": "^5.5.0" - } - }, - "@ethersproject/hash": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.5.0.tgz", - "integrity": "sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/hdnode": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.5.0.tgz", - "integrity": "sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/json-wallets": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz", - "integrity": "sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==", - "requires": { - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/pbkdf2": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "aes-js": "3.0.0", - "scrypt-js": "3.0.1" - }, - "dependencies": { - "aes-js": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", - "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" - } - } - }, - "@ethersproject/keccak256": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.5.0.tgz", - "integrity": "sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "js-sha3": "0.8.0" - } - }, - "@ethersproject/logger": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.5.0.tgz", - "integrity": "sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==" - }, - "@ethersproject/networks": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.5.0.tgz", - "integrity": "sha512-KWfP3xOnJeF89Uf/FCJdV1a2aDJe5XTN2N52p4fcQ34QhDqQFkgQKZ39VGtiqUgHcLI8DfT0l9azC3KFTunqtA==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/pbkdf2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz", - "integrity": "sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/sha2": "^5.5.0" - } - }, - "@ethersproject/properties": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.5.0.tgz", - "integrity": "sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==", - "requires": { - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/providers": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.5.0.tgz", - "integrity": "sha512-xqMbDnS/FPy+J/9mBLKddzyLLAQFjrVff5g00efqxPzcAwXiR+SiCGVy6eJ5iAIirBOATjx7QLhDNPGV+AEQsw==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/basex": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/networks": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/web": "^5.5.0", - "bech32": "1.1.4", - "ws": "7.4.6" - }, - "dependencies": { - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" - }, - "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "requires": {} - } - } - }, - "@ethersproject/random": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.5.0.tgz", - "integrity": "sha512-egGYZwZ/YIFKMHcoBUo8t3a8Hb/TKYX8BCBoLjudVCZh892welR3jOxgOmb48xznc9bTcMm7Tpwc1gHC1PFNFQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/rlp": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.5.0.tgz", - "integrity": "sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/sha2": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.5.0.tgz", - "integrity": "sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "hash.js": "1.1.7" - } - }, - "@ethersproject/signing-key": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.5.0.tgz", - "integrity": "sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "bn.js": "^4.11.9", - "elliptic": "6.5.4", - "hash.js": "1.1.7" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "@ethersproject/solidity": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.5.0.tgz", - "integrity": "sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/sha2": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/strings": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.5.0.tgz", - "integrity": "sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/transactions": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.5.0.tgz", - "integrity": "sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==", - "requires": { - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/rlp": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0" - } - }, - "@ethersproject/units": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.5.0.tgz", - "integrity": "sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==", - "requires": { - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/constants": "^5.5.0", - "@ethersproject/logger": "^5.5.0" - } - }, - "@ethersproject/wallet": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.5.0.tgz", - "integrity": "sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==", - "requires": { - "@ethersproject/abstract-provider": "^5.5.0", - "@ethersproject/abstract-signer": "^5.5.0", - "@ethersproject/address": "^5.5.0", - "@ethersproject/bignumber": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/hdnode": "^5.5.0", - "@ethersproject/json-wallets": "^5.5.0", - "@ethersproject/keccak256": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/random": "^5.5.0", - "@ethersproject/signing-key": "^5.5.0", - "@ethersproject/transactions": "^5.5.0", - "@ethersproject/wordlists": "^5.5.0" - } - }, - "@ethersproject/web": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.5.0.tgz", - "integrity": "sha512-BEgY0eL5oH4mAo37TNYVrFeHsIXLRxggCRG/ksRIxI2X5uj5IsjGmcNiRN/VirQOlBxcUhCgHhaDLG4m6XAVoA==", - "requires": { - "@ethersproject/base64": "^5.5.0", - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@ethersproject/wordlists": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.5.0.tgz", - "integrity": "sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==", - "requires": { - "@ethersproject/bytes": "^5.5.0", - "@ethersproject/hash": "^5.5.0", - "@ethersproject/logger": "^5.5.0", - "@ethersproject/properties": "^5.5.0", - "@ethersproject/strings": "^5.5.0" - } - }, - "@grpc/grpc-js": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.4.tgz", - "integrity": "sha512-a6222b7Dl6fIlMgzVl7e+NiRoLiZFbpcwvBH2Oli56Bn7W4/3Ld+86hK4ffPn5rx2DlDidmIcvIJiOQXyhv9gA==", - "requires": { - "@grpc/proto-loader": "^0.6.4", - "@types/node": ">=12.12.47" - } - }, - "@grpc/proto-loader": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.7.tgz", - "integrity": "sha512-QzTPIyJxU0u+r2qGe8VMl3j/W2ryhEvBv7hc42OjYfthSj370fUrb7na65rG6w3YLZS/fb8p89iTBobfWGDgdw==", - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.10.0", - "yargs": "^16.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@improbable-eng/grpc-web": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.14.1.tgz", - "integrity": "sha512-XaIYuunepPxoiGVLLHmlnVminUGzBTnXr8Wv7khzmLWbNw4TCwJKX09GSMJlKhu/TRk6gms0ySFxewaETSBqgw==", - "requires": { - "browser-headers": "^0.4.1" - } - }, - "@improbable-eng/grpc-web-node-http-transport": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web-node-http-transport/-/grpc-web-node-http-transport-0.15.0.tgz", - "integrity": "sha512-HLgJfVolGGpjc9DWPhmMmXJx8YGzkek7jcCFO1YYkSOoO81MWRZentPOd/JiKiZuU08wtc4BG+WNuGzsQB5jZA==", - "requires": {} - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@pythnetwork/client": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@pythnetwork/client/-/client-2.5.1.tgz", - "integrity": "sha512-QXt31aWuVi02yvjmNEFDKurTkeTL/BEM4Ney4uixUbkxZDSrYRUuYNXPTrylRLdT3C3DlbF858/Jt7DwtLMR2w==", - "requires": { - "@solana/web3.js": "^1.30.2", - "assert": "^2.0.0", - "buffer": "^6.0.1" - } - }, - "@randlabs/js-config-reader": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@randlabs/js-config-reader/-/js-config-reader-1.1.0.tgz", - "integrity": "sha512-/Jz+3+i9Hz1Z5us8SoRZNJtH9ZwSnYta2iRDRric3IxVQUpcxXoihNv+8tlauzmPXT3iSlM+QzjGIBudGqzKcw==", - "requires": { - "ajv": "^6.12.5", - "ajv-formats-draft2019": "^1.4.3", - "json5": "^2.1.3" - } - }, - "@randlabs/js-logger": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@randlabs/js-logger/-/js-logger-1.2.0.tgz", - "integrity": "sha512-WB0oQ7KDrJwDGeHhdE45v6XGZYn4lm2LO2phP+QoaIlbv+GVVm79yuWuSuqmUZ52a3TAqnxoTpfCPdzHr8IGxw==", - "requires": { - "colors": "^1.4.0", - "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0", - "winston-syslog": "^2.4.4" - } - }, - "@solana/buffer-layout": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz", - "integrity": "sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==", - "requires": { - "buffer": "~6.0.3" - } - }, - "@solana/spl-token": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/@solana/spl-token/-/spl-token-0.1.8.tgz", - "integrity": "sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==", - "requires": { - "@babel/runtime": "^7.10.5", - "@solana/web3.js": "^1.21.0", - "bn.js": "^5.1.0", - "buffer": "6.0.3", - "buffer-layout": "^1.2.0", - "dotenv": "10.0.0" - } - }, - "@solana/web3.js": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.30.2.tgz", - "integrity": "sha512-hznCj+rkfvM5taRP3Z+l5lumB7IQnDrB4l55Wpsg4kDU9Zds8pE5YOH5Z9bbF/pUzZJKQjyBjnY/6kScBm3Ugg==", - "requires": { - "@babel/runtime": "^7.12.5", - "@ethersproject/sha2": "^5.5.0", - "@solana/buffer-layout": "^3.0.0", - "bn.js": "^5.0.0", - "borsh": "^0.4.0", - "bs58": "^4.0.1", - "buffer": "6.0.1", - "cross-fetch": "^3.1.4", - "jayson": "^3.4.4", - "js-sha3": "^0.8.0", - "rpc-websockets": "^7.4.2", - "secp256k1": "^4.0.2", - "superstruct": "^0.14.2", - "tweetnacl": "^1.0.0" - }, - "dependencies": { - "buffer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.1.tgz", - "integrity": "sha512-rVAXBwEcEoYtxnHSO5iWyhzV/O1WMtkUYWlfdLS7FjU4PnSJJHEfHXi/uHPI5EwltmOA794gN3bm3/pzuctWjQ==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - } - } - }, - "@terra-dev/browser-check": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/browser-check/-/browser-check-2.3.0.tgz", - "integrity": "sha512-dHSrk1f6UbA2PQ6OjZo4w66/QyfbTr/OGeTKGarsaFgPCK3SJ4H3wM3sWfJqG7yn/DYpclWmnHvnRUbVHQdcog==", - "requires": { - "bowser": "^2.11.0", - "mobile-detect": "^1.4.5" - } - }, - "@terra-dev/chrome-extension": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/chrome-extension/-/chrome-extension-2.3.0.tgz", - "integrity": "sha512-R+SWvc4DLECKp7aHS1pwQ0gK4XuhsqaInTGNf/NOXg6vxlFsl3bg1Yj5vVS9ro4HaG7zH+/WP0wCn8WZ+7Ulgw==", - "requires": { - "@terra-dev/browser-check": "^2.3.0", - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0", - "rxjs": "^7.3.0" - } - }, - "@terra-dev/readonly-wallet": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/readonly-wallet/-/readonly-wallet-2.3.0.tgz", - "integrity": "sha512-oBUy8U598ly/LWE+sKb45fqAFB/CQvJbRBYzeUJZUKUdQUP50xG4fMyga/ANoUpDNd3GEwkl41uG3JSYTctRKw==", - "requires": { - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0" - } - }, - "@terra-dev/readonly-wallet-modal": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/readonly-wallet-modal/-/readonly-wallet-modal-2.3.0.tgz", - "integrity": "sha512-UcHigWCPZdYjsQ7GbCg65+yKgUEUvstweJiMnV82ihM2nqOTRSNlLjd0rlJ1t3IZQFrBnELF5jXDhGMsOLExLA==", - "requires": { - "@terra-dev/readonly-wallet": "^2.3.0", - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0", - "styled-components": "^5.0.0" - } - }, - "@terra-dev/use-wallet": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/use-wallet/-/use-wallet-2.3.0.tgz", - "integrity": "sha512-F3YZmVKD1EancUGO8In845pqiqEbk5UEu8Or32xHPywJ7Qa+5LYS5fiX6NKgz1BB7MZ5iW2gIWjwo93eejvqNw==", - "requires": { - "@terra-dev/wallet-types": "^2.3.0", - "@terra-money/terra.js": "^2.0.0" - } - }, - "@terra-dev/wallet-types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/wallet-types/-/wallet-types-2.3.0.tgz", - "integrity": "sha512-WpuEuiqXlCHVWomE9nnkpWUDtWiaKLB9iCLsfGqUyU8AInqDyALydtAGpGtIj8SykqX/6wGRDeK67DBCqVdd3w==", - "requires": { - "@terra-money/terra.js": "^2.0.0" - } - }, - "@terra-dev/walletconnect": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/walletconnect/-/walletconnect-2.3.0.tgz", - "integrity": "sha512-eodXfTwD/EYNjejwJW4c5IMFjWT/Tgde70c4BexpMrAif3OXkFwZyNVEATLaqsisHzdq5vJ7oOTaWCHxu03uRg==", - "requires": { - "@terra-dev/browser-check": "^2.3.0", - "@terra-dev/walletconnect-qrcode-modal": "^2.3.0", - "@terra-money/terra.js": "^2.0.0", - "@walletconnect/core": "^1.6.1", - "@walletconnect/iso-crypto": "^1.6.1", - "@walletconnect/types": "^1.6.1", - "@walletconnect/utils": "^1.6.1", - "rxjs": "^7.3.0", - "ws": "^7.5.3" - } - }, - "@terra-dev/walletconnect-qrcode-modal": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-dev/walletconnect-qrcode-modal/-/walletconnect-qrcode-modal-2.3.0.tgz", - "integrity": "sha512-S1jokcgValyGrTvcyOHRwTKFYxhnAROYp5cPglywD4YYMZEXmw85+9AULFUIDDL87Wv0hrJXyznXSNdpAoZ9pA==", - "requires": { - "@terra-dev/browser-check": "^2.3.0", - "@walletconnect/types": "^1.6.1", - "qrcode.react": "^1.0.1", - "styled-components": "^5.0.0" - } - }, - "@terra-dev/web-connector-controller": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@terra-dev/web-connector-controller/-/web-connector-controller-0.7.0.tgz", - "integrity": "sha512-hH27gma1Mb04bMIf/x/Rza2uiWDv18xcdLtx5s+3111ycL1REeIU6RyGAsiXVUy0HWf8YGODLscJVxSK7Kn30g==", - "requires": { - "@terra-dev/web-connector-interface": "^0.7.0", - "@terra-money/terra.js": "^2.0.14", - "bowser": "^2.11.0", - "rxjs": "^7.3.0" - } - }, - "@terra-dev/web-connector-interface": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@terra-dev/web-connector-interface/-/web-connector-interface-0.7.0.tgz", - "integrity": "sha512-bYyMk18lFTzEccsWjqg2UbgA7olkHKerl0JD9MgGRqVvAJAbkXQ4hWBFu6EfrmFAdCwHDT4xgu41WtbEmjBNqQ==", - "requires": { - "@terra-money/terra.js": "^2.0.14", - "rxjs": "^7.3.0" - } - }, - "@terra-money/terra.js": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-2.0.16.tgz", - "integrity": "sha512-kPW45vIeAbTgHRimoCzsJS9B9XfDI+5OzHhhLCqHUJpZwL5bEhA+wDu216VcHrq1R0fMBmsGlIq3ugrX5HTG+A==", - "requires": { - "axios": "^0.24.0", - "bech32": "^2.0.0", - "bip32": "^2.0.6", - "bip39": "^3.0.3", - "bufferutil": "^4.0.3", - "decimal.js": "^10.2.1", - "jscrypto": "^1.0.1", - "readable-stream": "^3.6.0", - "secp256k1": "^4.0.2", - "tmp": "^0.2.1", - "utf-8-validate": "^5.0.5", - "ws": "^7.5.5" - } - }, - "@terra-money/wallet-provider": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@terra-money/wallet-provider/-/wallet-provider-2.3.0.tgz", - "integrity": "sha512-ee1iK5cxffOlgPSxO1vzPdGB01u1uvq+VP+74KPY1k+GpqOCYezOZGbLVMWXOuu861GxMuMl90K9Eu0n32mwQg==", - "requires": { - "@terra-dev/browser-check": "^2.3.0", - "@terra-dev/chrome-extension": "^2.3.0", - "@terra-dev/readonly-wallet": "^2.3.0", - "@terra-dev/readonly-wallet-modal": "^2.3.0", - "@terra-dev/use-wallet": "^2.3.0", - "@terra-dev/wallet-types": "^2.3.0", - "@terra-dev/walletconnect": "^2.3.0", - "@terra-dev/web-connector-controller": "^0.7.0", - "@terra-dev/web-connector-interface": "^0.7.0", - "@terra-money/terra.js": "^2.0.0", - "fast-deep-equal": "^3.1.3", - "rxjs": "^7.3.0" - } - }, - "@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", - "dev": true - }, - "@types/express-serve-static-core": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.25.tgz", - "integrity": "sha512-OUJIVfRMFijZukGGwTpKNFprqCCXk5WjNGvUgB/CxxBR40QWSjsNK86+yvGKlCOGc7sbwfHLaXhkG+NsytwBaQ==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@types/lodash": { - "version": "4.14.176", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz", - "integrity": "sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ==" - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/node": { - "version": "16.11.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz", - "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==" - }, - "@types/pbkdf2": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", - "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" - }, - "@types/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w==", - "requires": { - "@types/node": "*" - } - }, - "@types/superagent": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.13.tgz", - "integrity": "sha512-YIGelp3ZyMiH0/A09PMAORO0EBGlF5xIKfDpK74wdYvWUs2o96b5CItJcWPdH409b7SAXIIG6p8NdU/4U2Maww==", - "dev": true, - "requires": { - "@types/cookiejar": "*", - "@types/node": "*" - } - }, - "@types/ws": { - "version": "7.4.7", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.4.7.tgz", - "integrity": "sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==", - "requires": { - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - } - } - }, - "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "@walletconnect/browser-utils": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/browser-utils/-/browser-utils-1.6.6.tgz", - "integrity": "sha512-E29xSHU7Akd4jaPehWVGx7ct+SsUzZbxcGc0fz+Pw6/j4Gh5tlfYZ9XuVixuYI4WPdQ2CmOraj8RrVOu5vba4w==", - "requires": { - "@walletconnect/safe-json": "1.0.0", - "@walletconnect/types": "^1.6.6", - "@walletconnect/window-getters": "1.0.0", - "@walletconnect/window-metadata": "1.0.0", - "detect-browser": "5.2.0" - } - }, - "@walletconnect/core": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/core/-/core-1.6.6.tgz", - "integrity": "sha512-pSftIVPY6mYz2koZPBEYmeFeAjVf2MSnRHOM6+vx+iAsUEcfMZHkgeXX6GtM6Fjza+zSZu1qnmdgURVXpmKwtQ==", - "requires": { - "@walletconnect/socket-transport": "^1.6.6", - "@walletconnect/types": "^1.6.6", - "@walletconnect/utils": "^1.6.6" - } - }, - "@walletconnect/crypto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@walletconnect/crypto/-/crypto-1.0.1.tgz", - "integrity": "sha512-IgUReNrycIFxkGgq8YT9HsosCkhutakWD9Q411PR0aJfxpEa/VKJeaLRtoz6DvJpztWStwhIHnAbBoOVR72a6g==", - "requires": { - "@walletconnect/encoding": "^1.0.0", - "@walletconnect/environment": "^1.0.0", - "@walletconnect/randombytes": "^1.0.1", - "aes-js": "^3.1.2", - "hash.js": "^1.1.7" - } - }, - "@walletconnect/encoding": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/encoding/-/encoding-1.0.0.tgz", - "integrity": "sha512-4nkJFnS0QF5JdieG/3VPD1/iEWkLSZ14EBInLZ00RWxmC6EMZrzAeHNAWIgm+xP3NK0lqz+7lEsmWGtcl5gYnQ==", - "requires": { - "is-typedarray": "1.0.0", - "typedarray-to-buffer": "3.1.5" - } - }, - "@walletconnect/environment": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/environment/-/environment-1.0.0.tgz", - "integrity": "sha512-4BwqyWy6KpSvkocSaV7WR3BlZfrxLbJSLkg+j7Gl6pTDE+U55lLhJvQaMuDVazXYxcjBsG09k7UlH7cGiUI5vQ==" - }, - "@walletconnect/iso-crypto": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/iso-crypto/-/iso-crypto-1.6.6.tgz", - "integrity": "sha512-wRYgKvd8K3A9FVLn2c0cDh4+9OUHkqibKtwQJTJsz+ibPGgd+n5j1/FjnzDDRGb9T1+TtlwYF3ZswKyys3diVQ==", - "requires": { - "@walletconnect/crypto": "^1.0.1", - "@walletconnect/types": "^1.6.6", - "@walletconnect/utils": "^1.6.6" - } - }, - "@walletconnect/jsonrpc-types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.0.tgz", - "integrity": "sha512-11QXNq5H1PKZk7bP8SxgmCw3HRaDuPOVE+wObqEvmhc7OWYUZqfuaaMb+OXGRSOHL3sbC+XHfdeCxFTMXSFyng==", - "requires": { - "keyvaluestorage-interface": "^1.0.0" - } - }, - "@walletconnect/jsonrpc-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.0.tgz", - "integrity": "sha512-qUHbKUK6sHeHn67qtHZoLoYk5hS6x1arTPjKDRkY93/6Fx+ZmNIpdm1owX3l6aYueyegJ7mz43FpvYHUqJ8xcw==", - "requires": { - "@walletconnect/environment": "^1.0.0", - "@walletconnect/jsonrpc-types": "^1.0.0" - } - }, - "@walletconnect/randombytes": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@walletconnect/randombytes/-/randombytes-1.0.1.tgz", - "integrity": "sha512-YJTyq69i0PtxVg7osEpKfvjTaWuAsR49QEcqGKZRKVQWMbGXBZ65fovemK/SRgtiFRv0V8PwsrlKSheqzfPNcg==", - "requires": { - "@walletconnect/encoding": "^1.0.0", - "@walletconnect/environment": "^1.0.0", - "randombytes": "^2.1.0" - } - }, - "@walletconnect/safe-json": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/safe-json/-/safe-json-1.0.0.tgz", - "integrity": "sha512-QJzp/S/86sUAgWY6eh5MKYmSfZaRpIlmCJdi5uG4DJlKkZrHEF7ye7gA+VtbVzvTtpM/gRwO2plQuiooIeXjfg==" - }, - "@walletconnect/socket-transport": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/socket-transport/-/socket-transport-1.6.6.tgz", - "integrity": "sha512-mugCEoeKTx75ogb5ROg/+LA3yGTsuRNcrYgrApceo7WNU9Z4dG8l6ycMPqrrFcODcrasq3NmXVWUYDv/CvrzSw==", - "requires": { - "@walletconnect/types": "^1.6.6", - "@walletconnect/utils": "^1.6.6", - "ws": "7.5.3" - }, - "dependencies": { - "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", - "requires": {} - } - } - }, - "@walletconnect/types": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/types/-/types-1.6.6.tgz", - "integrity": "sha512-op77cxexOmQQN36XB1sYouNTlBRV0Rup/2NYK8A1ffdwXa3a6HLHHdhBM7I/I9BVmRXoZ4+XoOnPKGGrYtlS3g==" - }, - "@walletconnect/utils": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/@walletconnect/utils/-/utils-1.6.6.tgz", - "integrity": "sha512-s2X/cVXiMDSEoWV6i7HPMbP1obXlzP7KLMrBo9OMabiJKnQEh6HSZ39WLswB2PHnl8Hp1Sr4BdRvhM5kCcYWRw==", - "requires": { - "@walletconnect/browser-utils": "^1.6.6", - "@walletconnect/encoding": "^1.0.0", - "@walletconnect/jsonrpc-utils": "^1.0.0", - "@walletconnect/types": "^1.6.6", - "bn.js": "4.11.8", - "js-sha3": "0.8.0", - "query-string": "6.13.5" - }, - "dependencies": { - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" - } - } - }, - "@walletconnect/window-getters": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/window-getters/-/window-getters-1.0.0.tgz", - "integrity": "sha512-xB0SQsLaleIYIkSsl43vm8EwETpBzJ2gnzk7e0wMF3ktqiTGS6TFHxcprMl5R44KKh4tCcHCJwolMCaDSwtAaA==" - }, - "@walletconnect/window-metadata": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@walletconnect/window-metadata/-/window-metadata-1.0.0.tgz", - "integrity": "sha512-9eFvmJxIKCC3YWOL97SgRkKhlyGXkrHwamfechmqszbypFspaSk+t2jQXAEU7YClHF6Qjw5eYOmy1//zFi9/GA==", - "requires": { - "@walletconnect/window-getters": "^1.0.0" - } - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "aes-js": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-formats-draft2019": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ajv-formats-draft2019/-/ajv-formats-draft2019-1.6.1.tgz", - "integrity": "sha512-JQPvavpkWDvIsBp2Z33UkYCtXCSpW4HD3tAZ+oL4iEFOk9obQZffx0yANwECt6vzr6ET+7HN5czRyqXbnq/u0Q==", - "requires": { - "punycode": "^2.1.1", - "schemes": "^1.4.0", - "smtp-address-parser": "^1.0.3", - "uri-js": "^4.4.1" - } - }, - "algo-msgpack-with-bigint": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/algo-msgpack-with-bigint/-/algo-msgpack-with-bigint-2.1.1.tgz", - "integrity": "sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==" - }, - "algosdk": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/algosdk/-/algosdk-1.12.0.tgz", - "integrity": "sha512-Iqek0AwcCeXLywVg4E8gWWjmuPZ10P7PUmpZrlR71FSNyEtX4Ie+UgrNHWhkYnhyykRU5mjtvD4Hrb2eOepsGA==", - "requires": { - "algo-msgpack-with-bigint": "^2.1.1", - "buffer": "^6.0.2", - "hi-base32": "^0.5.1", - "js-sha256": "^0.9.0", - "js-sha3": "^0.8.0", - "js-sha512": "^0.8.0", - "json-bigint": "^1.0.0", - "superagent": "^6.1.0", - "tweetnacl": "^1.0.3", - "url-parse": "^1.5.1" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==" - }, - "axios": { - "version": "0.24.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", - "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", - "requires": { - "follow-redirects": "^1.14.4" - } - }, - "babel-plugin-styled-components": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz", - "integrity": "sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-module-imports": "^7.15.4", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "base58-universal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base58-universal/-/base58-universal-1.0.0.tgz", - "integrity": "sha512-v0Ja4jwaQP8gBZPNXpfaXlLht2ed/Gp3AsVUZXtlZgY1qbKS0CjxvYs43U0Gh00zbVc1neMe+q/ULJ7ubVyB+w==", - "requires": { - "esm": "^3.2.25" - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bech32": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", - "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==" - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "requires": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - }, - "dependencies": { - "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" - } - } - }, - "bip39": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.4.tgz", - "integrity": "sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==", - "requires": { - "@types/node": "11.11.6", - "create-hash": "^1.1.0", - "pbkdf2": "^3.0.9", - "randombytes": "^2.0.1" - }, - "dependencies": { - "@types/node": { - "version": "11.11.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", - "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" - } - } - }, - "blakejs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.1.tgz", - "integrity": "sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==" - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==" - }, - "borsh": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/borsh/-/borsh-0.4.0.tgz", - "integrity": "sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==", - "requires": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", - "bs58": "^4.0.0", - "text-encoding-utf-8": "^1.0.2" - } - }, - "bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" - }, - "browser-headers": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz", - "integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==" - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "requires": { - "base-x": "^3.0.2" - } - }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" - } - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "buffer-layout": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/buffer-layout/-/buffer-layout-1.2.2.tgz", - "integrity": "sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==" - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" - }, - "bufferutil": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz", - "integrity": "sha512-HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==", - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "camelize": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", - "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "charm": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", - "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", - "requires": { - "inherits": "^2.0.1" - } - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-json": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - }, - "dependencies": { - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - } - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "color-string": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.0.tgz", - "integrity": "sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "colorspace": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", - "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", - "requires": { - "color": "^3.1.3", - "text-hex": "1.0.x" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cookiejar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", - "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==" - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "cross-fetch": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", - "integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==", - "requires": { - "node-fetch": "2.6.1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" - }, - "css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "delay": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", - "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "detect-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/detect-browser/-/detect-browser-5.2.0.tgz", - "integrity": "sha512-tr7XntDAu50BVENgQfajMLzacmSe34D+qZc4zjnniz0ZVuw/TZcLcyxHQjYpJTM36sGEkZZlYLnIM1hH7alTMA==" - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "enabled": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", - "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=" - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "eslint-config-standard": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true, - "requires": {} - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.25.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.3.tgz", - "integrity": "sha512-RzAVbby+72IB3iOEL8clzPLzL3wpDrlwjsTBAQXgyp5SeTqqY+0bFubwuo+y/HLhNZcXV4XqTBO4LGsfyHIDXg==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.1", - "has": "^1.0.3", - "is-core-module": "^2.8.0", - "is-glob": "^4.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-node": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", - "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", - "dev": true, - "requires": { - "eslint-plugin-es": "^3.0.0", - "eslint-utils": "^2.0.0", - "ignore": "^5.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.10.1", - "semver": "^6.1.0" - }, - "dependencies": { - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.1.1.tgz", - "integrity": "sha512-XgdcdyNzHfmlQyweOPTxmc7pIsS6dE4MvwhXWMQ2Dxs1XAL2GJDilUsjWen6TWik0aSI+zD/PqocZBblcm9rdA==", - "dev": true, - "requires": {} - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==" - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "ethereum-bloom-filters": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz", - "integrity": "sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA==", - "requires": { - "js-sha3": "^0.8.0" - } - }, - "ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "requires": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } - }, - "ethereumjs-util": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.3.tgz", - "integrity": "sha512-y+82tEbyASO0K0X1/SRhbJJoAlfcvq8JbrG4a5cjrOks7HS/36efU/0j2flxCPOUM++HFahk33kr/ZxyC4vNuw==", - "requires": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, - "dependencies": { - "@types/bn.js": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.0.tgz", - "integrity": "sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==", - "requires": { - "@types/node": "*" - } - } - } - }, - "ethers": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.5.1.tgz", - "integrity": "sha512-RodEvUFZI+EmFcE6bwkuJqpCYHazdzeR1nMzg+YWQSmQEsNtfl1KHGfp/FWZYl48bI/g7cgBeP2IlPthjiVngw==", - "requires": { - "@ethersproject/abi": "5.5.0", - "@ethersproject/abstract-provider": "5.5.1", - "@ethersproject/abstract-signer": "5.5.0", - "@ethersproject/address": "5.5.0", - "@ethersproject/base64": "5.5.0", - "@ethersproject/basex": "5.5.0", - "@ethersproject/bignumber": "5.5.0", - "@ethersproject/bytes": "5.5.0", - "@ethersproject/constants": "5.5.0", - "@ethersproject/contracts": "5.5.0", - "@ethersproject/hash": "5.5.0", - "@ethersproject/hdnode": "5.5.0", - "@ethersproject/json-wallets": "5.5.0", - "@ethersproject/keccak256": "5.5.0", - "@ethersproject/logger": "5.5.0", - "@ethersproject/networks": "5.5.0", - "@ethersproject/pbkdf2": "5.5.0", - "@ethersproject/properties": "5.5.0", - "@ethersproject/providers": "5.5.0", - "@ethersproject/random": "5.5.0", - "@ethersproject/rlp": "5.5.0", - "@ethersproject/sha2": "5.5.0", - "@ethersproject/signing-key": "5.5.0", - "@ethersproject/solidity": "5.5.0", - "@ethersproject/strings": "5.5.0", - "@ethersproject/transactions": "5.5.0", - "@ethersproject/units": "5.5.0", - "@ethersproject/wallet": "5.5.0", - "@ethersproject/web": "5.5.0", - "@ethersproject/wordlists": "5.5.0" - } - }, - "ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", - "requires": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==" - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fecha": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.1.tgz", - "integrity": "sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q==" - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-stream-rotator": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz", - "integrity": "sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ==", - "requires": { - "moment": "^2.11.2" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.4.tgz", - "integrity": "sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw==", - "dev": true - }, - "fn.name": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", - "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" - }, - "follow-redirects": { - "version": "1.14.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", - "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "glossy": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/glossy/-/glossy-0.1.7.tgz", - "integrity": "sha1-dptZhKlvYGarnqdYIkgl7mwhDws=" - }, - "google-protobuf": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.19.1.tgz", - "integrity": "sha512-Isv1RlNC+IzZzilcxnlVSf+JvuhxmY7DaxYCBy+zPS9XVuJRtlTTIXR9hnZ1YL1MMusJn/7eSy2swCzZIomQSg==", - "peer": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hi-base32": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", - "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz", - "integrity": "sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==" - }, - "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" - }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-observable": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", - "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==" - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==" - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.8.tgz", - "integrity": "sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "requires": { - "call-bind": "^1.0.0" - } - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isomorphic-ws": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", - "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", - "requires": {} - }, - "jayson": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/jayson/-/jayson-3.6.5.tgz", - "integrity": "sha512-wmOjX+eQcnCDyPF4KORomaIj9wj3h0B5VEbeD0+2VHfTfErB+h1zpR7oBkgCZp36AFjp3+a4CLz6U72BYpFHAw==", - "requires": { - "@types/connect": "^3.4.33", - "@types/express-serve-static-core": "^4.17.9", - "@types/lodash": "^4.14.159", - "@types/node": "^12.12.54", - "@types/ws": "^7.4.4", - "commander": "^2.20.3", - "delay": "^5.0.0", - "es6-promisify": "^5.0.0", - "eyes": "^0.1.8", - "isomorphic-ws": "^4.0.1", - "json-stringify-safe": "^5.0.1", - "JSONStream": "^1.3.5", - "lodash": "^4.17.20", - "uuid": "^3.4.0", - "ws": "^7.4.5" - }, - "dependencies": { - "@types/node": { - "version": "12.20.37", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", - "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==" - } - } - }, - "js-base64": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.2.tgz", - "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" - }, - "js-sha256": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", - "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" - }, - "js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, - "js-sha512": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", - "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jscrypto": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/jscrypto/-/jscrypto-1.0.2.tgz", - "integrity": "sha512-r+oNJLGTv1nkNMBBq3c70xYrFDgJOYVgs2OHijz5Ht+0KJ0yObD0oYxC9mN72KLzVfXw+osspg6t27IZvuTUxw==" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "keccak": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.2.tgz", - "integrity": "sha512-PyKKjkH53wDMLGrvmRGSNWgmSxZOUqbnXwKL9tmgbFYA1iAYqW21kfR7mZXV0MlESiefxQQE9X9fTa3X+2MPDQ==", - "requires": { - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0", - "readable-stream": "^3.6.0" - } - }, - "keyvaluestorage-interface": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz", - "integrity": "sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==" - }, - "kuler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", - "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "logform": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", - "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", - "requires": { - "colors": "^1.2.1", - "fecha": "^4.2.0", - "ms": "^2.1.1", - "safe-stable-stringify": "^1.1.0", - "triple-beam": "^1.3.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" - }, - "mime-db": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", - "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" - }, - "mime-types": { - "version": "2.1.34", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", - "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", - "requires": { - "mime-db": "1.51.0" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "mobile-detect": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/mobile-detect/-/mobile-detect-1.4.5.tgz", - "integrity": "sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g==" - }, - "mocha": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.1.3.tgz", - "integrity": "sha512-Xcpl9FqXOAYqI3j79pEtHBBnQgVXIhpULjGQa7DVb0Po+VzmSIK9kanAiWLHoRR/dbZ2qpdPshuXr8l1VaHCzw==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.2", - "debug": "4.3.2", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.1.7", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "nanoid": "3.1.25", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.1.5", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, - "moo": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", - "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" - }, - "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "nearley": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", - "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", - "requires": { - "commander": "^2.19.0", - "moo": "^0.5.0", - "railroad-diagrams": "^1.0.0", - "randexp": "0.4.6" - } - }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" - }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" - }, - "node-gyp-build": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz", - "integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", - "requires": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" - } - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-hash": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", - "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==" - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "observable-fns": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/observable-fns/-/observable-fns-0.6.1.tgz", - "integrity": "sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "one-time": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", - "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", - "requires": { - "fn.name": "1.x.x" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "protobufjs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.2.tgz", - "integrity": "sha512-4BQJoPooKJl2G9j3XftkIXjoC9C0Av2NOrWmbLWT1vH32GcSUHjM0Arra6UfTsVyfMAuFzaLucXn1sadxJydAw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qr.js": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz", - "integrity": "sha1-ys6GOG9ZoNuAUPqQ2baw6IoeNk8=" - }, - "qrcode.react": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-1.0.1.tgz", - "integrity": "sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg==", - "requires": { - "loose-envify": "^1.4.0", - "prop-types": "^15.6.0", - "qr.js": "0.0.0" - } - }, - "qs": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.2.tgz", - "integrity": "sha512-mSIdjzqznWgfd4pMii7sHtaYF8rx8861hBO80SraY5GT0XQibWZWJSid0avzHGkDIZLImux2S5mXO0Hfct2QCw==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "query-string": { - "version": "6.13.5", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.5.tgz", - "integrity": "sha512-svk3xg9qHR39P3JlHuD7g3nRnyay5mHbrPctEBDUxUkHRifPHXJDhBUycdCC0NBjXoDf44Gb+IsOZL1Uwn8M/Q==", - "requires": { - "decode-uri-component": "^0.2.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "railroad-diagrams": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", - "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=" - }, - "randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "requires": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "react": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", - "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "react-dom": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", - "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "peer": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "rlp": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", - "requires": { - "bn.js": "^5.2.0" - } - }, - "rpc-websockets": { - "version": "7.4.16", - "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-7.4.16.tgz", - "integrity": "sha512-0b7OVhutzwRIaYAtJo5tqtaQTWKfwAsKnaThOSOy+VkhVdleNUgb8eZnWSdWITRZZEigV5uPEIDr5KZe4DBrdQ==", - "requires": { - "@babel/runtime": "^7.11.2", - "bufferutil": "^4.0.1", - "circular-json": "^0.5.9", - "eventemitter3": "^4.0.7", - "utf-8-validate": "^5.0.2", - "uuid": "^8.3.0", - "ws": "^7.4.5" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - } - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rxjs": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.4.0.tgz", - "integrity": "sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w==", - "requires": { - "tslib": "~2.1.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-stable-stringify": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", - "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==" - }, - "scheduler": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", - "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "peer": true, - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "schemes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/schemes/-/schemes-1.4.0.tgz", - "integrity": "sha512-ImFy9FbCsQlVgnE3TCWmLPCFnVzx0lHL/l+umHplDqAKd0dzFpnS6lFZIpagBlYhKwzVmlV36ec0Y1XTu8JBAQ==", - "requires": { - "extend": "^3.0.0" - } - }, - "scrypt-js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" - }, - "secp256k1": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", - "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "requires": { - "elliptic": "^6.5.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "smtp-address-parser": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/smtp-address-parser/-/smtp-address-parser-1.0.7.tgz", - "integrity": "sha512-QmmaQ99AtWTUtPXmUiwRXZN7IFLGS/SstKUyjsdqkQvGOwhTCMJw/Z+l9F3ImcZ5rLDj9y1mvwZ/+GAvMoa9Wg==", - "requires": { - "nearley": "^2.20.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, - "strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "requires": { - "is-hex-prefixed": "1.0.0" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "styled-components": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz", - "integrity": "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^0.8.8", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "superagent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-6.1.0.tgz", - "integrity": "sha512-OUDHEssirmplo3F+1HWKUrUjvnQuA+nZI6i/JJBdXb5eq9IyEQwPyPpqND+SSsxf6TygpBEkUjISVRN4/VOpeg==", - "requires": { - "component-emitter": "^1.3.0", - "cookiejar": "^2.1.2", - "debug": "^4.1.1", - "fast-safe-stringify": "^2.0.7", - "form-data": "^3.0.0", - "formidable": "^1.2.2", - "methods": "^1.1.2", - "mime": "^2.4.6", - "qs": "^6.9.4", - "readable-stream": "^3.6.0", - "semver": "^7.3.2" - } - }, - "superstruct": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.14.2.tgz", - "integrity": "sha512-nPewA6m9mR3d6k7WkZ8N8zpTWfenFH3q9pA2PkuiZxINr9DKB2+40wEQf0ixn8VaGuJ78AB6iWOtStI+/4FKZQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "table": { - "version": "6.7.3", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.3.tgz", - "integrity": "sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.7.1.tgz", - "integrity": "sha512-gPpOObTO1QjbnN1sVMjJcp1TF9nggMfO4MBR5uQl6ZVTOaEPq5i4oq/6R9q2alMMPB3eg53wFv1RuJBLuxf3Hw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, - "text-encoding-utf-8": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz", - "integrity": "sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==" - }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "threads": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/threads/-/threads-1.7.0.tgz", - "integrity": "sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==", - "requires": { - "callsites": "^3.1.0", - "debug": "^4.2.0", - "is-observable": "^2.1.0", - "observable-fns": "^0.6.1", - "tiny-worker": ">= 2" - } - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "tiny-secp256k1": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", - "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", - "requires": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "tiny-worker": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.3.0.tgz", - "integrity": "sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==", - "optional": true, - "requires": { - "esm": "^3.2.25" - } - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "requires": { - "rimraf": "^3.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, - "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - } - } - }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typeforce": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", - "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" - }, - "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", - "dev": true, - "peer": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "unix-dgram": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unix-dgram/-/unix-dgram-2.0.3.tgz", - "integrity": "sha512-Bay5CkSLcdypcBCsxvHEvaG3mftzT5FlUnRToPWEAVxwYI8NI/8zSJ/Gknlp86MPhV6hBA8I8TBsETj2tssoHQ==", - "optional": true, - "requires": { - "bindings": "^1.3.0", - "nan": "^2.13.2" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "url-parse": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "utf-8-validate": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz", - "integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==", - "requires": { - "node-gyp-build": "^4.3.0" - } - }, - "utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" - }, - "util": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.4.tgz", - "integrity": "sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==", - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "safe-buffer": "^5.1.2", - "which-typed-array": "^1.1.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "web3-eth-abi": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.6.1.tgz", - "integrity": "sha512-svhYrAlXP9XQtV7poWKydwDJq2CaNLMtmKydNXoOBLcQec6yGMP+v20pgrxF2H6wyTK+Qy0E3/5ciPOqC/VuoQ==", - "requires": { - "@ethersproject/abi": "5.0.7", - "web3-utils": "1.6.1" - }, - "dependencies": { - "@ethersproject/abi": { - "version": "5.0.7", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.7.tgz", - "integrity": "sha512-Cqktk+hSIckwP/W8O47Eef60VwmoSC/L3lY0+dIBhQPCNn9E4V7rwmm2aFrNRRDJfFlGuZ1khkQUOc3oBX+niw==", - "requires": { - "@ethersproject/address": "^5.0.4", - "@ethersproject/bignumber": "^5.0.7", - "@ethersproject/bytes": "^5.0.4", - "@ethersproject/constants": "^5.0.4", - "@ethersproject/hash": "^5.0.4", - "@ethersproject/keccak256": "^5.0.3", - "@ethersproject/logger": "^5.0.5", - "@ethersproject/properties": "^5.0.3", - "@ethersproject/strings": "^5.0.4" - } - } - } - }, - "web3-utils": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.6.1.tgz", - "integrity": "sha512-RidGKv5kOkcerI6jQqDFDoTllQQqV+rPhTzZHhmbqtFObbYpU93uc+yG1LHivRTQhA6llIx67iudc/vzisgO+w==", - "requires": { - "bn.js": "^4.11.9", - "ethereum-bloom-filters": "^1.0.6", - "ethereumjs-util": "^7.1.0", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - } - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.7.tgz", - "integrity": "sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==", - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.18.5", - "foreach": "^2.0.5", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.7" - } - }, - "wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", - "requires": { - "bs58check": "<3.0.0" - } - }, - "winston": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.3.3.tgz", - "integrity": "sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw==", - "requires": { - "@dabh/diagnostics": "^2.0.2", - "async": "^3.1.0", - "is-stream": "^2.0.0", - "logform": "^2.2.0", - "one-time": "^1.0.0", - "readable-stream": "^3.4.0", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - } - }, - "winston-daily-rotate-file": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.5.tgz", - "integrity": "sha512-ds0WahIjiDhKCiMXmY799pDBW+58ByqIBtUcsqr4oDoXrAI3Zn+hbgFdUxzMfqA93OG0mPLYVMiotqTgE/WeWQ==", - "requires": { - "file-stream-rotator": "^0.5.7", - "object-hash": "^2.0.1", - "triple-beam": "^1.3.0", - "winston-transport": "^4.4.0" - } - }, - "winston-syslog": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/winston-syslog/-/winston-syslog-2.4.4.tgz", - "integrity": "sha512-zDjoKO932Yszvzq8WtbIFMXHwAT2MOxpWC9s6djw2tvjdRESWw3au6l+0xDMatMhNWVoVaVNkDXF+r/eyoBUVA==", - "requires": { - "glossy": "^0.1.7", - "unix-dgram": "2.0.3" - } - }, - "winston-transport": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.4.1.tgz", - "integrity": "sha512-ciZRlU4CSjHqHe8RQG1iPxKMRVwv6ZJ0RC7DxStKWd0KjpAhPDy5gVYSCpIUq+5CUsP+IyNOTZy1X0tO2QZqjg==", - "requires": { - "logform": "^2.2.0", - "readable-stream": "^3.4.0", - "triple-beam": "^1.2.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workerpool": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", - "integrity": "sha512-XdKkCK0Zqc6w3iTxLckiuJ81tiD/o5rBE/m+nXpRCB+/Sq4DqkfXZ/x0jW02DG1tGsfUGXbTJyZDP+eu67haSw==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "requires": {} - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/staging/algorand/package.json b/staging/algorand/package.json deleted file mode 100644 index 6c2b60397..000000000 --- a/staging/algorand/package.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "pricecaster", - "version": "2.0.0", - "description": "Pricecaster V2 Service", - "main": "index.js", - "scripts": { - "compile": "tsc", - "build": "rimraf build && npm run compile", - "prepack": "npm run build", - "start": "npm run compile && cross-env PRICECASTER_SETTINGS=./settings/settings-worm.js node build/main.js", - "test-wormhole-sc": "mocha test/wormhole-sc-test.js --timeout 60000 --bail --allow-uncaught" - }, - "author": "Randlabs inc", - "license": "ISC", - "dependencies": { - "@certusone/wormhole-sdk": "^0.1.3", - "@certusone/wormhole-spydk": "^0.0.1", - "@improbable-eng/grpc-web-node-http-transport": "^0.15.0", - "@pythnetwork/client": "^2.3.1", - "@randlabs/js-config-reader": "^1.1.0", - "@randlabs/js-logger": "^1.2.0", - "algosdk": "^1.12.0", - "base58-universal": "^1.0.0", - "charm": "^1.0.2", - "elliptic": "^6.5.4", - "esm": "^3.2.25", - "ethers": "^5.5.1", - "js-sha512": "^0.8.0", - "web3-eth-abi": "^1.6.1", - "web3-utils": "^1.6.1" - }, - "devDependencies": { - "@types/superagent": "^4.1.13", - "@typescript-eslint/eslint-plugin": "^4.32.0", - "@typescript-eslint/parser": "^4.32.0", - "chai": "^4.3.4", - "chai-as-promised": "^7.1.1", - "cross-env": "^7.0.3", - "eslint": "^7.32.0", - "eslint-config-standard": "^16.0.3", - "eslint-plugin-import": "^2.24.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-promise": "^5.1.0", - "mocha": "^9.1.2", - "rimraf": "^3.0.2" - } -} diff --git a/staging/algorand/scripts/createapp.sh b/staging/algorand/scripts/createapp.sh deleted file mode 100755 index 3a785475d..000000000 --- a/staging/algorand/scripts/createapp.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -goal app create --creator "$OWNER_ADDR" --global-ints 4 --global-byteslices 20 --local-byteslices 0 --local-ints 0 --approval-prog vaa-processor-approval.teal --clear-prog vaa-processor-clear.teal --app-arg "b64:$GKEYSBASE64" --app-arg int:0 --app-arg int:0 -o create.txn -algokey -t create.txn -o create.stxn sign -m "$OWNER_MNEMO" -goal clerk rawsend -f create.stxn - diff --git a/staging/algorand/scripts/deleteapp.sh b/staging/algorand/scripts/deleteapp.sh deleted file mode 100644 index d6f60a1ae..000000000 --- a/staging/algorand/scripts/deleteapp.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -goal app delete --app-id $1 --from "$OWNER_ADDR" -o delete.txn -algokey -t delete.txn -o delete.stxn sign -m "$OWNER_MNEMO" -goal clerk rawsend -f delete.stxn diff --git a/staging/algorand/scripts/gensamplevaa.js b/staging/algorand/scripts/gensamplevaa.js deleted file mode 100644 index 72511c3f7..000000000 --- a/staging/algorand/scripts/gensamplevaa.js +++ /dev/null @@ -1,29 +0,0 @@ -const TestLib = require('../test/testlib.js') -const t = new TestLib.TestLib() -const sigkeys = ['563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757', '8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f', '9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b', -'5a02c4cd110d20a83a7ce8d1a2b2ae5df252b4e5f6781c7855db5cc28ed2d1b4', -'93d4e3b443bf11f99a00901222c032bd5f63cf73fc1bcfa40829824d121be9b2', -'ea40e40c63c6ff155230da64a2c44fcd1f1c9e50cacb752c230f77771ce1d856', -'87eaabe9c27a82198e618bca20f48f9679c0f239948dbd094005e262da33fe6a', -'61ffed2bff38648a6d36d6ed560b741b1ca53d45391441124f27e1e48ca04770', -'bd12a242c6da318fef8f98002efb98efbf434218a78730a197d981bebaee826e', -'20d3597bb16525b6d09e5fb56feb91b053d961ab156f4807e37d980f50e71aff', -'344b313ffbc0199ff6ca08cacdaf5dc1d85221e2f2dc156a84245bd49b981673', -'848b93264edd3f1a521274ca4da4632989eb5303fd15b14e5ec6bcaa91172b05', -'c6f2046c1e6c172497fc23bd362104e2f4460d0f61984938fa16ef43f27d93f6', -'693b256b1ee6b6fb353ba23274280e7166ab3be8c23c203cc76d716ba4bc32bf', -'13c41508c0da03018d61427910b9922345ced25e2bbce50652e939ee6e5ea56d', -'460ee0ee403be7a4f1eb1c63dd1edaa815fbaa6cf0cf2344dcba4a8acf9aca74', -'b25148579b99b18c8994b0b86e4dd586975a78fa6e7ad6ec89478d7fbafd2683', -'90d7ac6a82166c908b8cf1b352f3c9340a8d1f2907d7146fb7cd6354a5436cca', -'b71d23908e4cf5d6cd973394f3a4b6b164eb1065785feee612efdfd8d30005ed' - -] -const vaa = t.createSignedVAA(0, sigkeys, 1, 1, 1, '0x71f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b', 0, 0, '0x12345678') -if (process.argv[2] === '--sig') { - console.log(vaa.substr(12, sigkeys.length * 132)) -} else if (process.argv[2] === '--body') { - console.log(vaa.substr(12 + sigkeys.length * 132)) -} else { - console.log(vaa) -} diff --git a/staging/algorand/scripts/setvars.sh b/staging/algorand/scripts/setvars.sh deleted file mode 100644 index e678e0e36..000000000 --- a/staging/algorand/scripts/setvars.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -export OWNER_ADDR=OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU -export OWNER_MNEMO='assault approve result rare float sugar power float soul kind galaxy edit unusual pretty tone tilt net range pelican avoid unhappy amused recycle abstract master' -export GUARDIAN_KEYS='52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2389A74E8FFa224aeAD0778c786163a7A2150768CB4459EA6482D4aE574305B239B4f2264239e7599072491bd66F63356090C11Aae8114F5372aBf12B51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfFfa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CBe42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087ec8306B84235D7b0478c61783C50F990bfC44cFc0C8C1035110a13fe788259A4148F871b52bAbcb1B58A2508A20A7198E131503ce26bBE119aA8c62b28390820f04ddA22AFe03be1c3bb10f4ba6CF94A01FD6e97387C34a1F36DE0f8341E9D409E06ec45b255a41fC2792209CB998A8287204D40996df9E54bA663B12DD23fbF4FbAC618Be140727986B3BBd079040E577aC50486d0F6930e160A5C75FD1203C63580D2F00309A9A85efFAf02564Fc183C0183A963869795913D3B6dBF3B24a1C7654672c69A23c351c0Cc52D7673c52DE99785741344662F5b2308a0' -export GKEYSBASE64=`node -e "console.log(Buffer.from('$GUARDIAN_KEYS', 'hex').toString('base64'))"` - diff --git a/staging/algorand/scripts/setvphash.sh b/staging/algorand/scripts/setvphash.sh deleted file mode 100644 index 88c5d61f3..000000000 --- a/staging/algorand/scripts/setvphash.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -export STATELESS_ADDR=$(goal clerk compile vaa-verify.teal | cut -f 2 -d ':' | cut -c 2- ) -goal app call --app-id $1 --from "$OWNER_ADDR" --app-arg "str:setvphash" --app-arg "addr:$STATELESS_ADDR" -o setvphash.txn -algokey -t setvphash.txn -o setvphash.stxn sign -m "$OWNER_MNEMO" -goal clerk rawsend -f setvphash.stxn - - - - diff --git a/staging/algorand/scripts/verify-19.sh b/staging/algorand/scripts/verify-19.sh deleted file mode 100644 index 8d2450321..000000000 --- a/staging/algorand/scripts/verify-19.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash -export SIGNATURES064=`node -e "console.log(Buffer.from('003fe8e05b0d3594bbf0ab1da0110dded88930a181ace6089a2442a8e58b293b23777331d928ab36c85de11e6f2874c1cc12c418fc4e0c1e344864a8b85fda042e0001791d7134fba47002376841fe688f7c478ba223580ec25ad5046a93db477d36fb4afa241ea95bf3c02b378a24220ff0f2ea035d088a0011bff9a4743d88f5c1b4010281940f26308012efd7a307960223638abde4fb55abcaac04a9fa97bf92e5518e5903396bf7e807eb0e97e3009f7e679c0dcece45cd659ab6cf45fed9add2d6a10103470cda5780ffb89118f152c449b4137f6c4f5413c4193d8a4169b31712d6c6583a90d34a31184cc5f3c8e8c987753a69ceadb2a46fcd31cd2db8fba4f918f5270004376beb1f765fe3222cc3fc0a891f731a7c9cdb762b5997e8bd9e32e473c2cf8b63db7fbb06156ec90990e6edd39cf3402054c2ca34bbec6fc2ab1cbfe49c9a860005058e4f1150dcdba98b8054f99dfe75fa2c2c8f0c9b23a858c9e5abff85e535f317627ddf5ec51b43182b382811f8a52c7832be5c7c630eb45d9213a96989c25c01','hex').toString('base64'))"` -export SIGNATURES164=`node -e "console.log(Buffer.from('0699f7fe9387cbc7c6528f7b7183042efb8d52f5e2811dc274c3e90141ff187fa21761f04e0d9b99f7bb40ad48709532c40b012de07d5253696aae4972ed1db2130107bfcf86e950316e431874dc755acafdbaf9c28d62b3731f76abe2f7299add68d0629fc5df238856ba6ad1c9ab6a5ed3f0c43a350250005274bdadbc2c697eb63b0108d69cae6a854c5468415c51747c9d7861ca5d5b164d100486c40477602a1c2e983da703866ffb2d3c9a642681e0c97c1ba8927d38b1d583c03a89d4f277a9a33900097e82cad360d4bb4f71e74e2ce0bdc067c38a97bd000fb397c99dbed63013179000b47e534028300a99ba5f722877164341ab859f8e7c21f815a77d54fd78aba2000ab009ea66dd2d7114952b3a667bd603110f08bd20ac03a79b672049e4a2f515b713527db7db0a3c13442ba8f2dad37cb255e4c660251cb96784ce7d385576eed5010b5ef9003237297028d98779f43041bd3141b4219ffa5965cf806d23188bb0538f0639aaadcda9d62a402df3a48da7cae5cc25e1a129ba30cf08cf5ff4da49bd0c00', 'hex').toString('base64'))"` - -export SIGNATURES264=`node -e "console.log(Buffer.from('0cca7cd22e1514f0022666b35379f0685bfebbd5b80832d77eae6f57f52d351509093c433774d07ff6f3a4698331333a1dbb5478c4a51e20c15380d5dc68575f66000d525ac1524ec9d9ee623ef535a867e8f86d9b3f8e4c7b4234dbe7bb40dc8494327af2fa37c3db50064d6114f2e1441c4eee444b83636f11ce1f730f7b38490e28000e4528d8e7556ac14c74260f4ca5ed62c275324adec5a1146ac1abf6b41fcec88a24b4b797ed5370f648647904662e1fe2da2b4dea4327dfd2b94ca7080ed569f7010f5c84b1ef2ff5938ecdfd7048b2323b3e3568b2e0a62c8c513f60a4dfce8ee48e3fc7409caad8be1185be42c8a5e81d1fa4c4c98f6f53cdcddab6add2384dc5f20110cad08c66411cde321ce5b598ee4620e098e18a0427444c57923507064368912a3fab73a6b40dc050fbdaf340409583735a2528fde9b9b0322bd317f804b4767b0011c17a151c7d37376a3f7ea45030a18c4e3791dc5e376c350fe7838548506f64ee19e946fcb1b258394c6b6964608fc0a9d6a5ef682b3faded66b214637220dab300', 'hex').toString('base64'))"` - -export SIGNATURES364=`node -e "console.log(Buffer.from('12af4f9015c9f11da3cb5457be96db960d49b37e59ec2bfce2b21dd2dfd28305f560e7977994a8380b7486361758a3eeace18aa1781bfcd79ad27995b41e504cd701','hex').toString('base64'))"` - - -export GK0='52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2389A74E8FFa224aeAD0778c786163a7A2150768CB4459EA6482D4aE574305B239B4f2264239e7599072491bd66F63356090C11Aae8114F5372aBf12B51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfFfa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CB' - -export GK1='e42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087ec8306B84235D7b0478c61783C50F990bfC44cFc0C8C1035110a13fe788259A4148F871b52bAbcb1B58A2508A20A7198E131503ce26bBE119aA8c62b28390820f04ddA22AFe03be1c3bb10f4ba6CF94A0' - -export GK2='1FD6e97387C34a1F36DE0f8341E9D409E06ec45b255a41fC2792209CB998A8287204D40996df9E54bA663B12DD23fbF4FbAC618Be140727986B3BBd079040E577aC50486d0F6930e160A5C75FD1203C63580D2F00309A9A85efFAf02564Fc183C0183A963869795913D3B6dBF3B24a1C7654672c69A23c35' - -export GK3='1c0Cc52D7673c52DE99785741344662F5b2308a0' - -export GK064=`node -e "console.log(Buffer.from('$GK0', 'hex').toString('base64'))"` -export GK164=`node -e "console.log(Buffer.from('$GK1', 'hex').toString('base64'))"` -export GK264=`node -e "console.log(Buffer.from('$GK2', 'hex').toString('base64'))"` -export GK364=`node -e "console.log(Buffer.from('$GK3', 'hex').toString('base64'))"` - -export VAABODY='0000000100000001000171f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b00000000000000000012345678' -export VAABODY64=`node -e "console.log(Buffer.from('$VAABODY', 'hex').toString('base64'))"` -rm -f verify?.txn verify?.stxn verify?.dump - -if [[ $1 == '' ]] -then - echo 'No appid specified' - exit -fi -if [[ $STATELESS_ADDR == '' ]] -then - echo 'No STATELESS_ADDR' - exit -fi - -goal app call --app-id $1 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GK064" --app-arg "int:19" --noteb64 "$VAABODY64" -o verify0.txn -goal app call --app-id $1 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GK164" --app-arg "int:19" --noteb64 "$VAABODY64" -o verify1.txn -goal app call --app-id $1 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GK264" --app-arg "int:19" --noteb64 "$VAABODY64" -o verify2.txn -goal app call --app-id $1 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GK364" --app-arg "int:19" --noteb64 "$VAABODY64" -o verify3.txn -cat verify0.txn verify1.txn verify2.txn verify3.txn > verifycc.txn -goal clerk group -i verifycc.txn -o group.txn -goal clerk split -i group.txn -o verify-signed -goal clerk sign --program vaa-verify.teal --argb64 "$SIGNATURES064" --infile verify-signed-0 --outfile verify-signed-0 -goal clerk sign --program vaa-verify.teal --argb64 "$SIGNATURES164" --infile verify-signed-1 --outfile verify-signed-1 -goal clerk sign --program vaa-verify.teal --argb64 "$SIGNATURES264" --infile verify-signed-2 --outfile verify-signed-2 -goal clerk sign --program vaa-verify.teal --argb64 "$SIGNATURES364" --infile verify-signed-3 --outfile verify-signed-3 -cat verify-signed-0 verify-signed-1 verify-signed-2 verify-signed-3 > verifygroup.stxn -goal clerk dryrun -t verifygroup.stxn --dryrun-dump --outfile verifygroup.dump -goal clerk dryrun-remote -D verifygroup.dump --verbose - - diff --git a/staging/algorand/scripts/verify-dr.sh b/staging/algorand/scripts/verify-dr.sh deleted file mode 100644 index 71a5f865f..000000000 --- a/staging/algorand/scripts/verify-dr.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -export SIGNATURES64=`node -e "console.log(Buffer.from('$2','hex').toString('base64'))"` -export GUARDIAN_KEYS='52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2389A74E8FFa224aeAD0778c786163a7A2150768CB4459EA6482D4aE574305B239B4f2264239e7599072491bd66F63356090C11Aae8114F5372aBf12B51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfFfa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CBe42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087ec8306B84235D7b0478c61783C50F990bfC44cFc0C8C1035110a13fe788259A4148F871b52bAbcb1B58A2508A20A7198E131503ce26bBE119aA8c62b28390820f04ddA22AFe03be1c3bb10f4ba6CF94A01FD6e97387C34a1F36DE0f8341E9D409E06ec45b255a41fC2792209CB998A8287204D40996df9E54bA663B12DD23fbF4FbAC618Be140727986B3BBd079040E577aC50486d0F6930e160A5C75FD1203C63580D2F00309A9A85efFAf02564Fc183C0183A963869795913D3B6dBF3B24a1C7654672c69A23c351c0Cc52D7673c52DE99785741344662F5b2308a0' -export GKEYSBASE64=`node -e "console.log(Buffer.from('$GUARDIAN_KEYS', 'hex').toString('base64'))"` -export VAABODY=$3 -export VAABODY64=`node -e "console.log(Buffer.from('$VAABODY', 'hex').toString('base64'))"` -rm verify.txn verify.stxn -goal app call --app-id $1 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GKEYSBASE64" --app-arg "int:3" --noteb64 "$VAABODY64" -o verify.txn -goal clerk sign --program vaa-verify.teal --argb64 "$SIGNATURES64" --infile verify.txn --outfile verify.stxn -goal clerk dryrun -t verify.stxn --dryrun-dump --outfile verify.dump -goal clerk dryrun-remote -D verify.dump --verbose - - diff --git a/staging/algorand/scripts/verify.sh b/staging/algorand/scripts/verify.sh deleted file mode 100644 index 55ba6239a..000000000 --- a/staging/algorand/scripts/verify.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -export SIGNATURES64=`node -e "console.log(Buffer.from('25a2cec435380f6413e8b5d5531cd8789322a1d8bc488309bb868c33a26cc9492947b48895460d8d2261d669bcef210987cc5eeb9fa21504c3f5a9b5a0ff32df00ee4d1a5e589b5aa0d4787eaf57ba4b41e6a54e35e8ca60a028a0f1e35db3a8ed5d901a9831272fc117f472fcd0115d31365efd575a19a28eaf5ad9be7cf5f0d901a671b7c2af66aa6bff3337adaa7e5f196630508f85491e650cfdaccd2f67d2a605faf1c267eddaa50ac6de8d35894afce7974f14982f6173b0d020e0567f2a4a01','hex').toString('base64'))"` -export GUARDIAN_KEYS='52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2389A74E8FFa224aeAD0778c786163a7A2150768CB4459EA6482D4aE574305B239B4f2264239e7599' -export GKEYSBASE64=`node -e "console.log(Buffer.from('$GUARDIAN_KEYS', 'hex').toString('base64'))"` - - -export VAABODY='0000000100000001000171f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b00000000000000010012345678' -export VAABODY64=`node -e "console.log(Buffer.from('$VAABODY', 'hex').toString('base64'))"` - -goal app call --app-id $1 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GKEYSBASE64" --app-arg "int:3" --noteb64 "$VAABODY64" -o verify.txn - - diff --git a/staging/algorand/settings/settings-worm.js b/staging/algorand/settings/settings-worm.js deleted file mode 100644 index ed5e716b4..000000000 --- a/staging/algorand/settings/settings-worm.js +++ /dev/null @@ -1,71 +0,0 @@ -const path = require('path') - -module.exports = { - log: { - appName: 'pricecaster-v2', - disableConsoleLog: false, - fileLog: { - dir: './log', - daysTokeep: 7 - }, - // sysLog: { - // host: '127.0.0.1', - // port: 514, - // transport: 'udp', - // protocol: 'bsd', - // sendInfoNotifications: false - // }, - debugLevel: 1 - }, - algo: { - token: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - api: 'http://127.0.0.1', - port: '4001', - dumpFailedTx: true, - dumpFailedTxDirectory: './dump' - }, - apps: { - vaaVerifyProgramBinFile: 'bin/vaa-verify.bin', - vaaProcessorAppId: 622608992, - priceKeeperV2AppId: 622609307, - vaaVerifyProgramHash: 'ISTS5S7JLD5FBLM27NW7IWMQC4XPUOGGPFHOCEOL22Q557BIDOXHENLI6Y', - ownerAddress: 'OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU', - ownerKeyFile: './keys/owner.key' - }, - pyth: { - chainId: 1, - emitterAddress: '3afda841c1f43dd7d546c8a581ba1f92a139f4133f9f6ab095558f6a359df5d4' - }, - wormhole: { - spyServiceHost: 'localhost:7073' - }, - strategy: { - bufferSize: 100 - }, - symbols: [ - { - name: 'ETH/USD', - productId: 'c67940be40e0cc7ffaa1acb08ee3fab30955a197da1ec297ab133d4d43d86ee6', - priceId: 'ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace', - publishIntervalSecs: 30 - }, - { - name: 'ALGO/USD', - productId: '30fabb4e8ee48aec78799e8835c1b744d10d212c64f2671bed98d7b76a5306b0', - priceId: 'fa17ceaf30d19ba51112fdcc750cc83454776f47fb0112e4af07f15f4bb1ebc0', - publishIntervalSecs: 15 - }, - { - productId: '3515b3861e8fe93e5f540ba4077c216404782b86d5e78077b3cbfd27313ab3bc', - priceId: 'e62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43', - name: 'BTC/USD', - publishIntervalSecs: 25 - }, - { - productId: '230abfe0ec3b460bd55fc4fb36356716329915145497202b8eb8bf1af6a0a3b9', - priceId: 'fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd', - name: 'TEST', - publishIntervalSecs: 20 - } - ] -} diff --git a/staging/algorand/teal/pricekeeper/clearstate.teal b/staging/algorand/teal/pricekeeper/clearstate.teal deleted file mode 100644 index d62986563..000000000 --- a/staging/algorand/teal/pricekeeper/clearstate.teal +++ /dev/null @@ -1,3 +0,0 @@ -#pragma version 5 -int 1 -return \ No newline at end of file diff --git a/staging/algorand/teal/pricekeeper/pricekeeper.teal b/staging/algorand/teal/pricekeeper/pricekeeper.teal deleted file mode 100644 index 02cad241a..000000000 --- a/staging/algorand/teal/pricekeeper/pricekeeper.teal +++ /dev/null @@ -1,255 +0,0 @@ -#pragma version 5 -// ================================================================================================ -// PriceKeeper Approval Program -// ================================================================================================ -// -// App-globals: -// sym : byte[] Symbol to keep price for -// vaddr : byte[] Validator account -// price : uint64 current price -// stdev : uint64 current confidence (standard deviation) -// slot : uint64 slot of this onchain publication -// exp : byte[] exponent. Interpret as two-compliment, Big-Endian 64bit -// ts : uint64 last timestamp -// -// Slots: -// 0 Input message block -// 1 SHA256-Hashed message -// -// The Message format must have the packed fields: -// -// Field size -// 9 header Literal "PRICEDATA" -// 1 version int8 (Must be 1) -// 8 dest This appId -// 16 symbol String filled with spaces e.g ("ALGO/USD ") -// 8 price Price. 64bit integer. -// 8 priceexp Price exponent. Interpret as two-compliment, Big-Endian 64bit -// 8 conf Confidence (stdev). 64bit integer. -// 8 slot Valid-slot of this aggregate price. -// 8 ts timestamp of this price submitted by PriceFetcher service -// 32 s Signature s-component -// 32 r Signature r-component -// -// Size: 138 bytes. -// -// ------------------------------------------------------------------------------------------------ - - -// Application creation. -int 0 -txn ApplicationID -== -bnz handle_create - -// Handle app call: send price message -txn OnCompletion -int NoOp -== -bnz handle_call - -// Handle deletion. -txn OnCompletion -int DeleteApplication -== -bnz success - -// Fail otherwise -err - -handle_create: -// ----------------------------------------------------- -// Handle creation -// Arg 0: Validator address -// Arg 1: Symbol to keep price data -// ----------------------------------------------------- - -byte "vaddr" -txn ApplicationArgs 0 -app_global_put - -byte "sym" -txn ApplicationArgs 1 -dup -len -int 16 -== -assert -app_global_put - -byte "ts" -global LatestTimestamp -app_global_put - -b success - -// ----------------------------------------------------- -// Handle app call -// ----------------------------------------------------- - -handle_call: -// Group size must be 4 to raise computational allowance to 2800 - -global GroupSize -int 4 -== -assert - -// if this is one of dummy transactions(0, 1 or 2), exit with success -txn GroupIndex -int 3 -!= -bnz success - -// Verify if sender is the data validator -txn Sender -byte "vaddr" -app_global_get -== -assert - -// Retrieve message, store in slot 0 -txn ApplicationArgs 0 -store 0 - -// ------------------------------------------------------ -// Validate message -// ------------------------------------------------------ - -// Check length - -load 0 -len -int 138 -== -assert - -// Check header - -byte "PRICEDATA" -load 0 -extract 0 9 -== -assert - -// Check version - must be 1. - -load 0 -extract 9 1 -byte 0x01 -== -assert - -// Check destination - must be this appId. - -load 0 -extract 10 8 -btoi -txn ApplicationID -== -assert - -// Reject zero price -load 0 -extract 34 8 -btoi -int 0 -!= -assert - -// Reject zero slot -load 0 -extract 58 8 -btoi -int 0 -!= -assert - -// Check timestamp: -// * must be higher than ts recorded in global state -// * must be lower than current block stamp + 10s -// (TODO: check this again) -load 0 -extract 66 8 -btoi -dup -dup -global LatestTimestamp -int 10 -+ -< -assert -byte "ts" -app_global_get -> -assert - - -// ed25519verify args in stack: - -// data (hash of message) -load 0 -extract 0 74 -sha512_256 - -// (B) signature -load 0 -extract 74 64 - -// validator-address -byte "vaddr" -app_global_get - -// Verify signature -ed25519verify -int 1 -== -assert - -// ---------------------------------------------------------------------------- -// Verified. Store data to app globals. -// ---------------------------------------------------------------------------- - -byte "ts" -load 0 -extract 66 8 -btoi -app_global_put - -byte "price" -load 0 -extract 34 8 -btoi -app_global_put - -byte "exp" -load 0 -extract 42 8 -app_global_put - -byte "conf" -load 0 -extract 50 8 -btoi -app_global_put - -byte "slot" -load 0 -extract 58 8 -btoi -app_global_put - -b success - -// ---------------------------------------------------------------------------- - -fail: -int 0 -return - -success: -int 1 -return - - - diff --git a/staging/algorand/teal/wormhole/pyteal/pricekeeper-v2.py b/staging/algorand/teal/wormhole/pyteal/pricekeeper-v2.py deleted file mode 100644 index 4bffcec00..000000000 --- a/staging/algorand/teal/wormhole/pyteal/pricekeeper-v2.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/python3 -""" -================================================================================================ - -The Pricekeeper II Program - -(c) 2022 Wormhole Project Contributors - ------------------------------------------------------------------------------------------------- - -This program stores price data verified from Pyth VAA messaging. To accept data, this application -requires to be the last of the verification transaction group, and the verification condition -bits must be set. - -The following application calls are available. - -submit: Submit payload. -This must be 150-bytes long (Pyth native payload.) ------------------------------------------------------------------------------------------------- - -Global state: - -key name of symbol -value packed fields as follow: - - Bytes - 32 productId - 32 priceId - 8 price - 1 price_type - 4 exponent - 8 twap value - 8 twac value - 8 confidence - 8 timestamp (based on Solana contract call time) - ------------------------------ - Total: 109 bytes. - ------------------------------------------------------------------------------------------------- -""" -from pyteal.ast import * -from pyteal.types import * -from pyteal.compiler import * -from pyteal.ir import * -from globals import * -import sys - -METHOD = Txn.application_args[0] -ARG_SYMBOL_NAME = Txn.application_args[1] -ARG_PRICE_DATA = Txn.application_args[2] -SLOTID_VERIFIED_BIT = 254 -SLOT_VERIFIED_BITFIELD = ScratchVar(TealType.uint64, SLOTID_VERIFIED_BIT) -SLOT_TEMP = ScratchVar(TealType.uint64) -VAA_PROCESSOR_APPID = App.globalGet(Bytes("vaapid")) -PYTH_PAYLOAD_LENGTH_BYTES = 150 - - -@Subroutine(TealType.uint64) -def is_creator(): - return Txn.sender() == Global.creator_address() - - -@Subroutine(TealType.uint64) -# Arg0: Bootstrap with the authorized VAA Processor appid. -def bootstrap(): - return Seq([ - App.globalPut(Bytes("vaapid"), Btoi(Txn.application_args[0])), - Approve() - ]) - - -@Subroutine(TealType.uint64) -def check_group_tx(): - # - # Verifies that previous steps had set their verification bits. - # Verifies that previous steps are app calls issued from authorized appId. - # - i = SLOT_TEMP - return Seq([ - For(i.store(Int(1)), - i.load() < Global.group_size() - Int(1), - i.store(i.load() + Int(1))).Do(Seq([ - Assert(Gtxn[i.load()].type_enum() == TxnType.ApplicationCall), - Assert(Gtxn[i.load()].application_id() - == VAA_PROCESSOR_APPID), - Assert(GetBit(ImportScratchValue(i.load() - Int(1), - SLOTID_VERIFIED_BIT), i.load() - Int(1)) == Int(1)) - ]) - ), - Return(Int(1)) - ]) - - -def store(): - # * Sender must be owner - # * This must be part of a transaction group - # * All calls in group must be issued from authorized appid. - # * All calls in group must have verification bits set. - # * Argument 0 must be price symbol name. - # * Argument 1 must be Pyth payload (150 bytes long) - - pyth_price_data = ScratchVar(TealType.bytes) - packed_price_data = ScratchVar(TealType.bytes) - return Seq([ - pyth_price_data.store(ARG_PRICE_DATA), - Assert(Global.group_size() > Int(1)), - Assert(Len(pyth_price_data.load()) == Int(PYTH_PAYLOAD_LENGTH_BYTES)), - Assert(Txn.application_args.length() == Int(3)), - Assert(is_creator()), - Assert(check_group_tx()), - - # Unpack Pyth payload and store the data we want (see doc at beginning) - - packed_price_data.store(Concat( - # store product_id, price_id, price_type, price, exponent, twap - Extract(pyth_price_data.load(), Int(14), Int(85)), - Extract(pyth_price_data.load(), Int(108), Int(8)), # store twac - Extract(pyth_price_data.load(), Int(132), Int(8)), # confidence - Extract(pyth_price_data.load(), Int(142), Int(8)), # timestamp - )), - App.globalPut(ARG_SYMBOL_NAME, packed_price_data.load()), - Approve()]) - - -def pricekeeper_program(): - handle_create = Return(bootstrap()) - handle_update = Return(is_creator()) - handle_delete = Return(is_creator()) - handle_noop = Cond( - [METHOD == Bytes("store"), store()], - ) - return Cond( - [Txn.application_id() == Int(0), handle_create], - [Txn.on_completion() == OnComplete.UpdateApplication, handle_update], - [Txn.on_completion() == OnComplete.DeleteApplication, handle_delete], - [Txn.on_completion() == OnComplete.NoOp, handle_noop] - ) - - -def clear_state_program(): - return Int(1) - - -if __name__ == "__main__": - - approval_outfile = "teal/wormhole/build/pricekeeper-v2-approval.teal" - clear_state_outfile = "teal/wormhole/build/pricekeeper-v2-clear.teal" - - if len(sys.argv) >= 2: - approval_outfile = sys.argv[1] - - if len(sys.argv) >= 3: - clear_state_outfile = sys.argv[2] - - print("Pricekeeper V2 Program, (c) 2022 Wormhole Project Contributors") - print("Compiling approval program...") - - with open(approval_outfile, "w") as f: - compiled = compileTeal(pricekeeper_program(), - mode=Mode.Application, version=5) - f.write(compiled) - - print("Written to " + approval_outfile) - print("Compiling clear state program...") - - with open(clear_state_outfile, "w") as f: - compiled = compileTeal(clear_state_program(), - mode=Mode.Application, version=5) - f.write(compiled) - - print("Written to " + clear_state_outfile) diff --git a/staging/algorand/teal/wormhole/pyteal/vaa-processor.py b/staging/algorand/teal/wormhole/pyteal/vaa-processor.py deleted file mode 100644 index 7059a35a0..000000000 --- a/staging/algorand/teal/wormhole/pyteal/vaa-processor.py +++ /dev/null @@ -1,328 +0,0 @@ -#!/usr/bin/python3 -""" -================================================================================================ - -The VAA Processor Program - -(c) 2022 Wormhole Project Contributors - -Changelog. - -v1.0 - Initial design -v1.1 211214 - Group must end with either a dummy or app-call such as Store price onchain. - ------------------------------------------------------------------------------------------------- - -This program is the core client to signed VAAs from Wormhole, working in tandem with the -verify-vaa.teal stateless programs. - -The following application calls are available. - -setvphash: Set verify program hash. -setauthid: Set the authorized app-id of the last transaction call in the group, used as consumer - of the verified VAA. - -verify: Verify guardian signature subset i..j, works in tandem with stateless program. - Arguments: #0 guardian public keys subset i..j (must match stored in global state) - #1 guardian signatures subset i..j - TX Note: payload to verify - Last verification step triggers the VAA commiting stage, - where we decide what to do based on the payload. A last work transaction must be issued, - with a call to an authorized app-id (authid). This serves for example to call a Pricekeeper - contract to store price data on-chain. - If nothing is to be done, any dummy app-call must be called for the group to be approved. - ------------------------------------------------------------------------------------------------- - -Global state: - -"vphash" : Hash of verification program logic -"gsexp" : Guardian set expiration time -"gscount" : Guardian set size -"vssize" : Verification step size. -"authid" : The authorized app-id of the last transaction call in the group, used as consumer - of the verified VAA. -key N : address of guardian N - ------------------------------------------------------------------------------------------------- -Stores in scratch: - -SLOT 255: number of guardians in set -================================================================================================ - -""" -from pyteal.ast import * -from pyteal.types import * -from pyteal.compiler import * -from pyteal.ir import * -from globals import * -import sys - -GUARDIAN_ADDRESS_SIZE = 20 -METHOD = Txn.application_args[0] -VERIFY_ARG_GUARDIAN_KEY_SUBSET = Txn.application_args[1] -VERIFY_ARG_GUARDIAN_SET_SIZE = Txn.application_args[2] -VERIFY_ARG_PAYLOAD = Txn.note() -SLOTID_TEMP_0 = 251 -SLOTID_VERIFIED_BIT = 254 -STATELESS_LOGIC_HASH = App.globalGet(Bytes("vphash")) -NUM_GUARDIANS = App.globalGet(Bytes("gscount")) -AUTHORIZED_APP_ID = App.globalGet(Bytes("authid")) -SLOT_VERIFIED_BITFIELD = ScratchVar(TealType.uint64, SLOTID_VERIFIED_BIT) -SLOT_TEMP = ScratchVar(TealType.uint64, SLOTID_TEMP_0) - -# defined chainId/contracts - -GOVERNANCE_CHAIN_ID = 1 -GOVERNANCE_EMITTER_ID = '00000000000000000000000000000000000000000000' -PYTH2WORMHOLE_CHAIN_ID = 1 -# PYTH2WORMHOLE_EMITTER_ID = '0x71f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b' - -# Testnet emitter. -PYTH2WORMHOLE_EMITTER_ID = '0x3afda841c1f43dd7d546c8a581ba1f92a139f4133f9f6ab095558f6a359df5d4' - -# VAA fields - -VAA_RECORD_EMITTER_CHAIN_POS = 8 -VAA_RECORD_EMITTER_CHAIN_LEN = 2 -VAA_RECORD_EMITTER_ADDR_POS = 10 -VAA_RECORD_EMITTER_ADDR_LEN = 32 - -# ------------------------------------------------------------------------------------------------- - - -@Subroutine(TealType.uint64) -# Arg0: Bootstrap with the initial list of guardians packed. -# Arg1: Expiration time in second argument. -# Arg2: Guardian set Index. -# -# Guardian public keys are 20-bytes wide, so -# using arguments a maximum 1000/20 ~ 200 public keys can be specified in this version. -def bootstrap(): - guardian_count = ScratchVar(TealType.uint64) - i = SLOT_TEMP - return Seq([ - Assert(Txn.application_args.length() == Int(3)), - Assert(Len(Txn.application_args[0]) % - Int(GUARDIAN_ADDRESS_SIZE) == Int(0)), - guardian_count.store( - Len(Txn.application_args[0]) / Int(GUARDIAN_ADDRESS_SIZE)), - Assert(guardian_count.load() > Int(0)), - For(i.store(Int(0)), i.load() < guardian_count.load(), i.store(i.load() + Int(1))).Do( - App.globalPut(Itob(i.load()), Extract( - Txn.application_args[0], i.load() * Int(GUARDIAN_ADDRESS_SIZE), Int(GUARDIAN_ADDRESS_SIZE))) - ), - App.globalPut(Bytes("gscount"), guardian_count.load()), - App.globalPut(Bytes("gsexp"), Btoi(Txn.application_args[1])), - App.globalPut(Bytes("gsindex"), Btoi(Txn.application_args[2])), - App.globalPut(Bytes("vssize"), Int(MAX_SIGNATURES_PER_VERIFICATION_STEP)), - Approve() - ]) - - -@Subroutine(TealType.uint64) -def is_creator(): - return Txn.sender() == Global.creator_address() - - -@Subroutine(TealType.uint64) -def check_guardian_key_subset(): - # Verify that the passed argument for guardian keys [i..j] match the - # global state for the same keys. - # - i = SLOT_TEMP - sig_count = ScratchVar(TealType.uint64) - idx_base = ScratchVar(TealType.uint64) - return Seq([ - idx_base.store(Int(MAX_SIGNATURES_PER_VERIFICATION_STEP) * Txn.group_index()), - sig_count.store(get_sig_count_in_step(Txn.group_index(), NUM_GUARDIANS)), - For(i.store(Int(0)), - i.load() < sig_count.load(), - i.store(i.load() + Int(1))).Do( - If( - App.globalGet(Itob(i.load() + idx_base.load())) != Extract(VERIFY_ARG_GUARDIAN_KEY_SUBSET, - i.load() * Int(GUARDIAN_ADDRESS_SIZE), - Int(GUARDIAN_ADDRESS_SIZE))).Then(Return(Int(0))) # get and compare stored global key - ), - Return(Int(1)) - ]) - - -@Subroutine(TealType.uint64) -def check_guardian_set_size(): - # - # Verify that the passed argument for guardian set size matches the global state. - # - return NUM_GUARDIANS == Btoi(VERIFY_ARG_GUARDIAN_SET_SIZE) - - -@Subroutine(TealType.uint64) -def handle_governance(): - return Int(1) - - -@Subroutine(TealType.uint64) -def handle_pyth_price_ticker(): - return Int(1) - - -@Subroutine(TealType.uint64) -# -# Unpack the verified VAA payload and process it according to -# the source based by emitterChainId, emitterAddress. -# -# NOTE: This will work when contract-to-contract call is available in the AVM. -# Now, the transaction group must end with a call to process the VAA or -# do-nothing, if you want only to do verification chores without processing anything. -# -def commit_vaa(): - chainId = Btoi(Extract(VERIFY_ARG_PAYLOAD, Int( - VAA_RECORD_EMITTER_CHAIN_POS), Int(VAA_RECORD_EMITTER_CHAIN_LEN))) - emitterId = Extract(VERIFY_ARG_PAYLOAD, Int( - VAA_RECORD_EMITTER_ADDR_POS), Int(VAA_RECORD_EMITTER_ADDR_LEN)) - return Seq([ - If(And( - chainId == Int(GOVERNANCE_CHAIN_ID), - emitterId == Bytes(GOVERNANCE_EMITTER_ID))).Then( - Return(handle_governance())) - .ElseIf(And( - chainId == Int(PYTH2WORMHOLE_CHAIN_ID), - emitterId == Bytes('base16', PYTH2WORMHOLE_EMITTER_ID) - )).Then( - Return(handle_pyth_price_ticker()) - ).Else( - Reject() - ) - ]) - - -@Subroutine(TealType.uint64) -def check_final_verification_state(): - # - # Verifies that previous steps had set their verification bits. - # - i = SLOT_TEMP - return Seq([ - For(i.store(Int(1)), - i.load() < Global.group_size() - Int(1), - i.store(i.load() + Int(1))).Do(Seq([ - Assert(Gtxn[i.load()].type_enum() == TxnType.ApplicationCall), - Assert(Gtxn[i.load()].application_id() == Txn.application_id()), - Assert(GetBit(ImportScratchValue(i.load() - Int(1), SLOTID_VERIFIED_BIT), i.load() - Int(1)) == Int(1)) - ]) - ), - Return(Int(1)) - ]) - - -def setvphash(): - # - # Sets the hash of the verification stateless program. - # - - return Seq([ - Assert(is_creator()), - Assert(Global.group_size() == Int(1)), - Assert(Txn.application_args.length() == Int(2)), - Assert(Len(Txn.application_args[1]) == Int(32)), - App.globalPut(Bytes("vphash"), Txn.application_args[1]), - Approve() - ]) - -def setauthid(): - # - # Sets the app-id of an authorized program to be executed as a - # last call in the group to optionally consume the verified VAA. - # - - return Seq([ - Assert(is_creator()), - Assert(Global.group_size() == Int(1)), - Assert(Txn.application_args.length() == Int(2)), - App.globalPut(Bytes("authid"), Btoi(Txn.application_args[1])), - Approve() - ]) - -def verify(): - # * Sender must be stateless logic. - # * Let N be the number of signatures per verification step, for the TX(i) in group, we verify signatures [j..k] where j = i*N, k = j+(N-1) - # * Argument 0 must contain guardian public keys for guardians [i..j] (read by stateless logic). - # Public keys are 32 bytes long so expected argument length is 32 * (j - i + 1) - # * Argument 1 must contain current guardian set size (read by stateless logic) - # * Passed guardian public keys [i..j] must match the current global state. - # * Note must contain VAA message-in-digest (header+payload) (up to 1KB) (read by stateless logic) - # - # Last verify TX in group will trigger VAA handling depending on payload. It is required that - # all previous transactions are app-calls for this AppId and all bitfields are set. - # Last TX in group must be call to authorized applications. - - return Seq([ - SLOT_VERIFIED_BITFIELD.store(Int(0)), - Assert(Global.group_size() == get_group_size(NUM_GUARDIANS) + Int(1)), - Assert(Gtxn[Global.group_size() - Int(1)].type_enum() == TxnType.ApplicationCall), - Assert(Gtxn[Global.group_size() - Int(1)].application_id() == AUTHORIZED_APP_ID), - Assert(Txn.application_args.length() == Int(3)), - Assert(Txn.sender() == STATELESS_LOGIC_HASH), - Assert(check_guardian_set_size()), - Assert(check_guardian_key_subset()), - SLOT_VERIFIED_BITFIELD.store( - SetBit(SLOT_VERIFIED_BITFIELD.load(), Txn.group_index(), Int(1))), - If(Txn.group_index() == Global.group_size() - - Int(2)).Then( - Return(Seq([ - Assert(check_final_verification_state()), - commit_vaa() - ]))), - Approve()]) - - -def vaa_processor_program(): - handle_create = Return(bootstrap()) - handle_update = Return(is_creator()) - handle_delete = Return(is_creator()) - handle_noop = Cond( - [METHOD == Bytes("setvphash"), setvphash()], - [METHOD == Bytes("setauthid"), setauthid()], - [METHOD == Bytes("verify"), verify()], - [METHOD == Bytes("nop"), Return(Int(1))], - ) - return Cond( - [Txn.application_id() == Int(0), handle_create], - [Txn.on_completion() == OnComplete.UpdateApplication, handle_update], - [Txn.on_completion() == OnComplete.DeleteApplication, handle_delete], - [Txn.on_completion() == OnComplete.NoOp, handle_noop] - ) - - -def clear_state_program(): - return Int(1) - - -if __name__ == "__main__": - - approval_outfile = "teal/wormhole/build/vaa-processor-approval.teal" - clear_state_outfile = "teal/wormhole/build/vaa-processor-clear.teal" - - if len(sys.argv) >= 2: - approval_outfile = sys.argv[1] - - if len(sys.argv) >= 3: - clear_state_outfile = sys.argv[2] - - print("VAA Processor Program, (c) 2022 Wormhole Project Contributors ") - print("Compiling approval program...") - - with open(approval_outfile, "w") as f: - compiled = compileTeal(vaa_processor_program(), - mode=Mode.Application, version=5) - f.write(compiled) - - print("Written to " + approval_outfile) - print("Compiling clear state program...") - - with open(clear_state_outfile, "w") as f: - compiled = compileTeal(clear_state_program(), - mode=Mode.Application, version=5) - f.write(compiled) - - print("Written to " + clear_state_outfile) diff --git a/staging/algorand/teal/wormhole/pyteal/vaa-verify.py b/staging/algorand/teal/wormhole/pyteal/vaa-verify.py deleted file mode 100644 index cc5f35cc1..000000000 --- a/staging/algorand/teal/wormhole/pyteal/vaa-verify.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/python3 -""" -================================================================================================ - -The VAA Signature Verify Stateless Program - -Copyright 2022 Wormhole Project Contributors - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - ------------------------------------------------------------------------------------------------- - -This program verifies a subset of the signatures in a VAA against the guardian set. This -program works in tandem with the VAA Processor stateful program. - -================================================================================================ - -""" -from pyteal.ast import * -from pyteal.types import * -from pyteal.compiler import * -from pyteal.ir import * -from globals import * -from inlineasm import * - -import sys - -SLOTID_RECOVERED_PK_X = 240 -SLOTID_RECOVERED_PK_Y = 241 - - -@Subroutine(TealType.uint64) -def sig_check(signatures, digest, keys, vaa_signature_count): - si = ScratchVar(TealType.uint64) # signature index (zero-based) - ki = ScratchVar(TealType.uint64) # key index - gi = ScratchVar(TealType.uint64) # guardian index (signature prefix) - i = ScratchVar(TealType.uint64) - rec_pk_x = ScratchVar(TealType.bytes, SLOTID_RECOVERED_PK_X) - rec_pk_y = ScratchVar(TealType.bytes, SLOTID_RECOVERED_PK_Y) - - return Seq( - [ - rec_pk_x.store(Bytes("")), - rec_pk_y.store(Bytes("")), - gi.store(Int(0)), - For(Seq([ - i.store(Int(0)), - si.store(Int(0)), - ki.store(Int(0)) - ]), - si.load() < Len(signatures), - Seq([ - si.store(si.load() + Int(66)), - ki.store(ki.load() + Int(20)), - i.store(i.load() + Int(1)), - ])).Do( - Seq([ - gi.store(Btoi(Extract(signatures, si.load(), Int(1)))), - - # Bail out case if we must ignore all signatures past sig_count > 2/3+1 - If (gi.load() >= vaa_signature_count).Then(Break()), - - # Index must be sequential - - Assert(gi.load() == - i.load() + (Txn.group_index() * Int(MAX_SIGNATURES_PER_VERIFICATION_STEP))), - - InlineAssembly( - "ecdsa_pk_recover Secp256k1", - Keccak256(Keccak256(digest)), - Btoi(Extract(signatures, si.load() + Int(65), Int(1))), - Extract(signatures, si.load() + Int(1), Int(32)), # R - Extract(signatures, si.load() + Int(33), Int(32)), # S - type=TealType.none), - - # returned values in stack, pass to scratch-vars - - InlineAssembly("store " + str(SLOTID_RECOVERED_PK_Y)), - InlineAssembly("store " + str(SLOTID_RECOVERED_PK_X)), - - # Generate Ethereum-type public key, compare with guardian key. - - Assert( - Extract(keys, ki.load(), Int(20)) == - Substring(Keccak256(Concat(rec_pk_x.load(), - rec_pk_y.load())), Int(12), Int(32)) - ) - ]) - - - ), - Return(Int(1)) - ] - ) - - -""" -* Let N be the number of signatures per verification step, for the TX(i) in group, we verify signatures [j..k] where j = i*N, k = j+(N-1) -* Input 0 is signatures [j..k] to verify as LogicSigArgs. (Format is GuardianIndex + signature) -* Input 1 is the total signature count specified in the VAA. This must be > 2/3 of the guardian set plus 1. -* Input 2 is signed digest of payload, contained in the note field of the TX in current slot. -* Input 3 is public keys for guardians [j..k] contained in the first Argument of the TX in current slot. -* Input 4 is guardian set size contained in the second argument of the TX in current slot. -""" - - -def vaa_verify_program(vaa_processor_app_id): - signatures = Arg(0) - vaa_signature_count = Arg(1) - digest = Txn.note() - keys = Txn.application_args[1] - num_guardians = Txn.application_args[2] - - return Seq([ - Assert(Txn.fee() <= Int(1000)), - Assert(Txn.application_args.length() == Int(3)), - Assert(Btoi(vaa_signature_count) > ((Btoi(num_guardians) * Int(10) / Int(3)) * Int(2)) / Int(10) + Int(1)), - Assert(Len(signatures) == get_sig_count_in_step(Txn.group_index(), Btoi(num_guardians)) * Int(66)), - Assert(Txn.rekey_to() == Global.zero_address()), - Assert(Txn.application_id() == Int(vaa_processor_app_id)), - Assert(Txn.type_enum() == TxnType.ApplicationCall), - Assert(Global.group_size() == Int(1) + get_group_size(Btoi(num_guardians))), - Assert(sig_check(signatures, digest, keys, Btoi(vaa_signature_count))), - Approve()] - ) - -if __name__ == "__main__": - outfile = "teal/wormhole/build/vaa-verify.teal" - appid = 0 - - print("VAA Verify Stateless Program, (c) 2022 Wormhole Project Contributors") - print("Compiling...") - - if len(sys.argv) >= 1: - appid = sys.argv[1] - - if len(sys.argv) >= 2: - outfile = sys.argv[2] - - with open(outfile, "w") as f: - compiled = compileTeal(vaa_verify_program( - int(appid)), mode=Mode.Signature, version=5) - f.write(compiled) - - print("Written to " + outfile) diff --git a/staging/algorand/test/Handtest-guide.md b/staging/algorand/test/Handtest-guide.md deleted file mode 100644 index 4f7dcb99c..000000000 --- a/staging/algorand/test/Handtest-guide.md +++ /dev/null @@ -1,237 +0,0 @@ -Hand-testing guide ------------------- - - -The nineteen sample guardian keys: - -``` -Key PK ------------------------------------------- ---------------------------------------------------------------- -0x52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2 563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757 -0x389A74E8FFa224aeAD0778c786163a7A2150768C 8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f -0xB4459EA6482D4aE574305B239B4f2264239e7599 9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b -0x072491bd66F63356090C11Aae8114F5372aBf12B 5a02c4cd110d20a83a7ce8d1a2b2ae5df252b4e5f6781c7855db5cc28ed2d1b4 -0x51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfF 93d4e3b443bf11f99a00901222c032bd5f63cf73fc1bcfa40829824d121be9b2 -0xfa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CB ea40e40c63c6ff155230da64a2c44fcd1f1c9e50cacb752c230f77771ce1d856 -0xe42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A 87eaabe9c27a82198e618bca20f48f9679c0f239948dbd094005e262da33fe6a -0x4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087e 61ffed2bff38648a6d36d6ed560b741b1ca53d45391441124f27e1e48ca04770 -0xc8306B84235D7b0478c61783C50F990bfC44cFc0 bd12a242c6da318fef8f98002efb98efbf434218a78730a197d981bebaee826e -0xC8C1035110a13fe788259A4148F871b52bAbcb1B 20d3597bb16525b6d09e5fb56feb91b053d961ab156f4807e37d980f50e71aff -0x58A2508A20A7198E131503ce26bBE119aA8c62b2 344b313ffbc0199ff6ca08cacdaf5dc1d85221e2f2dc156a84245bd49b981673 -0x8390820f04ddA22AFe03be1c3bb10f4ba6CF94A0 848b93264edd3f1a521274ca4da4632989eb5303fd15b14e5ec6bcaa91172b05 -0x1FD6e97387C34a1F36DE0f8341E9D409E06ec45b c6f2046c1e6c172497fc23bd362104e2f4460d0f61984938fa16ef43f27d93f6 -0x255a41fC2792209CB998A8287204D40996df9E54 693b256b1ee6b6fb353ba23274280e7166ab3be8c23c203cc76d716ba4bc32bf -0xbA663B12DD23fbF4FbAC618Be140727986B3BBd0 13c41508c0da03018d61427910b9922345ced25e2bbce50652e939ee6e5ea56d -0x79040E577aC50486d0F6930e160A5C75FD1203C6 460ee0ee403be7a4f1eb1c63dd1edaa815fbaa6cf0cf2344dcba4a8acf9aca74 -0x3580D2F00309A9A85efFAf02564Fc183C0183A96 b25148579b99b18c8994b0b86e4dd586975a78fa6e7ad6ec89478d7fbafd2683 -0x3869795913D3B6dBF3B24a1C7654672c69A23c35 90d7ac6a82166c908b8cf1b352f3c9340a8d1f2907d7146fb7cd6354a5436cca -0x1c0Cc52D7673c52DE99785741344662F5b2308a0 b71d23908e4cf5d6cd973394f3a4b6b164eb1065785feee612efdfd8d30005ed ------------------------------------------- ---------------------------------------------------------------- -``` - - -keys for tx0: -52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2389A74E8FFa224aeAD0778c786163a7A2150768CB4459EA6482D4aE574305B239B4f2264239e7599072491bd66F63356090C11Aae8114F5372aBf12B51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfFfa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CB - -keys for tx1: -e42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087ec8306B84235D7b0478c61783C50F990bfC44cFc0C8C1035110a13fe788259A4148F871b52bAbcb1B58A2508A20A7198E131503ce26bBE119aA8c62b28390820f04ddA22AFe03be1c3bb10f4ba6CF94A0 - -keys for tx2: -1FD6e97387C34a1F36DE0f8341E9D409E06ec45b255a41fC2792209CB998A8287204D40996df9E54bA663B12DD23fbF4FbAC618Be140727986B3BBd079040E577aC50486d0F6930e160A5C75FD1203C63580D2F00309A9A85efFAf02564Fc183C0183A963869795913D3B6dBF3B24a1C7654672c69A23c35 - -keys for tx3: -1c0Cc52D7673c52DE99785741344662F5b2308a0 - - -563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757 -8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f -9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b -5a02c4cd110d20a83a7ce8d1a2b2ae5df252b4e5f6781c7855db5cc28ed2d1b4 -93d4e3b443bf11f99a00901222c032bd5f63cf73fc1bcfa40829824d121be9b2 -ea40e40c63c6ff155230da64a2c44fcd1f1c9e50cacb752c230f77771ce1d856 -87eaabe9c27a82198e618bca20f48f9679c0f239948dbd094005e262da33fe6a -61ffed2bff38648a6d36d6ed560b741b1ca53d45391441124f27e1e48ca04770 -bd12a242c6da318fef8f98002efb98efbf434218a78730a197d981bebaee826e -20d3597bb16525b6d09e5fb56feb91b053d961ab156f4807e37d980f50e71aff -344b313ffbc0199ff6ca08cacdaf5dc1d85221e2f2dc156a84245bd49b981673 -848b93264edd3f1a521274ca4da4632989eb5303fd15b14e5ec6bcaa91172b05 -c6f2046c1e6c172497fc23bd362104e2f4460d0f61984938fa16ef43f27d93f6 -693b256b1ee6b6fb353ba23274280e7166ab3be8c23c203cc76d716ba4bc32bf -13c41508c0da03018d61427910b9922345ced25e2bbce50652e939ee6e5ea56d -460ee0ee403be7a4f1eb1c63dd1edaa815fbaa6cf0cf2344dcba4a8acf9aca74 -b25148579b99b18c8994b0b86e4dd586975a78fa6e7ad6ec89478d7fbafd2683 -90d7ac6a82166c908b8cf1b352f3c9340a8d1f2907d7146fb7cd6354a5436cca -b71d23908e4cf5d6cd973394f3a4b6b164eb1065785feee612efdfd8d30005ed - - -003fe8e05b0d3594bbf0ab1da0110dded88930a181ace6089a2442a8e58b293b23777331d928ab36c85de11e6f2874c1cc12c418fc4e0c1e344864a8b85fda042e00 -01791d7134fba47002376841fe688f7c478ba223580ec25ad5046a93db477d36fb4afa241ea95bf3c02b378a24220ff0f2ea035d088a0011bff9a4743d88f5c1b401 -0281940f26308012efd7a307960223638abde4fb55abcaac04a9fa97bf92e5518e5903396bf7e807eb0e97e3009f7e679c0dcece45cd659ab6cf45fed9add2d6a101 -03470cda5780ffb89118f152c449b4137f6c4f5413c4193d8a4169b31712d6c6583a90d34a31184cc5f3c8e8c987753a69ceadb2a46fcd31cd2db8fba4f918f52700 -04376beb1f765fe3222cc3fc0a891f731a7c9cdb762b5997e8bd9e32e473c2cf8b63db7fbb06156ec90990e6edd39cf3402054c2ca34bbec6fc2ab1cbfe49c9a8600 -05058e4f1150dcdba98b8054f99dfe75fa2c2c8f0c9b23a858c9e5abff85e535f317627ddf5ec51b43182b382811f8a52c7832be5c7c630eb45d9213a96989c25c01 - -0699f7fe9387cbc7c6528f7b7183042efb8d52f5e2811dc274c3e90141ff187fa21761f04e0d9b99f7bb40ad48709532c40b012de07d5253696aae4972ed1db21301 -07bfcf86e950316e431874dc755acafdbaf9c28d62b3731f76abe2f7299add68d0629fc5df238856ba6ad1c9ab6a5ed3f0c43a350250005274bdadbc2c697eb63b01 -08d69cae6a854c5468415c51747c9d7861ca5d5b164d100486c40477602a1c2e983da703866ffb2d3c9a642681e0c97c1ba8927d38b1d583c03a89d4f277a9a33900 -097e82cad360d4bb4f71e74e2ce0bdc067c38a97bd000fb397c99dbed63013179000b47e534028300a99ba5f722877164341ab859f8e7c21f815a77d54fd78aba200 -0ab009ea66dd2d7114952b3a667bd603110f08bd20ac03a79b672049e4a2f515b713527db7db0a3c13442ba8f2dad37cb255e4c660251cb96784ce7d385576eed501 -0b5ef9003237297028d98779f43041bd3141b4219ffa5965cf806d23188bb0538f0639aaadcda9d62a402df3a48da7cae5cc25e1a129ba30cf08cf5ff4da49bd0c00 - -0cca7cd22e1514f0022666b35379f0685bfebbd5b80832d77eae6f57f52d351509093c433774d07ff6f3a4698331333a1dbb5478c4a51e20c15380d5dc68575f6600 -0d525ac1524ec9d9ee623ef535a867e8f86d9b3f8e4c7b4234dbe7bb40dc8494327af2fa37c3db50064d6114f2e1441c4eee444b83636f11ce1f730f7b38490e2800 -0e4528d8e7556ac14c74260f4ca5ed62c275324adec5a1146ac1abf6b41fcec88a24b4b797ed5370f648647904662e1fe2da2b4dea4327dfd2b94ca7080ed569f701 -0f5c84b1ef2ff5938ecdfd7048b2323b3e3568b2e0a62c8c513f60a4dfce8ee48e3fc7409caad8be1185be42c8a5e81d1fa4c4c98f6f53cdcddab6add2384dc5f201 -10cad08c66411cde321ce5b598ee4620e098e18a0427444c57923507064368912a3fab73a6b40dc050fbdaf340409583735a2528fde9b9b0322bd317f804b4767b00 -11c17a151c7d37376a3f7ea45030a18c4e3791dc5e376c350fe7838548506f64ee19e946fcb1b258394c6b6964608fc0a9d6a5ef682b3faded66b214637220dab300 - -12af4f9015c9f11da3cb5457be96db960d49b37e59ec2bfce2b21dd2dfd28305f560e7977994a8380b7486361758a3eeace18aa1781bfcd79ad27995b41e504cd701 - - -* Compile PyTEAL sources, - -``` -C:\src\PriceCasterService>python teal\wormhole\pyteal\vaa-processor.py vaap.teal vaap-clear.teal -VAA Processor Program -Compiling approval program... -Written to vaap.teal -Compiling clear state program... -Written to vaap-clear.teal - -``` - -* Copy compiled teal files to Sandbox (optional): - -``` -./sandbox copyTo /mnt/c/src/PriceCasterService/vaap.teal - -Now copying /mnt/c/src/PriceCasterService/vaap.teal to Algod container in /opt/data//mnt/c/src/PriceCasterService/vaap.teal -./sandbox copyTo /mnt/c/src/PriceCasterService/vaap-clear.teal - -Now copying /mnt/c/src/PriceCasterService/vaap-clear.teal to Algod container in /opt/data//mnt/c/src/PriceCasterService/vaap-clear.teal -``` - -* Execute `setvars` from scripts directory - -``` -source scripts/setvars.sh -``` - -* Make sure to clear previously created VAA Processor Apps, example: - -``` -goal account info -a OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU -Created Assets: - -Held Assets: - ID 14704676, Wrapped Algo Testnet, balance 0.000000 wALGO Ts -Created Apps: - ID 45231352, global state used 2/2 uints, 20/20 byte slices -Opted In Apps: - ID 14713804, local state used 1/3 uints, 1/2 byte slices - - -scripts/deleteapp.sh 45231352 - -``` - -* Create the application and Check the deployed application ID according to the final TX ID. - -``` -scripts/createapp.sh -``` - - -* Compile the stateless logic with the VAA Processor ID, for example: - - -``` -python teal\wormhole\pyteal\vaa-verify.py vaaverify.teal - -goal clerk compile vaaverify.teal -vaaverify.teal: 4H2VD6GY4L7HEOVTZBKGTO6EYFASYFOWN34ONR5HIFEE2JIJ2M5GK26SXI -``` - -* Set the stateless program hash with the "setvphash" appcall: - -``` -source scripts/setvphash -``` - -* To verify a sample VAA, you can use the testing library using Nodejs as follows: - -``` -Welcome to Node.js v14.17.6. -Type ".help" for more information. -> TestLib = require('./test/testlib') -{ TestLib: [class TestLib] } -> t = new TestLib.TestLib -TestLib {} -> sigkeys = ['563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757', '8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f', '9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b'] -[ - '563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757', - '8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f', - '9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b' -] -> t.createSignedVAA(0, sigkeys, 1, 1, 1, '0x71f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b', 0, 0, '0x12345678') -'0100000000030025a2cec435380f6413e8b5d5531cd8789322a1d8bc488309bb868c33a26cc9492947b48895460d8d2261d669bcef210987cc5eeb9fa21504c3f5a9b5a0ff32df0001ee4d1a5e589b5aa0d4787eaf57ba4b41e6a54e35e8ca60a028a0f1e35db3a8ed5d901a9831272fc117f472fcd0115d31365efd575a19a28eaf5ad9be7cf5f0d90102a671b7c2af66aa6bff3337adaa7e5f196630508f85491e650cfdaccd2f67d2a605faf1c267eddaa50ac6de8d35894afce7974f14982f6173b0d020e0567f2a4a0100000001000000010001000000000000000000000000000000000000000000000000000000000000ffff00000000000000000012345678' -``` - - -The resulting decomposed in fields VAA is: - -``` - -01 Version -00000000 Guardian-set-index -03 Signature count - -sig indexes + signatures: -00 -25a2cec435380f6413e8b5d5531cd8789322a1d8bc488309bb868c33a26cc9492947b48895460d8d2261d669bcef210987cc5eeb9fa21504c3f5a9b5a0ff32df00 -01 -ee4d1a5e589b5aa0d4787eaf57ba4b41e6a54e35e8ca60a028a0f1e35db3a8ed5d901a9831272fc117f472fcd0115d31365efd575a19a28eaf5ad9be7cf5f0d901 -02 -a671b7c2af66aa6bff3337adaa7e5f196630508f85491e650cfdaccd2f67d2a605faf1c267eddaa50ac6de8d35894afce7974f14982f6173b0d020e0567f2a4a01 - -00000001 timestamp -00000001 nonce -0001 chain-id -71f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b emitterAddress -0000000000000000 sequence -00 consistency-level - -payload: -12345678 - -``` - -VAA Body: -0000000100000001000171f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b00000000000000010012345678 - -Since there are three signers, VAA can be verified in a group transaction with just one step. - -Stateless logic accepts signature subset as argument (encoded in base64). - - - -``` -export SIGNATURES64=`node -e "console.log(Buffer.from('25a2cec435380f6413e8b5d5531cd8789322a1d8bc488309bb868c33a26cc9492947b48895460d8d2261d669bcef210987cc5eeb9fa21504c3f5a9b5a0ff32df00ee4d1a5e589b5aa0d4787eaf57ba4b41e6a54e35e8ca60a028a0f1e35db3a8ed5d901a9831272fc117f472fcd0115d31365efd575a19a28eaf5ad9be7cf5f0d901a671b7c2af66aa6bff3337adaa7e5f196630508f85491e650cfdaccd2f67d2a605faf1c267eddaa50ac6de8d35894afce7974f14982f6173b0d020e0567f2a4a01','hex').toString('base64'))"` -export VAABODY=`0000000100000001000171f8dcb863d176e2c420ad6610cf687359612b6fb392e0642b0ca6b1f186aa3b00000000000000010012345678` -export VAABODY64=`node -e "console.log(Buffer.from('$VAABODY64', 'hex').toString('base64'))"` -export STATELESS_ADDR=4H2VD6GY4L7HEOVTZBKGTO6EYFASYFOWN34ONR5HIFEE2JIJ2M5GK26SXI -export GUARDIAN_KEYS='52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2389A74E8FFa224aeAD0778c786163a7A2150768CB4459EA6482D4aE574305B239B4f2264239e7599' -export GKEYSBASE64=`node -e "console.log(Buffer.from('$GUARDIAN_KEYS', 'hex').toString('base64'))"` - -goal app call --app-id 45504480 --from "$STATELESS_ADDR" --app-arg "str:verify" --app-arg "b64:$GKEYSBASE64" --app-arg "int:3" --noteb64 "$VAABODY" -o verify.txn - -``` - -00 3fe8e05b0d3594bbf0ab1da0110dded88930a181ace6089a2442a8e58b293b23777331d928ab36c85de11e6f2874c1cc12c418fc4e0c1e344864a8b85fda042e00 -01 791d7134fba47002376841fe688f7c478ba223580ec25ad5046a93db477d36fb 4afa241ea95bf3c02b378a24220ff0f2ea035d088a0011bff9a4743d88f5c1b401 -02 81940f26308012efd7a307960223638abde4fb55abcaac04a9fa97bf92e5518e5903396bf7e807eb0e97e3009f7e679c0dcece45cd659ab6cf45fed9add2d6a10 - - -52a26ce40f8caa8d36155d37ef0d5d783fc614d2 -389a74e8ffa224aead0778c786163a7a2150768c -b4459ea6482d4ae574305b239b4f2264239e7599 diff --git a/staging/algorand/test/backend-test.js b/staging/algorand/test/backend-test.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/staging/algorand/test/pkeeper-sc-test.js b/staging/algorand/test/pkeeper-sc-test.js deleted file mode 100644 index 58facf112..000000000 --- a/staging/algorand/test/pkeeper-sc-test.js +++ /dev/null @@ -1,139 +0,0 @@ -const PricecasterLib = require('../lib/pricecaster') -const tools = require('../tools/app-tools') -const algosdk = require('algosdk') -const { expect } = require('chai') -const chai = require('chai') -chai.use(require('chai-as-promised')) -// Test general configuration for Betanet - -const VALIDATOR_ADDR = 'OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU' -const VALIDATOR_MNEMO = 'assault approve result rare float sugar power float soul kind galaxy edit unusual pretty tone tilt net range pelican avoid unhappy amused recycle abstract master' -const OTHER_ADDR = 'DMTBK62XZ6KNI7L5E6TRBTPB4B3YNVB4WYGSWR42SEV4XKV4LYHGBW4O34' -const OTHER_MNEMO = 'old agree harbor cost pink fog chunk hope vital used rural soccer model acquire clown host friend bring marriage surge dirt surge slab absent punch' -const SIGNATURES = {} -SIGNATURES[VALIDATOR_ADDR] = algosdk.mnemonicToSecretKey(VALIDATOR_MNEMO) -SIGNATURES[OTHER_ADDR] = algosdk.mnemonicToSecretKey(OTHER_MNEMO) - -const VALID_SYMBOL = 'BTC/USD ' -const VALID_PRICE = BigInt(485265555) -const VALID_EXPONENT = BigInt(4) -const VALID_CONF = BigInt(1400000) -const VALID_SLOT = BigInt(104566700) - -function signCallback (sender, tx) { - const txSigned = tx.signTxn(SIGNATURES[sender].sk) - return txSigned -} - -describe('Price-Keeper contract tests', function () { - let pclib - let algodClient - let appId - let lastTs - - before(async function () { - algodClient = new algosdk.Algodv2('', 'https://api.betanet.algoexplorer.io', '') - pclib = new PricecasterLib.PricecasterLib(algodClient) - - console.log('Clearing accounts of all previous apps...') - const appsTo = await tools.readCreatedApps(algodClient, VALIDATOR_ADDR) - for (let i = 0; i < appsTo.length; i++) { - console.log('Clearing ' + appsTo[i].id) - try { - const txId = await pclib.deleteApp(VALIDATOR_ADDR, signCallback, appsTo[i].id) - await pclib.waitForConfirmation(txId) - } catch (e) { - console.error('Could not delete application! Reason: ' + e) - } - } - - console.log('Creating new app...') - const txId = await pclib.createApp(VALIDATOR_ADDR, VALIDATOR_ADDR, VALID_SYMBOL, signCallback) - const txResponse = await pclib.waitForTransactionResponse(txId) - appId = pclib.appIdFromCreateAppResponse(txResponse) - pclib.setAppId(appId) - console.log('App Id: %d', appId) - }) - it('Must create app with proper initial global state', async function () { - const stVAddr = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'vaddr') - const stSym = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'sym') - expect(Buffer.from(stSym, 'base64').toString()).to.equal(VALID_SYMBOL) - expect(stVAddr.toString()).to.equal(VALIDATOR_ADDR) - }) - it('Must accept valid message and store data', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk) - const txid = await pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback) - expect(txid).to.have.length(52) - await pclib.waitForTransactionResponse(txid) - // console.log(await tools.printAppGlobalState(algodClient, appId, VALIDATOR_ADDR)) - const stPrice = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'price') - const stExp = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'exp') - const stConf = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'conf') - const stSlot = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'slot') - expect(stPrice.toString()).to.equal(VALID_PRICE.toString()) - expect((Buffer.from(stExp, 'base64')).readBigInt64BE()).to.equal(VALID_EXPONENT) - expect(stSlot.toString()).to.equal(VALID_SLOT.toString()) - expect(stConf.toString()).to.equal(VALID_CONF.toString()) - }) - it('Must accept second message with different price', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE + BigInt(400), VALID_EXPONENT + BigInt(3), VALID_CONF + BigInt(2), VALID_SLOT + BigInt(100), SIGNATURES[VALIDATOR_ADDR].sk) - const txid = await pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback) - expect(txid).to.have.length(52) - await pclib.waitForTransactionResponse(txid) - const stPrice = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'price') - const stExp = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'exp') - const stConf = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'conf') - const stSlot = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'slot') - expect(stPrice.toString()).to.equal((VALID_PRICE + BigInt(400)).toString()) - expect((Buffer.from(stExp, 'base64')).readBigInt64BE()).to.equal(VALID_EXPONENT + BigInt(3)) - expect(stSlot.toString()).to.equal((VALID_SLOT + BigInt(100)).toString()) - expect(stConf.toString()).to.equal((VALID_CONF + BigInt(2)).toString()) - lastTs = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'ts') - }) - it('Must accept negative exponent, stored as 2-complement 64bit', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, BigInt(-9), VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk) - const txid = await pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback) - expect(txid).to.have.length(52) - await pclib.waitForTransactionResponse(txid) - const stExp = await tools.readAppGlobalStateByKey(algodClient, appId, VALIDATOR_ADDR, 'exp') - const bufExp = Buffer.from(stExp, 'base64') - const val = bufExp.readBigInt64BE() - expect(val.toString()).to.equal('-9') - }) - it('Must reject non-validator as signer', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[OTHER_ADDR].sk) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject non-validator as sender', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk) - await expect(pclib.submitMessage(OTHER_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject future timestamp', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk, undefined, undefined, undefined, BigInt(lastTs + 200)) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject old timestamp', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk, undefined, undefined, undefined, BigInt(lastTs - 999999)) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject zero-priced message', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, BigInt(0), VALID_EXPONENT, VALID_CONF, VALID_SLOT, SIGNATURES[VALIDATOR_ADDR].sk) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject zero slot', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject bad header', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk, 'BADHEADER') - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject bad destination appId', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk, undefined, BigInt(100)) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) - it('Must reject bad message version', async function () { - const msgBuffer = pclib.createMessage(VALID_SYMBOL, VALID_PRICE, VALID_EXPONENT, VALID_CONF, BigInt(0), SIGNATURES[VALIDATOR_ADDR].sk, undefined, undefined, 0) - await expect(pclib.submitMessage(VALIDATOR_ADDR, msgBuffer, signCallback)).to.be.rejectedWith('Bad Request') - }) -}) diff --git a/staging/algorand/test/temp/dummy.txt b/staging/algorand/test/temp/dummy.txt deleted file mode 100644 index 3c546eb27..000000000 --- a/staging/algorand/test/temp/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -dummy file \ No newline at end of file diff --git a/staging/algorand/test/test-config.js b/staging/algorand/test/test-config.js deleted file mode 100644 index e215d500c..000000000 --- a/staging/algorand/test/test-config.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - // Configurations to use: - // - // Algoexplorer Betanet endpoint: - // - // ALGORAND_NODE_TOKEN: '' - // ALGORAND_NODE_HOST: 'https://api.betanet.algoexplorer.io', - // ALGORAND_NODE_PORT: '' - // - // Algoexplorer Testnet endpoint: - // - // ALGORAND_NODE_TOKEN: '' - // ALGORAND_NODE_HOST: 'https://api.betanet.algoexplorer.io' - // ALGORAND_NODE_PORT: '' - // - // Sandbox: - // - // ALGORAND_NODE_TOKEN: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' - // ALGORAND_NODE_HOST: 'localhost' - // ALGORAND_NODE_PORT: '4001' - // > - ALGORAND_NODE_HOST: 'https://api.testnet.algoexplorer.io', - ALGORAND_NODE_PORT: '', - ALGORAND_NODE_TOKEN: '' -} diff --git a/staging/algorand/test/testlib.js b/staging/algorand/test/testlib.js deleted file mode 100644 index 2ddf7f849..000000000 --- a/staging/algorand/test/testlib.js +++ /dev/null @@ -1,120 +0,0 @@ - -/** - * - * Pricecaster Testing Library. - * - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -const web3EthAbi = require('web3-eth-abi') -const web3Utils = require('web3-utils') -const elliptic = require('elliptic') -class TestLib { - /** - * Create a packed and signed VAA for testing. - * See https://github.com/certusone/wormhole/blob/dev.v2/design/0001_generic_message_passing.md - * - * @param {} guardianSetIndex The guardian set index - * @param {*} signers The list of private keys for signing the VAA - * @param {*} timestamp The timestamp of VAA - * @param {*} nonce The nonce. - * @param {*} emitterChainId The emitter chain identifier - * @param {*} emitterAddress The emitter chain address, prefixed with 0x - * @param {*} sequence The sequence. - * @param {*} consistencyLevel The reported consistency level - * @param {*} payload This VAA Payload hex string, prefixed with 0x - */ - createSignedVAA (guardianSetIndex, - signers, - timestamp, - nonce, - emitterChainId, - emitterAddress, - sequence, - consistencyLevel, - payload) { - const body = [ - web3EthAbi.encodeParameter('uint32', timestamp).substring(2 + (64 - 8)), - web3EthAbi.encodeParameter('uint32', nonce).substring(2 + (64 - 8)), - web3EthAbi.encodeParameter('uint16', emitterChainId).substring(2 + (64 - 4)), - web3EthAbi.encodeParameter('bytes32', emitterAddress).substring(2), - web3EthAbi.encodeParameter('uint64', sequence).substring(2 + (64 - 16)), - web3EthAbi.encodeParameter('uint8', consistencyLevel).substring(2 + (64 - 2)), - payload.substr(2) - ] - - const hash = web3Utils.keccak256(web3Utils.keccak256('0x' + body.join(''))) - - // console.log('VAA body Hash: ', hash) - - let signatures = '' - - for (const i in signers) { - // eslint-disable-next-line new-cap - const ec = new elliptic.ec('secp256k1') - const key = ec.keyFromPrivate(signers[i]) - const signature = key.sign(hash.substr(2), { canonical: true }) - - const packSig = [ - web3EthAbi.encodeParameter('uint8', i).substring(2 + (64 - 2)), - this.zeroPadBytes(signature.r.toString(16), 32), - this.zeroPadBytes(signature.s.toString(16), 32), - web3EthAbi.encodeParameter('uint8', signature.recoveryParam).substr(2 + (64 - 2)) - ] - - signatures += packSig.join('') - } - - const vm = [ - web3EthAbi.encodeParameter('uint8', 1).substring(2 + (64 - 2)), - web3EthAbi.encodeParameter('uint32', guardianSetIndex).substring(2 + (64 - 8)), - web3EthAbi.encodeParameter('uint8', signers.length).substring(2 + (64 - 2)), - - signatures, - body.join('') - ].join('') - - return vm - } - - zeroPadBytes (value, length) { - while (value.length < 2 * length) { - value = '0' + value - } - return value - } - - shuffle (array) { - let currentIndex = array.length; let randomIndex - - // While there remain elements to shuffle... - while (currentIndex !== 0) { - // Pick a remaining element... - randomIndex = Math.floor(Math.random() * currentIndex) - currentIndex--; - - // And swap it with the current element. - [array[currentIndex], array[randomIndex]] = [ - array[randomIndex], array[currentIndex]] - } - - return array - } -} - -module.exports = { - TestLib -} diff --git a/staging/algorand/test/wormhole-sc-test.js b/staging/algorand/test/wormhole-sc-test.js deleted file mode 100644 index af705a9e1..000000000 --- a/staging/algorand/test/wormhole-sc-test.js +++ /dev/null @@ -1,455 +0,0 @@ -/* eslint-disable no-unused-expressions */ -const PricecasterLib = require('../lib/pricecaster') -const tools = require('../tools/app-tools') -const algosdk = require('algosdk') -const { expect } = require('chai') -const chai = require('chai') -const spawnSync = require('child_process').spawnSync -const fs = require('fs') -const TestLib = require('../test/testlib.js') -const { makePaymentTxnWithSuggestedParams } = require('algosdk') -const testLib = new TestLib.TestLib() -const testConfig = require('./test-config') - -chai.use(require('chai-as-promised')) - -let pclib -let algodClient -let verifyProgramHash -let compiledVerifyProgram - -const OWNER_ADDR = 'OPDM7ACAW64Q4VBWAL77Z5SHSJVZZ44V3BAN7W44U43SUXEOUENZMZYOQU' -const OWNER_MNEMO = 'assault approve result rare float sugar power float soul kind galaxy edit unusual pretty tone tilt net range pelican avoid unhappy amused recycle abstract master' -const OTHER_ADDR = 'DMTBK62XZ6KNI7L5E6TRBTPB4B3YNVB4WYGSWR42SEV4XKV4LYHGBW4O34' -const OTHER_MNEMO = 'old agree harbor cost pink fog chunk hope vital used rural soccer model acquire clown host friend bring marriage surge dirt surge slab absent punch' -const SIGNATURES = {} -SIGNATURES[OWNER_ADDR] = algosdk.mnemonicToSecretKey(OWNER_MNEMO) -SIGNATURES[OTHER_ADDR] = algosdk.mnemonicToSecretKey(OTHER_MNEMO) - -const TEST_SYMBOL = 'TEST/USDX' - -const guardianKeys = [ - '52A26Ce40F8CAa8D36155d37ef0D5D783fc614d2', - '389A74E8FFa224aeAD0778c786163a7A2150768C', - 'B4459EA6482D4aE574305B239B4f2264239e7599', - '072491bd66F63356090C11Aae8114F5372aBf12B', - '51280eA1fd2B0A1c76Ae29a7d54dda68860A2bfF', - 'fa9Aa60CfF05e20E2CcAA784eE89A0A16C2057CB', - 'e42d59F8FCd86a1c5c4bA351bD251A5c5B05DF6A', - '4B07fF9D5cE1A6ed58b6e9e7d6974d1baBEc087e', - 'c8306B84235D7b0478c61783C50F990bfC44cFc0', - 'C8C1035110a13fe788259A4148F871b52bAbcb1B', - '58A2508A20A7198E131503ce26bBE119aA8c62b2', - '8390820f04ddA22AFe03be1c3bb10f4ba6CF94A0', - '1FD6e97387C34a1F36DE0f8341E9D409E06ec45b', - '255a41fC2792209CB998A8287204D40996df9E54', - 'bA663B12DD23fbF4FbAC618Be140727986B3BBd0', - '79040E577aC50486d0F6930e160A5C75FD1203C6', - '3580D2F00309A9A85efFAf02564Fc183C0183A96', - '3869795913D3B6dBF3B24a1C7654672c69A23c35', - '1c0Cc52D7673c52DE99785741344662F5b2308a0' - -] -const guardianPrivKeys = [ - '563d8d2fd4e701901d3846dee7ae7a92c18f1975195264d676f8407ac5976757', - '8d97f25916a755df1d9ef74eb4dbebc5f868cb07830527731e94478cdc2b9d5f', - '9bd728ad7617c05c31382053b57658d4a8125684c0098f740a054d87ddc0e93b', - '5a02c4cd110d20a83a7ce8d1a2b2ae5df252b4e5f6781c7855db5cc28ed2d1b4', - '93d4e3b443bf11f99a00901222c032bd5f63cf73fc1bcfa40829824d121be9b2', - 'ea40e40c63c6ff155230da64a2c44fcd1f1c9e50cacb752c230f77771ce1d856', - '87eaabe9c27a82198e618bca20f48f9679c0f239948dbd094005e262da33fe6a', - '61ffed2bff38648a6d36d6ed560b741b1ca53d45391441124f27e1e48ca04770', - 'bd12a242c6da318fef8f98002efb98efbf434218a78730a197d981bebaee826e', - '20d3597bb16525b6d09e5fb56feb91b053d961ab156f4807e37d980f50e71aff', - '344b313ffbc0199ff6ca08cacdaf5dc1d85221e2f2dc156a84245bd49b981673', - '848b93264edd3f1a521274ca4da4632989eb5303fd15b14e5ec6bcaa91172b05', - 'c6f2046c1e6c172497fc23bd362104e2f4460d0f61984938fa16ef43f27d93f6', - '693b256b1ee6b6fb353ba23274280e7166ab3be8c23c203cc76d716ba4bc32bf', - '13c41508c0da03018d61427910b9922345ced25e2bbce50652e939ee6e5ea56d', - '460ee0ee403be7a4f1eb1c63dd1edaa815fbaa6cf0cf2344dcba4a8acf9aca74', - 'b25148579b99b18c8994b0b86e4dd586975a78fa6e7ad6ec89478d7fbafd2683', - '90d7ac6a82166c908b8cf1b352f3c9340a8d1f2907d7146fb7cd6354a5436cca', - 'b71d23908e4cf5d6cd973394f3a4b6b164eb1065785feee612efdfd8d30005ed' -] - -const PYTH_EMITTER = '0x3afda841c1f43dd7d546c8a581ba1f92a139f4133f9f6ab095558f6a359df5d4' -const OTHER_EMITTER = '0x1111111111111111111111111111111111111111111111111111111111111111' -const PYTH_PAYLOAD = '0x50325748000101230abfe0ec3b460bd55fc4fb36356716329915145497202b8eb8bf1af6a0a3b9fe650f0367d4a7ef9815a593ea15d36593f0643aaaf0149bb04be67ab851decd010000002f17254388fffffff70000002eed73d9000000000070d3b43f0000000037faa03d000000000e9e555100000000894af11c0000000037faa03d000000000dda6eb801000000000061a5ff9a' -const OTHER_PAYLOAD = '0xf0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0' - -let pythVaa -let pythVaaBody -let pythVaaSignatures -let otherVaa -let otherVaaBody -let otherVaaSignatures - -// -------------------------------------------------------------------------- -// Utility functions -// -------------------------------------------------------------------------- - -async function createVaaProcessorApp (gsexptime, gsindex, gkeys) { - const txId = await pclib.createVaaProcessorApp(OWNER_ADDR, gsexptime, gsindex, gkeys.join(''), signCallback) - const txResponse = await pclib.waitForTransactionResponse(txId) - const appId = pclib.appIdFromCreateAppResponse(txResponse) - pclib.setAppId('vaaProcessor', appId) - return appId -} - -async function createPricekeeperApp (vaaProcessorAppid) { - const txId = await pclib.createPricekeeperApp(OWNER_ADDR, vaaProcessorAppid, signCallback) - const txResponse = await pclib.waitForTransactionResponse(txId) - const appId = pclib.appIdFromCreateAppResponse(txResponse) - pclib.setAppId('pricekeeper', appId) - return appId -} - -function signCallback (sender, tx) { - const txSigned = tx.signTxn(SIGNATURES[sender].sk) - return txSigned -} - -async function getTxParams () { - const params = await algodClient.getTransactionParams().do() - params.fee = 1000 - params.flatFee = true - return params -} - -async function buildTransactionGroup (numOfVerifySteps, stepSize, guardianKeys, guardianCount, - signatures, vaaBody, fee, sender, addVerifyTxCallback, addLastTxCallback) { - const params = await getTxParams() - if (fee !== undefined) { - params.fee = fee - } - const senderAddress = sender !== undefined ? sender : verifyProgramHash - const addVerifyCallbackFn = addVerifyTxCallback !== undefined ? addVerifyTxCallback : pclib.addVerifyTx.bind(pclib) - const addLastTxCallbackFn = addLastTxCallback !== undefined ? addLastTxCallback : pclib.addPriceStoreTx.bind(pclib) - - // Fill remaining signatures with dummy ones for cases where not all guardians may sign. - - const numOfSigs = signatures.length / 132 - const remaining = guardianCount - numOfSigs - if (remaining > 0) { - for (let i = guardianCount - remaining; i < guardianCount; ++i) { - signatures += i.toString(16).padStart(2, '0') + ('0'.repeat(130)) - } - } - - const gid = pclib.beginTxGroup() - const sigSubsets = [] - for (let i = 0; i < numOfVerifySteps; i++) { - const st = stepSize * i - const sigSetLen = 132 * stepSize - const keySubset = guardianKeys.slice(st, i < numOfVerifySteps - 1 ? st + stepSize : undefined) - sigSubsets.push(signatures.slice(i * sigSetLen, i < numOfVerifySteps - 1 ? ((i * sigSetLen) + sigSetLen) : undefined)) - addVerifyCallbackFn(gid, senderAddress, params, vaaBody, keySubset, guardianCount) - } - - addLastTxCallbackFn(gid, OWNER_ADDR, params, TEST_SYMBOL, vaaBody.slice(51)) - const tx = await pclib.commitVerifyTxGroup(gid, compiledVerifyProgram.bytes, numOfSigs, sigSubsets, OWNER_ADDR, signCallback) - return tx -} - -// =============================================================================================================== -// -// Test suite starts here -// -// =============================================================================================================== - -describe('VAA Processor Smart-contract Tests', function () { - let appId, pkAppId - - before(async function () { - algodClient = new algosdk.Algodv2(testConfig.ALGORAND_NODE_TOKEN, testConfig.ALGORAND_NODE_HOST, testConfig.ALGORAND_NODE_PORT) - pclib = new PricecasterLib.PricecasterLib(algodClient) - const ownerAcc = algosdk.mnemonicToSecretKey(OWNER_MNEMO) - - const ownerAccInfo = await algodClient.accountInformation(ownerAcc.addr).do() - expect(ownerAccInfo.amount).to.be.at.least(algosdk.algosToMicroalgos(10), 'Owner must have enough funding (10 ALGO) to run tests') - - console.log('Clearing accounts of all previous apps...') - const appsTo = await tools.readCreatedApps(algodClient, OWNER_ADDR) - for (let i = 0; i < appsTo.length; i++) { - console.log('Clearing ' + appsTo[i].id) - try { - const txId = await pclib.deleteApp(OWNER_ADDR, signCallback, appsTo[i].id) - await pclib.waitForConfirmation(txId) - } catch (e) { - console.error('Could not delete application! Reason: ' + e) - } - } - - const vaaProcessorClearState = 'test/temp/vaa-clear-state.teal' - const vaaProcessorApproval = 'test/temp/vaa-processor.teal' - const priceKeeperApproval = 'test/temp/pricekeeper-v2.teal' - const priceKeeperClearState = 'test/temp/pricekeeper-clear-state.teal' - - pclib.setApprovalProgramFile('vaaProcessor', vaaProcessorApproval) - pclib.setApprovalProgramFile('pricekeeper', priceKeeperApproval) - pclib.setClearStateProgramFile('vaaProcessor', vaaProcessorClearState) - pclib.setClearStateProgramFile('pricekeeper', priceKeeperClearState) - - // (!) ENABLE FOR DIAGNOSING FAILED TESTS - // - pclib.enableDumpFailedTx(true) - pclib.setDumpFailedTxDirectory('./test/temp') - - console.log(spawnSync('python', ['teal/wormhole/pyteal/vaa-processor.py', vaaProcessorApproval, vaaProcessorClearState]).output.toString()) - console.log(spawnSync('python', ['teal/wormhole/pyteal/pricekeeper-v2.py', priceKeeperApproval, priceKeeperClearState]).output.toString()) - - pythVaa = testLib.createSignedVAA(0, guardianPrivKeys, 1, 1, 1, PYTH_EMITTER, 0, 0, PYTH_PAYLOAD) - pythVaaBody = Buffer.from(pythVaa.substr(12 + guardianPrivKeys.length * 132), 'hex') - pythVaaSignatures = pythVaa.substr(12, guardianPrivKeys.length * 132) - otherVaa = testLib.createSignedVAA(0, guardianPrivKeys, 1, 1, 1, OTHER_EMITTER, 0, 0, OTHER_PAYLOAD) - otherVaaBody = Buffer.from(otherVaa.substr(12 + guardianPrivKeys.length * 132), 'hex') - otherVaaSignatures = otherVaa.substr(12, guardianPrivKeys.length * 132) - } - ) - - it('Must fail to create app with incorrect guardian keys length', async function () { - const gsexptime = 2524618800 - await expect(createVaaProcessorApp(gsexptime, 0, ['BADADDRESS'])).to.be.rejectedWith('Bad Request') - }) - - it('Must create VAA Processor app with initial guardians and proper initial state', async function () { - const gsexptime = 2524618800 - appId = await createVaaProcessorApp(gsexptime, 0, guardianKeys) - console.log(' - [Created VAA Processor appId: %d]', appId) - - const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - const gsexp = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gsexp') - expect(gscount.toString()).to.equal((guardianKeys.length).toString()) - expect(gsexp.toString()).to.equal(gsexptime.toString()) - - let i = 0 - const buf = Buffer.alloc(8) - for (const gk of guardianKeys) { - buf.writeBigUint64BE(BigInt(i++)) - const gkstate = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, buf.toString()) - expect(Buffer.from(gkstate, 'base64').toString('hex')).to.equal(gk.toLowerCase()) - } - }) - - it('Must create Pricekeeper V2 app with VAA Processor app id set', async function () { - pkAppId = await createPricekeeperApp(pclib.getAppId('vaaProcessor')) - console.log(' - [Created pricekeeper appId: %d]', pkAppId) - - const vaapid = await tools.readAppGlobalStateByKey(algodClient, pclib.getAppId('pricekeeper'), OWNER_ADDR, 'vaapid') - expect(vaapid.toString()).to.equal(pclib.getAppId('vaaProcessor').toString()) - }) - - it('Must set stateless logic hash from owner', async function () { - const teal = 'test/temp/vaa-verify.teal' - spawnSync('python', ['teal/wormhole/pyteal/vaa-verify.py', appId, teal]) - const program = fs.readFileSync(teal, 'utf8') - compiledVerifyProgram = await pclib.compileProgram(program) - verifyProgramHash = compiledVerifyProgram.hash - console.log(' - Stateless program: ', verifyProgramHash) - - const txid = await pclib.setVAAVerifyProgramHash(OWNER_ADDR, verifyProgramHash, signCallback) - await pclib.waitForTransactionResponse(txid) - const vphstate = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vphash') - expect(vphstate).to.equal(verifyProgramHash) - - // Feed this account for verification fees. - const parms = await getTxParams() - const tx = makePaymentTxnWithSuggestedParams(OWNER_ADDR, verifyProgramHash, 200000, undefined, undefined, parms) - const signedTx = signCallback(OWNER_ADDR, tx) - await algodClient.sendRawTransaction(signedTx).do() - await pclib.waitForTransactionResponse(tx.txID().toString()) - }) - - it('Must set authorized appcall id from owner', async function () { - const txid = await pclib.setAuthorizedAppId(OWNER_ADDR, pkAppId, signCallback) - await pclib.waitForTransactionResponse(txid) - const authid = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'authid') - expect(authid).to.equal(pkAppId) - }) - - it('Must disallow setting stateless logic hash from non-owner', async function () { - await expect(pclib.setVAAVerifyProgramHash(OTHER_ADDR, verifyProgramHash, signCallback)).to.be.rejectedWith('Bad Request') - }) - - it('Must reject setting stateless logic hash from group transaction', async function () { - const appArgs = [new Uint8Array(Buffer.from('setvphash')), new Uint8Array(verifyProgramHash)] - const params = await getTxParams() - - const gid = pclib.beginTxGroup() - const appTx = algosdk.makeApplicationNoOpTxn(OWNER_ADDR, params, this.appId, appArgs) - const dummyTx = algosdk.makeApplicationNoOpTxn(OWNER_ADDR, params, this.appId, appArgs) - pclib.addTxToGroup(gid, appTx) - pclib.addTxToGroup(gid, dummyTx) - await expect(pclib.commitTxGroup(gid, OWNER_ADDR, signCallback)).to.be.rejectedWith('Bad Request') - }) - - it('Must reject setting stateless logic hash with invalid address length', async function () { - const appArgs = [new Uint8Array(Buffer.from('setvphash')), new Uint8Array(verifyProgramHash).subarray(0, 10)] - await expect(pclib.callApp(OWNER_ADDR, 'vaaProcessor', appArgs, [], signCallback)).to.be.rejectedWith('Bad Request') - }) - - // it('Must reject incorrect transaction group size', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const badSize = 4 + Math.ceil(gscount / vssize) - // await expect(execVerify(badSize, vssize, guardianKeys, pythVaaSignatures, pythVaaBody, gscount)).to.be.rejectedWith('Bad Request') - // }) - - // it('Must reject incorrect argument count for verify call', async function () { - // const verifyFunc = function (sender, params, payload, gksubset, totalguardians) { - // const appArgs = [] - // appArgs.push(new Uint8Array(Buffer.from('verify'))) - // const tx = algosdk.makeApplicationNoOpTxn(sender, - // params, - // appId, - // appArgs, undefined, undefined, undefined, - // new Uint8Array(payload)) - // pclib.groupTx.push(tx) - - // return tx.txID() - // } - // pclib.beginTxGroup() - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // await expect(execVerify(groupSize, vssize, guardianKeys, pythVaaSignatures, pythVaaBody, gscount, undefined, undefined, verifyFunc)).to.be.rejectedWith('Bad Request') - // }) - - // it('Must reject unknown sender for verify call', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // await expect(execVerify(groupSize, vssize, guardianKeys, pythVaaSignatures, pythVaaBody, gscount, undefined, OTHER_ADDR)).to.be.rejectedWith('Bad Request') - // }) - - // it('Must reject guardian set count argument not matching global state', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // await expect(execVerify(groupSize, vssize, guardianKeys, pythVaaSignatures, pythVaaBody, 2)).to.be.rejectedWith('Bad Request') - // }) - - // it('Must reject guardian key list argument not matching global state', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // const gkBad = guardianKeys.slice(0, guardianKeys.length - 3) - // await expect(execVerify(groupSize, vssize, gkBad, pythVaaSignatures, pythVaaBody, 2)).to.be.rejectedWith('Bad Request') - // }) - // it('Must reject non-app call transaction in group', async function () { - - // }) - // it('Must reject app-call with mismatched AppId in group', async function () { - - // }) - // it('Must reject transaction with not verified bit set in group', async function () { - - // }) - - it('Must verify and handle Pyth VAA - all signers present', async function () { - const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - const vsSize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - const groupSize = Math.ceil(gscount / vsSize) - const tx = await buildTransactionGroup(groupSize, vsSize, guardianKeys, gscount, pythVaaSignatures, pythVaaBody) - await pclib.waitForConfirmation(tx) - - // console.log(await tools.readAppGlobalStateByKey(algodClient, pkAppId, OWNER_ADDR, TEST_SYMBOL)) - }) - - it('Must fail to verify VAA - (shuffle signers)', async function () { - const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - const vsSize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - const groupSize = Math.ceil(gscount / vsSize) - - let shuffleGuardianPrivKeys = [...guardianPrivKeys] - shuffleGuardianPrivKeys = testLib.shuffle(shuffleGuardianPrivKeys) - - pythVaa = testLib.createSignedVAA(0, shuffleGuardianPrivKeys, 1, 1, 1, PYTH_EMITTER, 0, 0, PYTH_PAYLOAD) - pythVaaBody = Buffer.from(pythVaa.substr(12 + shuffleGuardianPrivKeys.length * 132), 'hex') - pythVaaSignatures = pythVaa.substr(12, shuffleGuardianPrivKeys.length * 132) - - await expect(buildTransactionGroup(groupSize, vsSize, guardianKeys, gscount, pythVaaSignatures, pythVaaBody)).to.be.rejectedWith('Bad Request') - }) - - it('Must verify VAA with signers > 2/3 + 1', async function () { - const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - const vsSize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - - // Fixed-point division - // https://github.com/certusone/wormhole/blob/00ddd5f02ba34e6570823b23518af8bbd6d91231/ethereum/contracts/Messages.sol#L30 - - const quorum = Math.trunc(((gscount * 10 / 3) * 2) / 10 + 1) - const slicedGuardianPrivKeys = guardianPrivKeys.slice(0, quorum + 1) - - pythVaa = testLib.createSignedVAA(0, slicedGuardianPrivKeys, 1, 1, 1, PYTH_EMITTER, 0, 0, PYTH_PAYLOAD) - pythVaaBody = Buffer.from(pythVaa.substr(12 + slicedGuardianPrivKeys.length * 132), 'hex') - pythVaaSignatures = pythVaa.substr(12, slicedGuardianPrivKeys.length * 132) - const groupSize = Math.ceil(gscount / vsSize) - const tx = await buildTransactionGroup(groupSize, vsSize, guardianKeys, gscount, pythVaaSignatures, pythVaaBody) - await pclib.waitForConfirmation(tx) - }) - - it('Must fail to verify VAA with <= 2/3 + 1 signers (no quorum)', async function () { - const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - const vsSize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - - // Fixed-point division - // https://github.com/certusone/wormhole/blob/00ddd5f02ba34e6570823b23518af8bbd6d91231/ethereum/contracts/Messages.sol#L30 - - const quorum = Math.trunc(((gscount * 10 / 3) * 2) / 10 + 1) - const slicedGuardianPrivKeys = guardianPrivKeys.slice(0, quorum) - - pythVaa = testLib.createSignedVAA(0, slicedGuardianPrivKeys, 1, 1, 1, PYTH_EMITTER, 0, 0, PYTH_PAYLOAD) - pythVaaBody = Buffer.from(pythVaa.substr(12 + slicedGuardianPrivKeys.length * 132), 'hex') - pythVaaSignatures = pythVaa.substr(12, slicedGuardianPrivKeys.length * 132) - const groupSize = Math.ceil(gscount / vsSize) - - await expect(buildTransactionGroup(groupSize, vsSize, guardianKeys, gscount, pythVaaSignatures, pythVaaBody)).to.be.rejectedWith('Bad Request') - }) - // it('Must verify and handle governance VAA', async function () { - // // TBD - // }) - - // it('Must reject unknown emitter VAA', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // await expect(execVerify(groupSize, vssize, guardianKeys, otherVaaSignatures, otherVaaBody, gscount)).to.be.rejectedWith('Bad Request') - // }) - - // it('Stateless: Must reject transaction with excess fee', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // await expect(execVerify(groupSize, vssize, guardianKeys, pythVaaSignatures, pythVaaBody, gscount, 800000)).to.be.rejectedWith('Bad Request') - // }) - - // it('Stateless: Must reject incorrect number of logic program arguments', async function () { - - // }) - - // it('Stateless: Must reject transaction with mismatching number of signatures', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // const pythVaaSignatures2 = pythVaaSignatures.substr(0, pythVaaSignatures.length - 132 - 1) - // await expect(execVerify(groupSize, vssize, guardianKeys, pythVaaSignatures2, pythVaaBody, gscount)).to.be.rejectedWith('Bad Request') - // }) - - // it('Stateless: Must reject transaction with non-zero rekey', async function () { - - // }) - - // it('Stateless: Must reject transaction call from bad app-id', async function () { - - // }) - - // it('Stateless: Must reject signature verification failure', async function () { - // const gscount = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'gscount') - // const vssize = await tools.readAppGlobalStateByKey(algodClient, appId, OWNER_ADDR, 'vssize') - // const groupSize = Math.ceil(gscount / vssize) - // let pythVaaSignatures2 = pythVaaSignatures.substr(0, pythVaaSignatures.length - 132 - 1) - // pythVaaSignatures2 += '0d525ac1524ec9d9ee623ef535a867e8f86d9b3f8e4c7b4234dbe7bb40dc8494327af2fa37c3db50064d6114f2e1441c4eee444b83636f11ce1f730f7b38490e2800' - // await expect(execVerify(groupSize, vssize, guardianKeys, pythVaaSignatures2, pythVaaBody, gscount)).to.be.rejectedWith('Bad Request') - // }) -}) diff --git a/staging/algorand/tools/app-tools.js b/staging/algorand/tools/app-tools.js deleted file mode 100644 index 473ee231f..000000000 --- a/staging/algorand/tools/app-tools.js +++ /dev/null @@ -1,276 +0,0 @@ -/************************************************************************* - * Copyright 2022 Wormhole Project Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -const sha512 = require('js-sha512') -const hibase32 = require('hi-base32') - -const ALGORAND_ADDRESS_SIZE = 58 - -function timeoutPromise (ms, promise) { - return new Promise((resolve, reject) => { - const timeoutId = setTimeout(() => { - reject(new Error('promise timeout')) - }, ms) - promise.then( - (res) => { - clearTimeout(timeoutId) - resolve(res) - }, - (err) => { - clearTimeout(timeoutId) - reject(err) - } - ) - }) -} - -function getInt64Bytes (x, len) { - if (!len) { - len = 8 - } - const bytes = new Uint8Array(len) - do { - len -= 1 - // eslint-disable-next-line no-bitwise - bytes[len] = x & (255) - // eslint-disable-next-line no-bitwise - x >>= 8 - } while (len) - return bytes -} - -function addressFromByteBuffer (addr) { - const bytes = Buffer.from(addr, 'base64') - - // compute checksum - const checksum = sha512.sha512_256.array(bytes).slice(28, 32) - - const c = new Uint8Array(bytes.length + checksum.length) - c.set(bytes) - c.set(checksum, bytes.length) - - const v = hibase32.encode(c) - - return v.toString().slice(0, ALGORAND_ADDRESS_SIZE) -} - -function printAppCallDeltaArray (deltaArray) { - for (let i = 0; i < deltaArray.length; i++) { - if (deltaArray[i].address) { - console.log('Local state change address: ' + deltaArray[i].address) - for (let j = 0; j < deltaArray[i].delta.length; j++) { - printAppCallDelta(deltaArray[i].delta[j]) - } - } else { - console.log('Global state change') - printAppCallDelta(deltaArray[i]) - } - } -} - -function printAppStateArray (stateArray) { - for (let n = 0; n < stateArray.length; n++) { - printAppState(stateArray[n]) - } -} - -function appValueState (stateValue) { - let text = '' - - if (stateValue.type == 1) { - const addr = addressFromByteBuffer(stateValue.bytes) - if (addr.length == ALGORAND_ADDRESS_SIZE) { - text += addr - } else { - text += stateValue.bytes - } - } else if (stateValue.type == 2) { - text = stateValue.uint - } else { - text += stateValue.bytes - } - - return text -} - -function appValueStateString (stateValue) { - let text = '' - - if (stateValue.type == 1) { - const addr = addressFromByteBuffer(stateValue.bytes) - if (addr.length == ALGORAND_ADDRESS_SIZE) { - text += addr - } else { - text += stateValue.bytes - } - } else if (stateValue.type == 2) { - text += stateValue.uint - } else { - text += stateValue.bytes - } - - return text -} - -function printAppState (state) { - let text = Buffer.from(state.key, 'base64').toString() + ': ' - - text += appValueStateString(state.value) - - console.log(text) -} - -async function printAppLocalState (algodClient, appId, accountAddr) { - const ret = await readAppLocalState(algodClient, appId, accountAddr) - if (ret) { - console.log('Application %d local state for account %s:', appId, accountAddr) - printAppStateArray(ret) - } -} - -async function printAppGlobalState (algodClient, appId, accountAddr) { - const ret = await readAppGlobalState(algodClient, appId, accountAddr) - if (ret) { - console.log('Application %d global state:', appId) - printAppStateArray(ret) - } -} - -async function readCreatedApps (algodClient, accountAddr) { - const accountInfoResponse = await algodClient.accountInformation(accountAddr).do() - return accountInfoResponse['created-apps'] -} - -async function readOptedInApps (algodClient, accountAddr) { - const accountInfoResponse = await algodClient.accountInformation(accountAddr).do() - return accountInfoResponse['apps-local-state'] -} - -// read global state of application -async function readAppGlobalState (algodClient, appId, accountAddr) { - const accountInfoResponse = await algodClient.accountInformation(accountAddr).do() - for (let i = 0; i < accountInfoResponse['created-apps'].length; i++) { - if (accountInfoResponse['created-apps'][i].id === appId) { - const globalState = accountInfoResponse['created-apps'][i].params['global-state'] - - return globalState - } - } -} - -async function readAppGlobalStateByKey (algodClient, appId, accountAddr, key) { - const accountInfoResponse = await algodClient.accountInformation(accountAddr).do() - for (let i = 0; i < accountInfoResponse['created-apps'].length; i++) { - if (accountInfoResponse['created-apps'][i].id === appId) { - // console.log("Application's global state:") - const stateArray = accountInfoResponse['created-apps'][i].params['global-state'] - for (let j = 0; j < stateArray.length; j++) { - const text = Buffer.from(stateArray[j].key, 'base64').toString() - - if (key === text) { - return appValueState(stateArray[j].value) - } - } - } - } -} - -// read local state of application from user account -async function readAppLocalState (algodClient, appId, accountAddr) { - const accountInfoResponse = await algodClient.accountInformation(accountAddr).do() - for (let i = 0; i < accountInfoResponse['apps-local-state'].length; i++) { - if (accountInfoResponse['apps-local-state'][i].id === appId) { - // console.log(accountAddr + " opted in, local state:") - - if (accountInfoResponse['apps-local-state'][i]['key-value']) { - return accountInfoResponse['apps-local-state'][i]['key-value'] - } - } - } -} - -async function readAppLocalStateByKey (algodClient, appId, accountAddr, key) { - const accountInfoResponse = await algodClient.accountInformation(accountAddr).do() - for (let i = 0; i < accountInfoResponse['apps-local-state'].length; i++) { - if (accountInfoResponse['apps-local-state'][i].id === appId) { - const stateArray = accountInfoResponse['apps-local-state'][i]['key-value'] - - if (!stateArray) { - return null - } - for (let j = 0; j < stateArray.length; j++) { - const text = Buffer.from(stateArray[j].key, 'base64').toString() - - if (key === text) { - return appValueState(stateArray[j].value) - } - } - // not found assume 0 - return 0 - } - } -} - -function uintArray8ToString (byteArray) { - return Array.from(byteArray, function (byte) { - // eslint-disable-next-line no-bitwise - return ('0' + (byte & 0xFF).toString(16)).slice(-2) - }).join('') -} - -/** - * Verify if transactionResponse has any information about a transaction local or global state change. - * @param {Object} transactionResponse object containing the transaction response of an application call - * @return {Boolean} returns true if there is a local or global delta meanining that - * the transaction made a change in the local or global state - */ -function anyAppCallDelta (transactionResponse) { - return (transactionResponse['global-state-delta'] || transactionResponse['local-state-delta']) -} - -/** - * Print to stdout the changes introduced by the transaction that generated the transactionResponse if any. - * @param {Object} transactionResponse object containing the transaction response of an application call - * @return {void} - */ -function printAppCallDelta (transactionResponse) { - if (transactionResponse['global-state-delta'] !== undefined) { - console.log('Global State updated:') - printAppCallDeltaArray(transactionResponse['global-state-delta']) - } - if (transactionResponse['local-state-delta'] !== undefined) { - console.log('Local State updated:') - printAppCallDeltaArray(transactionResponse['local-state-delta']) - } -} - -module.exports = { - timeoutPromise, - getInt64Bytes, - addressFromByteBuffer, - printAppStateArray, - printAppState, - printAppLocalState, - printAppGlobalState, - readCreatedApps, - readOptedInApps, - readAppGlobalState, - readAppGlobalStateByKey, - readAppLocalState, - readAppLocalStateByKey, - uintArray8ToString, - anyAppCallDelta, - printAppCallDelta -} diff --git a/staging/algorand/tools/deploy-wh.js b/staging/algorand/tools/deploy-wh.js deleted file mode 100644 index 947850a31..000000000 --- a/staging/algorand/tools/deploy-wh.js +++ /dev/null @@ -1,142 +0,0 @@ -/* eslint-disable linebreak-style */ -const algosdk = require('algosdk') -const { exit } = require('process') -const readline = require('readline') -const PricecasterLib = require('../lib/pricecaster') -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}) -const spawnSync = require('child_process').spawnSync -const fs = require('fs') - -function ask (questionText) { - return new Promise((resolve) => { - rl.question(questionText, input => resolve(input)) - }) -} - -let globalMnemo = '' - -function signCallback (sender, tx) { - const txSigned = tx.signTxn(algosdk.mnemonicToSecretKey(globalMnemo).sk) - return txSigned -} - -async function startOp (algodClient, fromAddress, gexpTime, gkeys) { - console.log('Compiling programs ...\n') - let out = spawnSync('python', ['teal/wormhole/pyteal/vaa-processor.py']) - console.log(out.output.toString()) - out = spawnSync('python', ['teal/wormhole/pyteal/pricekeeper-v2.py']) - console.log(out.output.toString()) - - const pclib = new PricecasterLib.PricecasterLib(algodClient) - console.log('Creating VAA Processor...') - let txId = await pclib.createVaaProcessorApp(fromAddress, gexpTime, 0, gkeys.join(''), signCallback) - console.log('txId: ' + txId) - let txResponse = await pclib.waitForTransactionResponse(txId) - const appId = pclib.appIdFromCreateAppResponse(txResponse) - console.log('Deployment App Id: %d', appId) - pclib.setAppId('vaaProcessor', appId) - - console.log('Creating Pricekeeper V2...') - txId = await pclib.createPricekeeperApp(fromAddress, appId, signCallback) - console.log('txId: ' + txId) - txResponse = await pclib.waitForTransactionResponse(txId) - const pkAppId = pclib.appIdFromCreateAppResponse(txResponse) - console.log('Deployment App Id: %d', pkAppId) - pclib.setAppId('pricekeeper', pkAppId) - - console.log('Setting VAA Processor authid parameter...') - txId = await pclib.setAuthorizedAppId(fromAddress, pkAppId, signCallback) - console.log('txId: ' + txId) - txResponse = await pclib.waitForTransactionResponse(txId) - - console.log('Compiling verify VAA stateless code...') - out = spawnSync('python', ['teal/wormhole/pyteal/vaa-verify.py']) - console.log(out.output.toString()) - - spawnSync('python', ['teal/wormhole/pyteal/vaa-verify.py', appId]) - const program = fs.readFileSync('teal/wormhole/build/vaa-verify.teal', 'utf8') - const compiledVerifyProgram = await pclib.compileProgram(program) - console.log('Stateless program address: ', compiledVerifyProgram.hash) - - console.log('Setting VAA Processor stateless code...') - const txid = await pclib.setVAAVerifyProgramHash(fromAddress, compiledVerifyProgram.hash, signCallback) - console.log('txId: ' + txId) - await pclib.waitForTransactionResponse(txid) - - const dt = Date.now().toString() - const resultsFileName = 'DEPLOY-' + dt - const binaryFileName = 'VAA-VERIFY-' + dt + '.BIN' - - console.log(`Writing deployment results file ${resultsFileName}...`) - fs.writeFileSync(resultsFileName, `vaaProcessorAppId: ${appId}\npriceKeeperV2AppId: ${pkAppId}\nvaaVerifyProgramHash: '${compiledVerifyProgram.hash}'`) - - console.log(`Writing stateless code binary file ${binaryFileName}...`) - fs.writeFileSync(binaryFileName, compiledVerifyProgram.bytes) -} - -(async () => { - console.log('\nPricecaster v2 Apps Deployment Tool') - - if (process.argv.length !== 7) { - console.log('Usage: deploy \n') - console.log('where:\n') - console.log('glistfile File containing the initial list of guardians') - console.log('gexptime Guardian set expiration time') - console.log('from Deployer account') - console.log('network Testnet, betanet or mainnet') - console.log('keyfile Secret file containing signing key mnemonic') - console.log('\n- File must contain one guardian key per line, formatted in hex, without hex prefix.') - console.log('\n- Deployment process will generate one DEPLOY-xxxx file with application Ids, stateless hash, and') - console.log(' a VAA-VERIFY-XXXX.bin with stateless compiled bytes, to use with backend configuration') - exit(0) - } - - const listfile = process.argv[2] - const gexpTime = process.argv[3] - const fromAddress = process.argv[4] - const network = process.argv[5] - const keyfile = process.argv[6] - - const config = { server: '', apiToken: '', port: '' } - if (network === 'betanet') { - config.server = 'https://api.betanet.algoexplorer.io' - } else if (network === 'mainnet') { - config.server = 'https://api.algoexplorer.io' - } else if (network === 'testnet') { - config.server = 'https://api.testnet.algoexplorer.io' - } else { - console.error('Invalid network: ' + network) - exit(1) - } - - const fileDataStr = fs.readFileSync(listfile).toString() - const gkeys = fileDataStr.match(/[^\r\n]+/g) - if (!algosdk.isValidAddress(fromAddress)) { - console.error('Invalid deployer address: ' + fromAddress) - exit(1) - } - - const algodClient = new algosdk.Algodv2(config.apiToken, config.server, config.port) - - console.log('Parameters for deployment: ') - console.log('From: ' + fromAddress) - console.log('Network: ' + network) - console.log('Guardian expiration time: ' + gexpTime) - console.log(`Guardian Keys: (${gkeys.length}) ` + gkeys) - const answer = await ask('\nEnter YES to confirm parameters, anything else to abort. ') - if (answer !== 'YES') { - console.warn('Aborted by user.') - exit(1) - } - globalMnemo = fs.readFileSync(keyfile).toString() - try { - await startOp(algodClient, fromAddress, gexpTime, gkeys) - } catch (e) { - console.error('(!) Deployment Failed: ' + e.toString()) - } - console.log('Bye.') - exit(0) -})() diff --git a/staging/algorand/tools/deploy.js b/staging/algorand/tools/deploy.js deleted file mode 100644 index f21706c1e..000000000 --- a/staging/algorand/tools/deploy.js +++ /dev/null @@ -1,91 +0,0 @@ -/* eslint-disable linebreak-style */ -const algosdk = require('algosdk') -const { exit } = require('process') -const readline = require('readline') -const PricecasterLib = require('../lib/pricecaster') -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}) - -function ask (questionText) { - return new Promise((resolve) => { - rl.question(questionText, input => resolve(input)) - }) -} - -let globalMnemo = '' - -function signCallback (sender, tx) { - const txSigned = tx.signTxn(algosdk.mnemonicToSecretKey(globalMnemo).sk) - return txSigned -} - -async function startOp (algodClient, symbol, vaddr, fromAddress) { - const pclib = new PricecasterLib.PricecasterLib(algodClient) - console.log('Creating new app...') - const txId = await pclib.createApp(fromAddress, vaddr, symbol, signCallback) - console.log('txId: ' + txId) - const txResponse = await pclib.waitForTransactionResponse(txId) - const appId = pclib.appIdFromCreateAppResponse(txResponse) - console.log('Deployment App Id: %d', appId) -} - -(async () => { - console.log('\nPricekeeper Deployment Tool') - console.log('-----------------------------\n') - - if (process.argv.length !== 6) { - console.log('Usage: deploy \n') - console.log('where:\n') - console.log('symbol The supported symbol for this priceKeeper (e.g BTC/USD)') - console.log('vaddr The validator address') - console.log('from Deployer account') - console.log('network Testnet, betanet or mainnet') - exit(0) - } - - const symbol = process.argv[2] - const vaddr = process.argv[3] - const fromAddress = process.argv[4] - const network = process.argv[5] - - const config = { server: '', apiToken: '', port: '' } - if (network === 'betanet') { - config.server = 'https://api.betanet.algoexplorer.io' - } else if (network === 'mainnet') { - config.server = 'https://api.algoexplorer.io' - } else if (network === 'testnet') { - config.server = 'https://api.testnet.algoexplorer.io' - } else { - console.error('Invalid network: ' + network) - exit(1) - } - - if (!algosdk.isValidAddress(vaddr)) { - console.error('Invalid validator address: ' + vaddr) - exit(1) - } - - if (!algosdk.isValidAddress(fromAddress)) { - console.error('Invalid deployer address: ' + fromAddress) - exit(1) - } - - const algodClient = new algosdk.Algodv2(config.apiToken, config.server, config.port) - - console.log('Parameters for deployment: ') - console.log('symbol: ' + symbol) - console.log('Validator addr: ' + vaddr) - console.log('From: ' + fromAddress) - console.log('Network: ' + network) - const answer = await ask('\nEnter YES to confirm parameters, anything else to abort. ') - if (answer !== 'YES') { - console.warn('Aborted by user.') - exit(1) - } - globalMnemo = await ask('\nEnter mnemonic for sender account.\nBE SURE TO DO THIS FROM A SECURED SYSTEM\n') - await startOp(algodClient, symbol, vaddr, fromAddress) - console.log('Bye.') - exit(0) -})() diff --git a/staging/algorand/tools/gkeys.test b/staging/algorand/tools/gkeys.test deleted file mode 100644 index 63013b3cb..000000000 --- a/staging/algorand/tools/gkeys.test +++ /dev/null @@ -1 +0,0 @@ -13947Bd48b18E53fdAeEe77F3473391aC727C638 \ No newline at end of file diff --git a/staging/algorand/tools/v1.prototxt.testnet b/staging/algorand/tools/v1.prototxt.testnet deleted file mode 100644 index f3ddf7e08..000000000 --- a/staging/algorand/tools/v1.prototxt.testnet +++ /dev/null @@ -1,19 +0,0 @@ -13947Bd48b18E53fdAeEe77F3473391aC727C638 -F18AbBac073741DD0F002147B735Ff642f3D113F -9925A94DC043D0803f8ef502D2dB15cAc9e02D76 -9e4EC2D92af8602bCE74a27F99A836f93C4a31E4 -9C40c4052A3092AfB8C99B985fcDfB586Ed19c98 -B86020cF1262AA4dd5572Af76923E271169a2CA7 -1937617fE1eD801fBa14Bd8BB9EDEcBA7A942FFe -9475b8D45DdE53614d92c779787C27fE2ef68752 -15A53B22c28AbC7B108612146B6aAa4a537bA305 -63842657C7aC7e37B04FBE76b8c54EFe014D04E1 -948ca1bBF4B858DF1A505b4C69c5c61bD95A12Bd -A6923e2259F8B5541eD18e410b8DdEE618337ff0 -F678Daf4b7f2789AA88A081618Aa966D6a39e064 -8cF31021838A8B3fFA43a71a50609877846f9E6d -eB15bCF2ae4f957012330B4741ecE3242De96184 -cc3766a03e4faec44Bda7a46D9Ea2A9D124e9Bf8 -841f499Ba89a6a8E9dD273BAd82Beb175094E5d7 -f5F2b82576e6CA17965dee853d08bbB471FA2433 -2bC2B1204599D4cA0d4Dde4a658a42c4dD13103a diff --git a/staging/algorand/tsconfig.json b/staging/algorand/tsconfig.json deleted file mode 100644 index 6d7a680bf..000000000 --- a/staging/algorand/tsconfig.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "compilerOptions": { - "alwaysStrict": true, - "declaration": true, - "declarationMap": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "forceConsistentCasingInFileNames": true, - "inlineSourceMap": false, - "inlineSources": true, - "esModuleInterop": true, - "baseUrl": ".", - "target": "es2020", - "module": "CommonJS", - "moduleResolution": "node", - "sourceMap": true, - "strict": true, - "importHelpers": false, - "noEmitHelpers": false, - "noEmitOnError": true, - "resolveJsonModule": true, - "removeComments": true, - "outDir": "build", - "types": ["node"], - "lib": [ "ES2020.Promise" ], - }, - "include": [ - "backend/**/*.ts", - ], - "exclude": [ - "build", - "node_modules", - "test", - "**/*.spec.ts" - ] -} diff --git a/terra/tools/deploy.js b/terra/tools/deploy.js index f9eca929e..70497647c 100644 --- a/terra/tools/deploy.js +++ b/terra/tools/deploy.js @@ -246,6 +246,8 @@ const contract_registrations = { process.env.REGISTER_ETH_TOKEN_BRIDGE_VAA, // BSC process.env.REGISTER_BSC_TOKEN_BRIDGE_VAA, + // ALGO + process.env.REGISTER_ALGO_TOKEN_BRIDGE_VAA, ], "nft_bridge.wasm": [ // Solana diff --git a/third_party/algorand/.gitignore b/third_party/algorand/.gitignore deleted file mode 100644 index 1019a8d09..000000000 --- a/third_party/algorand/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Generated -teal diff --git a/third_party/algorand/Dockerfile b/third_party/algorand/Dockerfile deleted file mode 100644 index 3cf802486..000000000 --- a/third_party/algorand/Dockerfile +++ /dev/null @@ -1,27 +0,0 @@ -# syntax=docker/dockerfile:1.2 -FROM docker.io/algorand/stable:3.2.1@sha256:0a87978492680fd98e2cc410f59f2bfd7fef979f035eb060685d56a6e916b5bd - -RUN mkdir -p /setup -ADD template.json /setup/ -ADD setup.sh /setup/ -ADD setup.py /setup/ -ADD teal/vaa-verify.teal /setup/ -ADD teal/vaa-processor-clear.teal /setup/ -ADD teal/vaa-processor-approval.teal /setup/ - -RUN ./goal network create -n sandnet -r /network -t /setup/template.json && echo rawr - -RUN mkdir -p /network/Node/kmd-v0.5 - -ADD token /network/Node/algod.token -ADD token /network/Node/kmd-v0.5/kmd.token -ADD config.json /network/Node/config.json -ADD kmd_config.json /network/Node/kmd-v0.5/kmd_config.json - -ENV ALGORAND_DATA=/network/Node - -ADD Pipfile.lock /setup/ -ADD Pipfile /setup/ -RUN apt-get update -RUN apt-get install -y python3-pip -RUN pip install pipenv diff --git a/third_party/algorand/Pipfile b/third_party/algorand/Pipfile deleted file mode 100644 index 9fcd222c5..000000000 --- a/third_party/algorand/Pipfile +++ /dev/null @@ -1,12 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -py-algorand-sdk = "*" -pyteal = "*" -mypy = "*" -pytest = "*" - -[dev-packages] diff --git a/third_party/algorand/Pipfile.lock b/third_party/algorand/Pipfile.lock deleted file mode 100644 index a2a16f486..000000000 --- a/third_party/algorand/Pipfile.lock +++ /dev/null @@ -1,316 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7d3b87829ef46d00b82e4450cc45b6ca299dc0a5e9bba990744eda1c901d8af4" - }, - "pipfile-spec": 6, - "requires": {}, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "attrs": { - "hashes": [ - "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", - "sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.2.0" - }, - "cffi": { - "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "version": "==1.15.0" - }, - "iniconfig": { - "hashes": [ - "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3", - "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32" - ], - "version": "==1.1.1" - }, - "msgpack": { - "hashes": [ - "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc", - "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147", - "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3", - "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba", - "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39", - "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85", - "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9", - "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a", - "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec", - "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88", - "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e", - "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a", - "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b", - "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1", - "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3", - "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef", - "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079", - "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52", - "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a", - "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a", - "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4", - "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996", - "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73", - "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a", - "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920", - "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7", - "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d", - "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770", - "sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50", - "sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2", - "sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2", - "sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d", - "sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea", - "sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611" - ], - "version": "==1.0.3" - }, - "mypy": { - "hashes": [ - "sha256:13b3c110309b53f5a62aa1b360f598124be33a42563b790a2a9efaacac99f1fc", - "sha256:140174e872d20d4768124a089b9f9fc83abd6a349b7f8cc6276bc344eb598922", - "sha256:31895b0b3060baf15bf76e789d94722c026f673b34b774bba9e8772295edccff", - "sha256:331a81d2c9bf1be25317260a073b41f4584cd11701a7c14facef0aa5a005e843", - "sha256:40cb062f1b7ff4cd6e897a89d8ddc48c6ad7f326b5277c93a8c559564cc1551c", - "sha256:41f3575b20714171c832d8f6c7aaaa0d499c9a2d1b8adaaf837b4c9065c38540", - "sha256:431be889ffc8d9681813a45575c42e341c19467cbfa6dd09bf41467631feb530", - "sha256:562a0e335222d5bbf5162b554c3afe3745b495d67c7fe6f8b0d1b5bace0c1eeb", - "sha256:618e677aabd21f30670bffb39a885a967337f5b112c6fb7c79375e6dced605d6", - "sha256:69b5a835b12fdbfeed84ef31152d41343d32ccb2b345256d8682324409164330", - "sha256:71c77bd885d2ce44900731d4652d0d1c174dc66a0f11200e0c680bdedf1a6b37", - "sha256:82e6c15675264e923b60a11d6eb8f90665504352e68edfbb4a79aac7a04caddd", - "sha256:98b4f91a75fed2e4c6339e9047aba95968d3a7c4b91e92ab9dc62c0c583564f4", - "sha256:993c2e52ea9570e6e872296c046c946377b9f5e89eeb7afea2a1524cf6e50b27", - "sha256:9cd316e9705555ca6a50670ba5fb0084d756d1d8cb1697c83820b1456b0bc5f3", - "sha256:a55438627f5f546192f13255a994d6d1cf2659df48adcf966132b4379fd9c86b", - "sha256:df0fec878ccfcb2d1d2306ba31aa757848f681e7bbed443318d9bbd4b0d0fe9a", - "sha256:e091fe58b4475b3504dc7c3022ff7f4af2f9e9ddf7182047111759ed0973bbde", - "sha256:f8b2059f73878e92eff7ed11a03515d6572f4338a882dd7547b5f7dd242118e6", - "sha256:ffb1e57ec49a30e3c0ebcfdc910ae4aceb7afb649310b7355509df6b15bd75f6" - ], - "index": "pypi", - "version": "==0.920" - }, - "mypy-extensions": { - "hashes": [ - "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d", - "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8" - ], - "version": "==0.4.3" - }, - "packaging": { - "hashes": [ - "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", - "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" - ], - "markers": "python_version >= '3.6'", - "version": "==21.3" - }, - "pluggy": { - "hashes": [ - "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159", - "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3" - ], - "markers": "python_version >= '3.6'", - "version": "==1.0.0" - }, - "py": { - "hashes": [ - "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", - "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.11.0" - }, - "py-algorand-sdk": { - "hashes": [ - "sha256:110480dc5baf2102721a5fe860c22fb445a737dfbb0a2e82ed97fee03b792d19", - "sha256:691771118f88855affbb57853a73113ce0ea554d7b9f1bbe50e309a83a632158" - ], - "index": "pypi", - "version": "==1.8.0" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "version": "==2.21" - }, - "pycryptodomex": { - "hashes": [ - "sha256:08c809e9f4be8d4f9948cf4d5ebc7431bbd9e1c0cd5ff478d0d5229f1bc4ad50", - "sha256:097095a7c24b9e7eec865417f620f78adf218162c03b68e4fde194bf87801a67", - "sha256:0981e8071d2ee457d842821438f833e362eed9a25a445d54ad7610b24293118f", - "sha256:1bd9d158afa33dca04748b23e7b9d4055f8c8015ace2e972a866519af02d5eed", - "sha256:1f6c370abf11546b1c9b70062918d601ac8fb7ff113554601b43175eed7480ef", - "sha256:2595b7be43b8b2da953ea3506a8d71c07fc9b479d5c118b0c44a5eca2a1664f6", - "sha256:2d173a5db4e306cd32558b1a3ceb45bd2ebeb6596525fd5945963798b3851e3d", - "sha256:33c06d6819a0204fac675d100f92aa472c704cd774a47171a5949c75c1040ed6", - "sha256:3559da56e1045ad567e69fcc74245073fe1943b07b137bfd1073c7a540a89df7", - "sha256:3bfa2936f8391bfaa17ed6a5c726e33acad56d7b47b8bf824b1908b16b140025", - "sha256:4361881388817f89aa819a553e987200a6eb664df995632b063997dd373a7cee", - "sha256:43af464dcac1ae53e6e14a0ae6f08373b538f3c49fb9e426423618571edfecff", - "sha256:44097663c62b3aa03b5b403b816dedafa592984e8c6857a061ade41f32a2666e", - "sha256:4cbaea8ab8bfa283e6219af39624d921f72f8174765a35416aab4d4b4dec370e", - "sha256:5b0fd9fc81d43cd54dc8e4b2df8730ffd1e34f1f0679920deae16f6487aa1414", - "sha256:676d9f4286f490612fa35ca8fe4b1fced8ff18e653abc1dda34fbf166129d6c2", - "sha256:79ad48096ceb5c714fbc4dc82e3e6b37f095f627b1fef90d94d85e19a19d6611", - "sha256:83379f1fd7b99c4993f5e905f2a6ddb9003996655151ea3c2ee77332ad009d08", - "sha256:88dc997e3e9199a0d67b547fba36c6d1c54fca7d83c4bfe0d3f34f55a4717a2c", - "sha256:8c5b97953130ff76500c6e8e159f2b881c737ebf00034006517b57f382d5317c", - "sha256:922e9dac0166e4617e5c7980d2cff6912a6eb5cb5c13e7ece222438650bd7f66", - "sha256:9c037aaf6affc8f7c4f6f9f6279aa57dd526734246fb5221a0fff3124f57e0b1", - "sha256:a896b41c518269c1cceb582e298a868e6c74bb3cbfd362865ea686c78aebe91d", - "sha256:b1a6f17c4ad896ed628663b021cd797b098c7e9537fd259958f6ffb3b8921081", - "sha256:b5ddaee74e1f06af9c0765a147904dddacf4ca9707f8f079e14e2b14b4f5a544", - "sha256:d55374ebc36de7a3217f2e2318886f0801dd5e486e21aba1fc4ca08e3b6637d7", - "sha256:ddac6a092b97aa11d2a21aec33e941b4453ef774da3d98f2b7c1e01da05e6d5e", - "sha256:de9832ac3c51484fe1757ca4303695423b16cfa54874dae9239bf41f50a2affa", - "sha256:e42a82c63952ed70be3c13782c6984a519b514e6b10108a9647c7576b6c86650", - "sha256:ea8e83bf4731a2369350d7771a1f2ef8d72ad3da70a37d86b1374be8c675abd0" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==3.12.0" - }, - "pynacl": { - "hashes": [ - "sha256:06cbb4d9b2c4bd3c8dc0d267416aaed79906e7b33f114ddbf0911969794b1cc4", - "sha256:11335f09060af52c97137d4ac54285bcb7df0cef29014a1a4efe64ac065434c4", - "sha256:2fe0fc5a2480361dcaf4e6e7cea00e078fcda07ba45f811b167e3f99e8cff574", - "sha256:30f9b96db44e09b3304f9ea95079b1b7316b2b4f3744fe3aaecccd95d547063d", - "sha256:4e10569f8cbed81cb7526ae137049759d2a8d57726d52c1a000a3ce366779634", - "sha256:511d269ee845037b95c9781aa702f90ccc36036f95d0f31373a6a79bd8242e25", - "sha256:537a7ccbea22905a0ab36ea58577b39d1fa9b1884869d173b5cf111f006f689f", - "sha256:54e9a2c849c742006516ad56a88f5c74bf2ce92c9f67435187c3c5953b346505", - "sha256:757250ddb3bff1eecd7e41e65f7f833a8405fede0194319f87899690624f2122", - "sha256:7757ae33dae81c300487591c68790dfb5145c7d03324000433d9a2c141f82af7", - "sha256:7c6092102219f59ff29788860ccb021e80fffd953920c4a8653889c029b2d420", - "sha256:8122ba5f2a2169ca5da936b2e5a511740ffb73979381b4229d9188f6dcb22f1f", - "sha256:9c4a7ea4fb81536c1b1f5cc44d54a296f96ae78c1ebd2311bd0b60be45a48d96", - "sha256:c914f78da4953b33d4685e3cdc7ce63401247a21425c16a39760e282075ac4a6", - "sha256:cd401ccbc2a249a47a3a1724c2918fcd04be1f7b54eb2a5a71ff915db0ac51c6", - "sha256:d452a6746f0a7e11121e64625109bc4468fc3100452817001dbe018bb8b08514", - "sha256:ea6841bc3a76fa4942ce00f3bda7d436fda21e2d91602b9e21b7ca9ecab8f3ff", - "sha256:f8851ab9041756003119368c1e6cd0b9c631f46d686b3904b18c0139f4419f80" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.4.0" - }, - "pyparsing": { - "hashes": [ - "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4", - "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81" - ], - "markers": "python_version >= '3.6'", - "version": "==3.0.6" - }, - "pyteal": { - "hashes": [ - "sha256:6a7fbb2155ee79e0b6dfbd635e6ac4508a0c2279ddb4203f1c356b47bd684bb6", - "sha256:e395cf30fce630ac26157132ae4e0240845060a858a1a162aeac8b92a286b554" - ], - "index": "pypi", - "version": "==0.9.1" - }, - "pytest": { - "hashes": [ - "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89", - "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134" - ], - "index": "pypi", - "version": "==6.2.5" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "tomli": { - "hashes": [ - "sha256:b5bde28da1fed24b9bd1d4d2b8cba62300bfb4ec9a6187a957e8ddb9434c5224", - "sha256:c292c34f58502a1eb2bbb9f5bbc9a5ebc37bee10ffb8c2d6bbdfa8eb13cc14e1" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "typing-extensions": { - "hashes": [ - "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e", - "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b" - ], - "markers": "python_version >= '3.6'", - "version": "==4.0.1" - } - }, - "develop": {} -} diff --git a/third_party/algorand/config.json b/third_party/algorand/config.json deleted file mode 100644 index 39904bdad..000000000 --- a/third_party/algorand/config.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "Version": 12, - "GossipFanout": 1, - "EndpointAddress": "0.0.0.0:4001", - "DNSBootstrapID": "", - "IncomingConnectionsLimit": 0, - "Archival": false, - "isIndexerActive": false, - "EnableDeveloperAPI": true -} diff --git a/third_party/algorand/kmd_config.json b/third_party/algorand/kmd_config.json deleted file mode 100644 index e640c8f69..000000000 --- a/third_party/algorand/kmd_config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "address": "0.0.0.0:4002", - "allowed_origins": [ - "*" - ] -} diff --git a/third_party/algorand/setup.py b/third_party/algorand/setup.py deleted file mode 100644 index bc9a41faf..000000000 --- a/third_party/algorand/setup.py +++ /dev/null @@ -1,248 +0,0 @@ -from time import time, sleep -from typing import List, Tuple, Dict, Any, Optional, Union -from base64 import b64decode -import base64 -import random -import hashlib - -from algosdk.v2client.algod import AlgodClient -from algosdk.kmd import KMDClient -from algosdk import account, mnemonic -from algosdk.future import transaction -from algosdk.encoding import decode_address -from pyteal import compileTeal, Mode, Expr -from pyteal import * -from algosdk.logic import get_application_address - -import pprint - -# Q5XDfcbiqiBwfMlY3gO1Mb0vyNCO+szD3v9azhrG16iO5Z5aTduNzeut/FLG0NOG0+txrBGN6lhi5iwytgkyKg== - -# position atom discover cluster fiction amused toe siren slam author surround spread garage craft isolate whisper kangaroo kitchen lend toss culture various effort absent kidney - -class Account: - """Represents a private key and address for an Algorand account""" - - def __init__(self, privateKey: str) -> None: - self.sk = privateKey - self.addr = account.address_from_private_key(privateKey) -# print (privateKey + " -> " + self.getMnemonic()) - - def getAddress(self) -> str: - return self.addr - - def getPrivateKey(self) -> str: - return self.sk - - def getMnemonic(self) -> str: - return mnemonic.from_private_key(self.sk) - - @classmethod - def FromMnemonic(cls, m: str) -> "Account": - return cls(mnemonic.to_private_key(m)) - -class PendingTxnResponse: - def __init__(self, response: Dict[str, Any]) -> None: - self.poolError: str = response["pool-error"] - self.txn: Dict[str, Any] = response["txn"] - - self.applicationIndex: Optional[int] = response.get("application-index") - self.assetIndex: Optional[int] = response.get("asset-index") - self.closeRewards: Optional[int] = response.get("close-rewards") - self.closingAmount: Optional[int] = response.get("closing-amount") - self.confirmedRound: Optional[int] = response.get("confirmed-round") - self.globalStateDelta: Optional[Any] = response.get("global-state-delta") - self.localStateDelta: Optional[Any] = response.get("local-state-delta") - self.receiverRewards: Optional[int] = response.get("receiver-rewards") - self.senderRewards: Optional[int] = response.get("sender-rewards") - - self.innerTxns: List[Any] = response.get("inner-txns", []) - self.logs: List[bytes] = [b64decode(l) for l in response.get("logs", [])] - -class Setup: - def __init__(self) -> None: - self.ALGOD_ADDRESS = "http://localhost:4001" - self.ALGOD_TOKEN = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - self.FUNDING_AMOUNT = 100_000_000 - - self.KMD_ADDRESS = "http://localhost:4002" - self.KMD_TOKEN = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - self.KMD_WALLET_NAME = "unencrypted-default-wallet" - self.KMD_WALLET_PASSWORD = "" - - self.TARGET_ACCOUNT = "position atom discover cluster fiction amused toe siren slam author surround spread garage craft isolate whisper kangaroo kitchen lend toss culture various effort absent kidney" - - self.kmdAccounts : Optional[List[Account]] = None - - self.accountList : List[Account] = [] - - self.APPROVAL_PROGRAM = b"" - self.CLEAR_STATE_PROGRAM = b"" - - def waitForTransaction( - self, client: AlgodClient, txID: str, timeout: int = 10 - ) -> PendingTxnResponse: - lastStatus = client.status() - lastRound = lastStatus["last-round"] - startRound = lastRound - - while lastRound < startRound + timeout: - pending_txn = client.pending_transaction_info(txID) - - if pending_txn.get("confirmed-round", 0) > 0: - return PendingTxnResponse(pending_txn) - - if pending_txn["pool-error"]: - raise Exception("Pool error: {}".format(pending_txn["pool-error"])) - - lastStatus = client.status_after_block(lastRound + 1) - - lastRound += 1 - - raise Exception( - "Transaction {} not confirmed after {} rounds".format(txID, timeout) - ) - - def getKmdClient(self) -> KMDClient: - return KMDClient(self.KMD_TOKEN, self.KMD_ADDRESS) - - def getGenesisAccounts(self) -> List[Account]: - if self.kmdAccounts is None: - kmd = self.getKmdClient() - - wallets = kmd.list_wallets() - walletID = None - for wallet in wallets: - if wallet["name"] == self.KMD_WALLET_NAME: - walletID = wallet["id"] - break - - if walletID is None: - raise Exception("Wallet not found: {}".format(self.KMD_WALLET_NAME)) - - walletHandle = kmd.init_wallet_handle(walletID, self.KMD_WALLET_PASSWORD) - - try: - addresses = kmd.list_keys(walletHandle) - privateKeys = [ - kmd.export_key(walletHandle, self.KMD_WALLET_PASSWORD, addr) - for addr in addresses - ] - self.kmdAccounts = [Account(sk) for sk in privateKeys] - finally: - kmd.release_wallet_handle(walletHandle) - - return self.kmdAccounts - - def getTargetAccount(self) -> Account: - return Account.FromMnemonic(self.TARGET_ACCOUNT) - - def fundTargetAccount(self, client: AlgodClient, target: Account): - print("fundTargetAccount") - genesisAccounts = self.getGenesisAccounts() - suggestedParams = client.suggested_params() - - for fundingAccount in genesisAccounts: - txn = transaction.PaymentTxn( - sender=fundingAccount.getAddress(), - receiver=target.getAddress(), - amt=self.FUNDING_AMOUNT, - sp=suggestedParams, - ) - pprint.pprint(txn) - print("signing txn") - stxn = txn.sign(fundingAccount.getPrivateKey()) - print("sending txn") - client.send_transaction(stxn) - print("waiting for txn") - self.waitForTransaction(client, stxn.get_txid()) - - def getAlgodClient(self) -> AlgodClient: - return AlgodClient(self.ALGOD_TOKEN, self.ALGOD_ADDRESS) - - def getBalances(self, client: AlgodClient, account: str) -> Dict[int, int]: - balances: Dict[int, int] = dict() - - accountInfo = client.account_info(account) - - # set key 0 to Algo balance - balances[0] = accountInfo["amount"] - - assets: List[Dict[str, Any]] = accountInfo.get("assets", []) - for assetHolding in assets: - assetID = assetHolding["asset-id"] - amount = assetHolding["amount"] - balances[assetID] = amount - - return balances - - def setup(self): - self.client = self.getAlgodClient() - - self.target = self.getTargetAccount() - - b = self.getBalances(self.client, self.target.getAddress()) - if (b[0] < 100000000): - print("Account needs money... funding it") - self.fundTargetAccount(self.client, self.target) - print(self.getBalances(self.client, self.target.getAddress())) - - - def deploy(self): - vaa_processor_approval = self.client.compile(open("vaa-processor-approval.teal", "r").read()) - vaa_processor_clear = self.client.compile(open("vaa-processor-clear.teal", "r").read()) - vaa_verify = self.client.compile(open("vaa-verify.teal", "r").read()) - verify_hash = vaa_verify['hash'] - print("verify_hash " + verify_hash + " " + str(len(decode_address(verify_hash)))) - - globalSchema = transaction.StateSchema(num_uints=4, num_byte_slices=20) - localSchema = transaction.StateSchema(num_uints=0, num_byte_slices=0) - - app_args = [ "beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe", 0, 0 ] - - txn = transaction.ApplicationCreateTxn( - sender=self.target.getAddress(), - on_complete=transaction.OnComplete.NoOpOC, - approval_program=b64decode(vaa_processor_approval["result"]), - clear_program=b64decode(vaa_processor_clear["result"]), - global_schema=globalSchema, - local_schema=localSchema, - app_args=app_args, - sp=self.client.suggested_params(), - ) - - signedTxn = txn.sign(self.target.getPrivateKey()) - self.client.send_transaction(signedTxn) - response = self.waitForTransaction(self.client, signedTxn.get_txid()) - assert response.applicationIndex is not None and response.applicationIndex > 0 - print("app_id: ", response.applicationIndex) - - appAddr = get_application_address(response.applicationIndex) - suggestedParams = self.client.suggested_params() - appCallTxn = transaction.ApplicationCallTxn( - sender=self.target.getAddress(), - index=response.applicationIndex, - on_complete=transaction.OnComplete.NoOpOC, - app_args=[b"setvphash", decode_address(verify_hash)], - sp=suggestedParams, - ) - - signedAppCallTxn = appCallTxn.sign(self.target.getPrivateKey()) - self.client.send_transactions([signedAppCallTxn]) - response = self.waitForTransaction(self.client, appCallTxn.get_txid()) - print("set the vp hash to the stateless contract") - - appCallTxn = transaction.PaymentTxn( - sender=self.target.getAddress(), - receiver=verify_hash, - amt=500000, - sp=suggestedParams, - ) - signedAppCallTxn = appCallTxn.sign(self.target.getPrivateKey()) - self.client.send_transactions([signedAppCallTxn]) - response = self.waitForTransaction(self.client, appCallTxn.get_txid()) - print("funded the stateless contract") - -s = Setup() -s.setup() -s.deploy() diff --git a/third_party/algorand/setup.sh b/third_party/algorand/setup.sh deleted file mode 100755 index d854a2122..000000000 --- a/third_party/algorand/setup.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -dn="$(dirname "$0")" -cd $dn - -pipenv install -pipenv run python3 setup.py diff --git a/third_party/algorand/template.json b/third_party/algorand/template.json deleted file mode 100644 index 52533731b..000000000 --- a/third_party/algorand/template.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "Genesis": { - "NetworkName": "", - "Wallets": [ - { - "Name": "Wallet1", - "Stake": 10, - "Online": true - }, - { - "Name": "Wallet2", - "Stake": 40, - "Online": true - }, - { - "Name": "Wallet3", - "Stake": 40, - "Online": false - }, - { - "Name": "Wallet4", - "Stake": 10, - "Online": false - } - ] - }, - "Nodes": [ - { - "Name": "Primary", - "IsRelay": true, - "Wallets": [ - { - "Name": "Wallet1", - "ParticipationOnly": false - } - ] - }, - { - "Name": "Node", - "Wallets": [ - { - "Name": "Wallet2", - "ParticipationOnly": false - }, - { - "Name": "Wallet3", - "ParticipationOnly": false - }, - { - "Name": "Wallet4", - "ParticipationOnly": false - } - ] - } - ] -}