Reimplement terra bridge in guardian software
Change-Id: Ic57d0ae91355d2415f13657f463e8929212b1c97
This commit is contained in:
parent
d9fde6d7cc
commit
0004dd6c2a
|
@ -6,3 +6,4 @@ node_modules
|
|||
bin
|
||||
target
|
||||
/mutagen.sh
|
||||
venv
|
|
@ -79,7 +79,7 @@ const (
|
|||
TerraTokenAddress = "terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5"
|
||||
|
||||
// Terra bridge contract address
|
||||
TerraBridgeAddress = "terra174kgn5rtw4kf6f938wm7kwh70h2v4vcfd26jlc"
|
||||
TerraBridgeAddress = "terra18eezxhys9jwku67cm4w84xhnzt4xjj77w2qt62"
|
||||
|
||||
// Terra devnet fee payer mnemonic
|
||||
TerraFeePayerKey = "notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius"
|
||||
|
|
|
@ -176,7 +176,7 @@ func (e *BridgeWatcher) Run(ctx context.Context) error {
|
|||
sender := gjson.Get(json, "result.events.from_contract\\.message\\.sender.0")
|
||||
chainId := gjson.Get(json, "result.events.from_contract\\.message\\.chain_id.0")
|
||||
nonce := gjson.Get(json, "result.events.from_contract\\.message\\.nonce.0")
|
||||
sequence := gjson.Get(json, "result.events.from_contract\\.message.sequence.0")
|
||||
sequence := gjson.Get(json, "result.events.from_contract\\.message\\.sequence.0")
|
||||
blockTime := gjson.Get(json, "result.events.from_contract\\.message\\.block_time.0")
|
||||
txHash := gjson.Get(json, "result.events.tx\\.hash.0")
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ spec:
|
|||
- --terraChainID
|
||||
- localterra
|
||||
- --terraContract
|
||||
- terra174kgn5rtw4kf6f938wm7kwh70h2v4vcfd26jlc
|
||||
- terra18eezxhys9jwku67cm4w84xhnzt4xjj77w2qt62
|
||||
- --terraKey
|
||||
- /tmp/terra.key
|
||||
- --agentRPC
|
||||
|
|
|
@ -7,9 +7,9 @@ ADD contracts /code/contracts
|
|||
RUN optimize_workspace.sh
|
||||
|
||||
# Contract deployment stage
|
||||
FROM node:14@sha256:04a33dac55af8d3170bffc91ca31fe8000b96ae1bab1a090deb920ca2ca2a38e
|
||||
FROM python:slim-buster@sha256:ec7a755e6313da2f7db02d8e82f6b0813b176f06c5622174c8ab45feefc8096d
|
||||
|
||||
RUN npm update && npm i -g typescript ts-node
|
||||
RUN apt update && apt install netcat curl jq -y
|
||||
|
||||
WORKDIR /app/tools
|
||||
|
||||
|
@ -19,8 +19,6 @@ ADD ./tools /app/tools
|
|||
|
||||
RUN chmod +x /app/tools/deploy.sh
|
||||
|
||||
RUN npm install
|
||||
|
||||
RUN ts-node --version
|
||||
RUN pip install -r /app/tools/requirements.txt
|
||||
|
||||
ENTRYPOINT /app/tools/deploy.sh
|
||||
|
|
314
terra/deploy.py
314
terra/deploy.py
|
@ -1,314 +0,0 @@
|
|||
from terra_sdk.client.localterra import AsyncLocalTerra
|
||||
from terra_sdk.core.auth import StdFee
|
||||
import asyncio
|
||||
from terra_sdk.core.wasm import (
|
||||
MsgStoreCode,
|
||||
MsgInstantiateContract,
|
||||
MsgExecuteContract,
|
||||
MsgMigrateContract,
|
||||
)
|
||||
from terra_sdk.util.contract import get_code_id, get_contract_address, read_file_as_b64
|
||||
import os
|
||||
import base64
|
||||
import pprint
|
||||
|
||||
|
||||
lt = AsyncLocalTerra(gas_prices={"uusd": "0.15"})
|
||||
terra = lt
|
||||
deployer = lt.wallets["test1"]
|
||||
|
||||
sequence = asyncio.get_event_loop().run_until_complete(deployer.sequence())
|
||||
|
||||
|
||||
async def sign_and_broadcast(*msgs):
|
||||
|
||||
global sequence
|
||||
try:
|
||||
tx = await deployer.create_and_sign_tx(
|
||||
msgs=msgs, fee=StdFee(30000000, "20000000uusd"), sequence=sequence
|
||||
)
|
||||
result = await terra.tx.broadcast(tx)
|
||||
sequence += 1
|
||||
if result.is_tx_error():
|
||||
raise Exception(result.raw_log)
|
||||
return result
|
||||
except:
|
||||
sequence = await deployer.sequence()
|
||||
raise
|
||||
|
||||
|
||||
async def store_contract(contract_name):
|
||||
parent_dir = os.path.dirname(__file__)
|
||||
contract_bytes = read_file_as_b64(f"{parent_dir}/artifacts/{contract_name}.wasm")
|
||||
store_code = MsgStoreCode(deployer.key.acc_address, contract_bytes)
|
||||
|
||||
result = await sign_and_broadcast(store_code)
|
||||
code_id = get_code_id(result)
|
||||
print(f"Code id for {contract_name} is {code_id}")
|
||||
return code_id
|
||||
|
||||
|
||||
async def store_contracts():
|
||||
|
||||
parent_dir = os.path.dirname(__file__)
|
||||
contract_names = [
|
||||
i[:-5] for i in os.listdir(f"{parent_dir}/artifacts") if i.endswith(".wasm")
|
||||
]
|
||||
|
||||
return {
|
||||
contract_name: await store_contract(contract_name)
|
||||
for contract_name in contract_names
|
||||
}
|
||||
|
||||
|
||||
class ContractQuerier:
|
||||
def __init__(self, address):
|
||||
self.address = address
|
||||
|
||||
def __getattr__(self, item):
|
||||
async def result_fxn(**kwargs):
|
||||
kwargs = convert_contracts_to_addr(kwargs)
|
||||
return await terra.wasm.contract_query(self.address, {item: kwargs})
|
||||
|
||||
return result_fxn
|
||||
|
||||
|
||||
class Contract:
|
||||
@staticmethod
|
||||
async def create(code_id, migratable=False, **kwargs):
|
||||
kwargs = convert_contracts_to_addr(kwargs)
|
||||
instantiate = MsgInstantiateContract(
|
||||
deployer.key.acc_address, code_id, kwargs, migratable=migratable
|
||||
)
|
||||
result = await sign_and_broadcast(instantiate)
|
||||
return Contract(get_contract_address(result))
|
||||
|
||||
def __init__(self, address):
|
||||
self.address = address
|
||||
|
||||
def __getattr__(self, item):
|
||||
async def result_fxn(coins=None, **kwargs):
|
||||
kwargs = convert_contracts_to_addr(kwargs)
|
||||
execute = MsgExecuteContract(
|
||||
deployer.key.acc_address, self.address, {item: kwargs}, coins=coins
|
||||
)
|
||||
return await sign_and_broadcast(execute)
|
||||
|
||||
return result_fxn
|
||||
|
||||
@property
|
||||
def query(self):
|
||||
return ContractQuerier(self.address)
|
||||
|
||||
async def migrate(self, new_code_id):
|
||||
migrate = MsgMigrateContract(
|
||||
contract=self.address,
|
||||
migrate_msg={},
|
||||
new_code_id=new_code_id,
|
||||
owner=deployer.key.acc_address,
|
||||
)
|
||||
return await sign_and_broadcast(migrate)
|
||||
|
||||
|
||||
def convert_contracts_to_addr(obj):
|
||||
if type(obj) == dict:
|
||||
return {k: convert_contracts_to_addr(v) for k, v in obj.items()}
|
||||
if type(obj) in {list, tuple}:
|
||||
return [convert_contracts_to_addr(i) for i in obj]
|
||||
if type(obj) == Contract:
|
||||
return obj.address
|
||||
return obj
|
||||
|
||||
|
||||
def to_bytes(n, length, byteorder="big"):
|
||||
return int(n).to_bytes(length, byteorder=byteorder)
|
||||
|
||||
|
||||
def assemble_vaa(emitter_chain, emitter_address, payload):
|
||||
import time
|
||||
|
||||
# version, guardian set index, len signatures
|
||||
header = to_bytes(1, 1) + to_bytes(0, 4) + to_bytes(0, 1)
|
||||
# timestamp, nonce, emitter_chain
|
||||
body = to_bytes(time.time(), 8) + to_bytes(1, 4) + to_bytes(emitter_chain, 2)
|
||||
# emitter_address, vaa payload
|
||||
body += emitter_address + payload
|
||||
|
||||
return header + body
|
||||
|
||||
|
||||
async def main():
|
||||
code_ids = await store_contracts()
|
||||
print(code_ids)
|
||||
|
||||
# fake governance contract on solana
|
||||
GOV_CHAIN = 1
|
||||
GOV_ADDRESS = b"0" * 32
|
||||
|
||||
wormhole = await Contract.create(
|
||||
code_id=code_ids["wormhole"],
|
||||
gov_chain=GOV_CHAIN,
|
||||
gov_address=base64.b64encode(GOV_ADDRESS).decode("utf-8"),
|
||||
guardian_set_expirity=10 ** 15,
|
||||
initial_guardian_set={"addresses": [], "expiration_time": 10 ** 15},
|
||||
migratable=True,
|
||||
)
|
||||
|
||||
# TODO:
|
||||
# resp = await wormhole.migrate(code_ids["wormhole"])
|
||||
# for event in resp.logs:
|
||||
# pprint.pprint(event.events_by_type)
|
||||
|
||||
token_bridge = await Contract.create(
|
||||
code_id=code_ids["token_bridge"],
|
||||
gov_chain=GOV_CHAIN,
|
||||
gov_address=base64.b64encode(GOV_ADDRESS).decode("utf-8"),
|
||||
wormhole_contract=wormhole,
|
||||
wrapped_asset_code_id=int(code_ids["cw20_wrapped"]),
|
||||
)
|
||||
|
||||
mock_token = await Contract.create(
|
||||
code_id=code_ids["cw20_base"],
|
||||
name="MOCK",
|
||||
symbol="MCK",
|
||||
decimals=6,
|
||||
initial_balances=[{"address": deployer.key.acc_address, "amount": "100000000"}],
|
||||
mint=None,
|
||||
)
|
||||
|
||||
raw_addr = deployer.key.raw_address
|
||||
recipient = b"\0" * 12 + raw_addr
|
||||
recipient = base64.b64encode(recipient)
|
||||
|
||||
print(
|
||||
"Balance before initiate transfer",
|
||||
await mock_token.query.balance(address=deployer.key.acc_address),
|
||||
)
|
||||
|
||||
await mock_token.increase_allowance(spender=token_bridge, amount="1000")
|
||||
bridge_canonical = bytes.fromhex(
|
||||
(await wormhole.query.query_address_hex(address=token_bridge))["hex"]
|
||||
)
|
||||
|
||||
# fake a VAA from the gov contract
|
||||
module = b"token_bridge"
|
||||
module += b" " * (32 - len(module))
|
||||
chain = to_bytes(0, 2)
|
||||
action = to_bytes(0, 1)
|
||||
# chain_id chain_address (pretend there's a bridge w/ the same address on solana)
|
||||
payload = to_bytes(3, 2) + bridge_canonical
|
||||
|
||||
vaa = assemble_vaa(GOV_CHAIN, GOV_ADDRESS, module + chain + action + payload)
|
||||
|
||||
# register the chain
|
||||
await token_bridge.submit_vaa(data=base64.b64encode(vaa).decode("utf-8"))
|
||||
|
||||
resp = await token_bridge.initiate_transfer(
|
||||
asset=mock_token,
|
||||
amount="1000",
|
||||
recipient_chain=3,
|
||||
recipient=recipient.decode("utf-8"),
|
||||
nonce=0,
|
||||
coins={"uluna": "10000"},
|
||||
)
|
||||
|
||||
print(
|
||||
"Balance after initiate transfer",
|
||||
await mock_token.query.balance(address=deployer.key.acc_address),
|
||||
)
|
||||
|
||||
logs = resp.logs[0].events_by_type
|
||||
transfer_data = {
|
||||
k: v[0] for k, v in logs["from_contract"].items() if k.startswith("message")
|
||||
}
|
||||
vaa = assemble_vaa(
|
||||
transfer_data["message.chain_id"],
|
||||
bytes.fromhex(transfer_data["message.sender"]),
|
||||
bytes.fromhex(transfer_data["message.message"]),
|
||||
)
|
||||
|
||||
await token_bridge.submit_vaa(data=base64.b64encode(vaa).decode("utf-8"))
|
||||
|
||||
print(
|
||||
"Balance after complete transfer",
|
||||
await mock_token.query.balance(address=deployer.key.acc_address),
|
||||
)
|
||||
|
||||
# pretend there exists another bridge contract with the same address but on solana
|
||||
# fake a VAA from the gov contract
|
||||
module = b"token_bridge"
|
||||
module += b" " * (32 - len(module))
|
||||
chain = to_bytes(0, 2)
|
||||
action = to_bytes(0, 1)
|
||||
# chain_id chain_address (pretend there's a bridge w/ the same address on solana)
|
||||
payload = to_bytes(1, 2) + bridge_canonical
|
||||
|
||||
vaa = assemble_vaa(GOV_CHAIN, GOV_ADDRESS, module + chain + action + payload)
|
||||
|
||||
# register the chain
|
||||
await token_bridge.submit_vaa(data=base64.b64encode(vaa).decode("utf-8"))
|
||||
|
||||
resp = await token_bridge.create_asset_meta(
|
||||
asset_address=mock_token,
|
||||
nonce=1,
|
||||
coins={"uluna": "10000"},
|
||||
)
|
||||
|
||||
logs = resp.logs[0].events_by_type
|
||||
create_meta_data = {
|
||||
k: v[0] for k, v in logs["from_contract"].items() if k.startswith("message")
|
||||
}
|
||||
message_bytes = bytes.fromhex(create_meta_data["message.message"])
|
||||
|
||||
# switch the chain of the asset meta to say its from solana
|
||||
message_bytes = message_bytes[:1] + to_bytes(1, 2) + message_bytes[3:]
|
||||
vaa = assemble_vaa(
|
||||
1, # totally came from solana
|
||||
bytes.fromhex(create_meta_data["message.sender"]),
|
||||
message_bytes,
|
||||
)
|
||||
|
||||
# attest this metadata and make a wrapped asset from solana
|
||||
resp = await token_bridge.submit_vaa(data=base64.b64encode(vaa).decode("utf-8"))
|
||||
|
||||
wrapped_token = Contract(get_contract_address(resp))
|
||||
|
||||
# now send from solana...
|
||||
message_bytes = bytes.fromhex(transfer_data["message.message"])
|
||||
message_bytes = message_bytes[:1] + to_bytes(1, 2) + message_bytes[3:]
|
||||
|
||||
vaa = assemble_vaa(
|
||||
1, # totally came from solana
|
||||
bytes.fromhex(transfer_data["message.sender"]),
|
||||
message_bytes,
|
||||
)
|
||||
print(
|
||||
"Balance before completing transfer from solana",
|
||||
await wrapped_token.query.balance(address=deployer.key.acc_address),
|
||||
)
|
||||
|
||||
await token_bridge.submit_vaa(data=base64.b64encode(vaa).decode("utf-8"))
|
||||
|
||||
print(
|
||||
"Balance after completing transfer from solana",
|
||||
await wrapped_token.query.balance(address=deployer.key.acc_address),
|
||||
)
|
||||
|
||||
await wrapped_token.increase_allowance(spender=token_bridge, amount="1000")
|
||||
resp = await token_bridge.initiate_transfer(
|
||||
asset=wrapped_token,
|
||||
amount="1000",
|
||||
recipient_chain=1,
|
||||
recipient=recipient.decode("utf-8"),
|
||||
nonce=0,
|
||||
coins={"uluna": "10000"},
|
||||
)
|
||||
|
||||
print(
|
||||
"Balance after completing transfer to solana",
|
||||
await wrapped_token.query.balance(address=deployer.key.acc_address),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
|
@ -0,0 +1,160 @@
|
|||
from terra_sdk.client.localterra import AsyncLocalTerra
|
||||
from terra_sdk.core.auth import StdFee
|
||||
import asyncio
|
||||
from terra_sdk.core.wasm import (
|
||||
MsgStoreCode,
|
||||
MsgInstantiateContract,
|
||||
MsgExecuteContract,
|
||||
MsgMigrateContract,
|
||||
)
|
||||
from terra_sdk.util.contract import get_code_id, get_contract_address, read_file_as_b64
|
||||
import os
|
||||
import base64
|
||||
import pprint
|
||||
|
||||
lt = AsyncLocalTerra(gas_prices={"uusd": "0.15"}, url="http://terra-lcd:1317")
|
||||
terra = lt
|
||||
deployer = lt.wallets["test1"]
|
||||
|
||||
sequence = asyncio.get_event_loop().run_until_complete(deployer.sequence())
|
||||
|
||||
|
||||
async def sign_and_broadcast(*msgs):
|
||||
global sequence
|
||||
try:
|
||||
tx = await deployer.create_and_sign_tx(
|
||||
msgs=msgs, fee=StdFee(30000000, "20000000uusd"), sequence=sequence
|
||||
)
|
||||
result = await terra.tx.broadcast(tx)
|
||||
sequence += 1
|
||||
if result.is_tx_error():
|
||||
raise Exception(result.raw_log)
|
||||
return result
|
||||
except:
|
||||
sequence = await deployer.sequence()
|
||||
raise
|
||||
|
||||
|
||||
async def store_contract(contract_name):
|
||||
parent_dir = os.path.dirname(__file__)
|
||||
contract_bytes = read_file_as_b64(f"{parent_dir}/../artifacts/{contract_name}.wasm")
|
||||
store_code = MsgStoreCode(deployer.key.acc_address, contract_bytes)
|
||||
|
||||
result = await sign_and_broadcast(store_code)
|
||||
code_id = get_code_id(result)
|
||||
print(f"Code id for {contract_name} is {code_id}")
|
||||
return code_id
|
||||
|
||||
|
||||
async def store_contracts():
|
||||
parent_dir = os.path.dirname(__file__)
|
||||
contract_names = [
|
||||
i[:-5] for i in os.listdir(f"{parent_dir}/../artifacts") if i.endswith(".wasm")
|
||||
]
|
||||
|
||||
return {
|
||||
contract_name: await store_contract(contract_name)
|
||||
for contract_name in contract_names
|
||||
}
|
||||
|
||||
|
||||
class ContractQuerier:
|
||||
def __init__(self, address):
|
||||
self.address = address
|
||||
|
||||
def __getattr__(self, item):
|
||||
async def result_fxn(**kwargs):
|
||||
kwargs = convert_contracts_to_addr(kwargs)
|
||||
return await terra.wasm.contract_query(self.address, {item: kwargs})
|
||||
|
||||
return result_fxn
|
||||
|
||||
|
||||
class Contract:
|
||||
@staticmethod
|
||||
async def create(code_id, migratable=False, **kwargs):
|
||||
kwargs = convert_contracts_to_addr(kwargs)
|
||||
instantiate = MsgInstantiateContract(
|
||||
deployer.key.acc_address, code_id, kwargs, migratable=migratable
|
||||
)
|
||||
result = await sign_and_broadcast(instantiate)
|
||||
return Contract(get_contract_address(result))
|
||||
|
||||
def __init__(self, address):
|
||||
self.address = address
|
||||
|
||||
def __getattr__(self, item):
|
||||
async def result_fxn(coins=None, **kwargs):
|
||||
kwargs = convert_contracts_to_addr(kwargs)
|
||||
execute = MsgExecuteContract(
|
||||
deployer.key.acc_address, self.address, {item: kwargs}, coins=coins
|
||||
)
|
||||
return await sign_and_broadcast(execute)
|
||||
|
||||
return result_fxn
|
||||
|
||||
@property
|
||||
def query(self):
|
||||
return ContractQuerier(self.address)
|
||||
|
||||
async def migrate(self, new_code_id):
|
||||
migrate = MsgMigrateContract(
|
||||
contract=self.address,
|
||||
migrate_msg={},
|
||||
new_code_id=new_code_id,
|
||||
owner=deployer.key.acc_address,
|
||||
)
|
||||
return await sign_and_broadcast(migrate)
|
||||
|
||||
|
||||
def convert_contracts_to_addr(obj):
|
||||
if type(obj) == dict:
|
||||
return {k: convert_contracts_to_addr(v) for k, v in obj.items()}
|
||||
if type(obj) in {list, tuple}:
|
||||
return [convert_contracts_to_addr(i) for i in obj]
|
||||
if type(obj) == Contract:
|
||||
return obj.address
|
||||
return obj
|
||||
|
||||
|
||||
def to_bytes(n, length, byteorder="big"):
|
||||
return int(n).to_bytes(length, byteorder=byteorder)
|
||||
|
||||
|
||||
def assemble_vaa(emitter_chain, emitter_address, payload):
|
||||
import time
|
||||
|
||||
# version, guardian set index, len signatures
|
||||
header = to_bytes(1, 1) + to_bytes(0, 4) + to_bytes(0, 1)
|
||||
# timestamp, nonce, emitter_chain
|
||||
body = to_bytes(time.time(), 8) + to_bytes(1, 4) + to_bytes(emitter_chain, 2)
|
||||
# emitter_address, vaa payload
|
||||
body += emitter_address + payload
|
||||
|
||||
return header + body
|
||||
|
||||
|
||||
async def main():
|
||||
code_ids = await store_contracts()
|
||||
print(code_ids)
|
||||
|
||||
# fake governance contract on solana
|
||||
GOV_CHAIN = 1
|
||||
GOV_ADDRESS = b"0" * 32
|
||||
|
||||
wormhole = await Contract.create(
|
||||
code_id=code_ids["wormhole"],
|
||||
gov_chain=GOV_CHAIN,
|
||||
gov_address=base64.b64encode(GOV_ADDRESS).decode("utf-8"),
|
||||
guardian_set_expirity=10 ** 15,
|
||||
initial_guardian_set={
|
||||
"addresses": [{"bytes": base64.b64encode(
|
||||
bytearray.fromhex("beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe")).decode("utf-8")}],
|
||||
"expiration_time": 0},
|
||||
migratable=True,
|
||||
)
|
||||
print("Wormhole contract: {}".format(wormhole.address))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.get_event_loop().run_until_complete(main())
|
|
@ -1,5 +1,14 @@
|
|||
npm run prepare-token http://terra-lcd:1317
|
||||
npm run prepare-wormhole http://terra-lcd:1317
|
||||
npm run lock-token terra18vd8fpwxzck93qlwghaj6arh4p7c5n896xzem5 terra174kgn5rtw4kf6f938wm7kwh70h2v4vcfd26jlc 1000 http://terra-lcd:1317
|
||||
# Wait for node to start
|
||||
while ! /bin/netcat -z localhost 26657; do
|
||||
sleep 1
|
||||
done
|
||||
# Wait for first block
|
||||
while [ $(curl localhost:26657/status -ks | jq ".result.sync_info.latest_block_height|tonumber") -lt 1 ]; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
sleep 2
|
||||
|
||||
python deploy.py
|
||||
echo "Going to sleep, interrupt if running manually"
|
||||
sleep infinity
|
|
@ -1,26 +0,0 @@
|
|||
import { init_lcd, execute_contract, execute_contract_with_fee, query_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
if (process.argv.length < 5) {
|
||||
console.log('Required 3 params TOKEN_CONTRACT, WORMHOLE_CONTRACT, integer AMOUNT');
|
||||
}
|
||||
let token_contract = process.argv[2];
|
||||
let wormhole_contract = process.argv[3];
|
||||
let amount = process.argv[4];
|
||||
|
||||
let allowanceResult = await execute_contract(token_contract, {increase_allowance: {spender: wormhole_contract, amount}});
|
||||
if (allowanceResult == null) return;
|
||||
console.log('Allowance increased');
|
||||
let lockResult = await execute_contract_with_fee(wormhole_contract, {lock_assets: {
|
||||
asset: token_contract,
|
||||
amount,
|
||||
recipient: Buffer.from('00000000000000000000000019a4437E2BA06bF1FA42C56Fb269Ca0d30f60716', 'hex').toString('base64'),
|
||||
target_chain: 2, // Ethereum
|
||||
nonce: Date.now() % 1000000
|
||||
}});
|
||||
if (lockResult == null) return;
|
||||
console.log('Tokens locked');
|
||||
}
|
||||
|
||||
init_lcd(process.argv[5]);
|
||||
script();
|
|
@ -1,494 +0,0 @@
|
|||
{
|
||||
"name": "terra-contract-tools",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@terra-money/terra.js": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@terra-money/terra.js/-/terra.js-0.5.12.tgz",
|
||||
"integrity": "sha512-3UZWMT3Tu+MOQrHZ8uEtHL+hurKbe1QVm8x+qWOe4+IOeY3eWdVeBIkHflhGI8NU31v/r5eznbTuy7kEMA4CMQ==",
|
||||
"requires": {
|
||||
"axios": "^0.20.0",
|
||||
"bech32": "^1.1.4",
|
||||
"bip32": "^2.0.6",
|
||||
"bip39": "^3.0.2",
|
||||
"bufferutil": "^4.0.1",
|
||||
"crypto-js": "3.3.0",
|
||||
"decimal.js": "^10.2.1",
|
||||
"post-message-stream": "^3.0.0",
|
||||
"secp256k1": "^4.0.2",
|
||||
"utf-8-validate": "^5.0.2",
|
||||
"ws": "^7.3.1"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "14.14.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.6.tgz",
|
||||
"integrity": "sha512-6QlRuqsQ/Ox/aJEQWBEJG7A9+u7oSYl3mem/K8IzxXG/kAGbV1YPD9Bg9Zw3vyxC/YP+zONKwy8hGkSt1jxFMw=="
|
||||
},
|
||||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.20.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz",
|
||||
"integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"base-x": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz",
|
||||
"integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"bech32": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
||||
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
|
||||
},
|
||||
"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.2",
|
||||
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz",
|
||||
"integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==",
|
||||
"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=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"bn.js": {
|
||||
"version": "4.11.9",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
|
||||
"integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw=="
|
||||
},
|
||||
"brorand": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
|
||||
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
|
||||
},
|
||||
"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-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
},
|
||||
"bufferutil": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.2.tgz",
|
||||
"integrity": "sha512-AtnG3W6M8B2n4xDQ5R+70EXvOpnXsFYg/AK2yTZd+HQ/oxAdz+GI+DvjmhBw3L0ole+LJ0ngqY4JMbDzkfNzhA==",
|
||||
"requires": {
|
||||
"node-gyp-build": "^4.2.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"
|
||||
}
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"crypto-js": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
|
||||
"integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
|
||||
},
|
||||
"decimal.js": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz",
|
||||
"integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw=="
|
||||
},
|
||||
"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.3",
|
||||
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
|
||||
"integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
|
||||
"requires": {
|
||||
"bn.js": "^4.4.0",
|
||||
"brorand": "^1.0.1",
|
||||
"hash.js": "^1.0.0",
|
||||
"hmac-drbg": "^1.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"minimalistic-assert": "^1.0.0",
|
||||
"minimalistic-crypto-utils": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
|
||||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
|
||||
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
|
||||
},
|
||||
"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.2.3",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
|
||||
"integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg=="
|
||||
},
|
||||
"pbkdf2": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
|
||||
"integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"post-message-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/post-message-stream/-/post-message-stream-3.0.0.tgz",
|
||||
"integrity": "sha1-kNn1S9IJ5rb110eVuHWIIFtUcEg=",
|
||||
"requires": {
|
||||
"readable-stream": "^2.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.19",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
|
||||
"integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.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"
|
||||
}
|
||||
},
|
||||
"tiny-secp256k1": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.5.tgz",
|
||||
"integrity": "sha512-duE2hSLSQIpHGzmK48OgRrGTi+4OTkXLC6aa86uOYQ6LLCYZSarVKIAvEtY7MoXjoL6bOXMSerEGMzrvW4SkDw==",
|
||||
"requires": {
|
||||
"bindings": "^1.3.0",
|
||||
"bn.js": "^4.11.8",
|
||||
"create-hmac": "^1.1.7",
|
||||
"elliptic": "^6.4.0",
|
||||
"nan": "^2.13.2"
|
||||
}
|
||||
},
|
||||
"ts-node": {
|
||||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
|
||||
"integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"source-map-support": "^0.5.17",
|
||||
"yn": "3.1.1"
|
||||
}
|
||||
},
|
||||
"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.1.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.2.tgz",
|
||||
"integrity": "sha512-thGloWsGH3SOxv1SoY7QojKi0tc+8FnOmiarEGMbd/lar7QOEd3hvlx3Fp5y6FlDUGl9L+pd4n2e+oToGMmhRQ=="
|
||||
},
|
||||
"utf-8-validate": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.3.tgz",
|
||||
"integrity": "sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A==",
|
||||
"requires": {
|
||||
"node-gyp-build": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"wif": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
|
||||
"integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=",
|
||||
"requires": {
|
||||
"bs58check": "<3.0.0"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
|
||||
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA=="
|
||||
},
|
||||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "terra-contract-tools",
|
||||
"version": "1.0.0",
|
||||
"description": "Tools to build and deploy Terra contracts",
|
||||
"repository": "https://github.com/certusone/wormhole",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build-contracts": "( cd .. && docker run --rm -v \"$(pwd)\":/code --mount type=volume,source=\"$(basename \"$(pwd)\")_cache\",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/workspace-optimizer:0.10.4 )",
|
||||
"prepare-token": "ts-node prepare-token.ts",
|
||||
"prepare-wormhole": "ts-node prepare-wormhole.ts",
|
||||
"lock-token": "ts-node lock-token.ts",
|
||||
"submit-vaa": "ts-node submit-vaa.ts"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@terra-money/terra.js": "^0.5.12",
|
||||
"@types/node": "^14.14.6",
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^4.1.2"
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
import { init_lcd, deploy_contract, instantiate_contract, query_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
const TEST_ADDRESS: string = 'terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v';
|
||||
// cw20_base.wasm is a binary artifact built from https://github.com/CosmWasm/cosmwasm-plus repository at v0.2.0
|
||||
// and is a standard base cw20 contract. Is it used for testing only.
|
||||
let code_id = await deploy_contract('../artifacts/cw20_base.wasm');
|
||||
if (code_id == -1) return;
|
||||
console.log(`Program deployed with code id ${code_id}`);
|
||||
let contract_address = await instantiate_contract(code_id, {
|
||||
name: 'Test token',
|
||||
symbol: 'TST',
|
||||
decimals: 8,
|
||||
initial_balances: [{
|
||||
address: TEST_ADDRESS,
|
||||
amount: '100000000000000',
|
||||
}],
|
||||
mint: null,
|
||||
});
|
||||
console.log(`Contract instance created at ${contract_address}`);
|
||||
|
||||
// Verify if token was minted to the test address
|
||||
let result = await query_contract(contract_address, {balance: { address : TEST_ADDRESS}});
|
||||
console.log(`${TEST_ADDRESS} balance is ${result.balance}`);
|
||||
}
|
||||
|
||||
init_lcd(process.argv[2]);
|
||||
script();
|
|
@ -1,27 +0,0 @@
|
|||
import { init_lcd, deploy_contract, instantiate_contract, query_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
// Deploy cw20-wrapped
|
||||
let wrapped_code_id = await deploy_contract('../artifacts/cw20_wrapped.wasm');
|
||||
if (wrapped_code_id == -1) return;
|
||||
console.log(`CW20 Wrapped program deployed with code id ${wrapped_code_id}`);
|
||||
// Deploy wormhole
|
||||
let wormhole_code_id = await deploy_contract('../artifacts/wormhole.wasm');
|
||||
if (wormhole_code_id == -1) return;
|
||||
console.log(`Wormhole program deployed with code id ${wormhole_code_id}`);
|
||||
// Instantiate wormhole
|
||||
let contract_address = await instantiate_contract(wormhole_code_id, {
|
||||
initial_guardian_set: {
|
||||
addresses: [
|
||||
{ bytes: Buffer.from('beFA429d57cD18b7F8A4d91A2da9AB4AF05d0FBe', 'hex').toString('base64') }
|
||||
],
|
||||
expiration_time: Math.floor(Date.now() / 1000) + 1000 * 60 * 60
|
||||
},
|
||||
guardian_set_expirity: 0,
|
||||
wrapped_asset_code_id: wrapped_code_id,
|
||||
});
|
||||
console.log(`Wormhole instance created at ${contract_address}`);
|
||||
}
|
||||
|
||||
init_lcd(process.argv[2]);
|
||||
script();
|
|
@ -0,0 +1 @@
|
|||
terra_sdk==0.14.0
|
|
@ -1,18 +0,0 @@
|
|||
import { init_lcd, execute_contract } from './utils';
|
||||
|
||||
async function script() {
|
||||
if (process.argv.length < 3) {
|
||||
console.log('Required 1 param WORMHOLE_CONTRACT');
|
||||
}
|
||||
let wormhole_contract = process.argv[2];
|
||||
|
||||
// Test VAA built using bridge/cmd/vaa-test
|
||||
let vaaResult = await execute_contract(wormhole_contract, {submit_v_a_a: {
|
||||
vaa: Buffer.from('010000000001001063f503dd308134e0f158537f54c5799719f4fa2687dd276c72ef60ae0c82c47d4fb560545afaabdf60c15918e221763fd1892c75f2098c0ffd5db4af254a4501000007d01000000038010302010400000000000000000000000000000000000000000000000000000000000101010101010101010101010101010101010101000000000000000000000000010000000000000000000000000347ef34687bdc9f189e87a9200658d9c40e9988080000000000000000000000000000000000000000000000000de0b6b3a7640000', 'hex').toString('base64')
|
||||
}});
|
||||
if (vaaResult == null) return;
|
||||
console.log('Vaa submitted');
|
||||
}
|
||||
|
||||
init_lcd(process.argv[3]);
|
||||
script();
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"esModuleInterop": true,
|
||||
"target": "es2017",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"outDir": "dist"
|
||||
},
|
||||
"lib": ["es2017"]
|
||||
}
|
|
@ -1,154 +0,0 @@
|
|||
import { LCDClient, MsgStoreCode, MsgInstantiateContract, MsgExecuteContract, MnemonicKey, isTxError } from '@terra-money/terra.js';
|
||||
import * as fs from 'fs';
|
||||
|
||||
// test1 key from localterra accounts
|
||||
const mk = new MnemonicKey({
|
||||
mnemonic: 'notice oak worry limit wrap speak medal online prefer cluster roof addict wrist behave treat actual wasp year salad speed social layer crew genius'
|
||||
})
|
||||
|
||||
let terra: LCDClient;
|
||||
let wallet;
|
||||
|
||||
export function init_lcd(host_name='http://localhost:1317') {
|
||||
// connect to localterra
|
||||
terra = new LCDClient({
|
||||
URL: host_name,
|
||||
chainID: 'localterra'
|
||||
});
|
||||
wallet = terra.wallet(mk);
|
||||
}
|
||||
|
||||
function delay(ms: number) {
|
||||
return new Promise( resolve => setTimeout(resolve, ms) );
|
||||
}
|
||||
|
||||
export async function deploy_contract(wasm_file) : Promise<number> {
|
||||
|
||||
const storeCode = new MsgStoreCode(
|
||||
wallet.key.accAddress,
|
||||
fs.readFileSync(wasm_file).toString('base64')
|
||||
);
|
||||
let first_attempt = true;
|
||||
for (;;) {
|
||||
try {
|
||||
const storeCodeTx = await wallet.createAndSignTx({
|
||||
msgs: [storeCode],
|
||||
});
|
||||
const storeCodeTxResult = await terra.tx.broadcast(storeCodeTx);
|
||||
|
||||
//console.log(storeCodeTxResult);
|
||||
|
||||
if (isTxError(storeCodeTxResult)) {
|
||||
throw new Error(
|
||||
`store code failed. code: ${storeCodeTxResult.code}, codespace: ${storeCodeTxResult.codespace}, raw_log: ${storeCodeTxResult.raw_log}`
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
store_code: { code_id },
|
||||
} = storeCodeTxResult.logs[0].eventsByType;
|
||||
|
||||
return parseInt(code_id[0], 10);
|
||||
} catch (err) {
|
||||
// Only show error from the second time it shows to avoid spamming errors while initialization not yet finished
|
||||
if (!first_attempt) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
}
|
||||
first_attempt = false;
|
||||
await delay(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function instantiate_contract(code_id: number, initMsg: object) : Promise<string> {
|
||||
try {
|
||||
const instantiate = new MsgInstantiateContract(
|
||||
wallet.key.accAddress,
|
||||
code_id,
|
||||
initMsg,
|
||||
{},
|
||||
false
|
||||
);
|
||||
|
||||
const instantiateTx = await wallet.createAndSignTx({
|
||||
msgs: [instantiate],
|
||||
});
|
||||
const instantiateTxResult = await terra.tx.broadcast(instantiateTx);
|
||||
|
||||
if (isTxError(instantiateTxResult)) {
|
||||
throw new Error(
|
||||
`instantiate failed. code: ${instantiateTxResult.code}, codespace: ${instantiateTxResult.codespace}, raw_log: ${instantiateTxResult.raw_log}`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
instantiate_contract: { contract_address },
|
||||
} = instantiateTxResult.logs[0].eventsByType;
|
||||
|
||||
return contract_address[0];
|
||||
|
||||
} catch (err) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function execute_contract(contract_address: string, msg: object) : Promise<any> {
|
||||
try {
|
||||
const execute = new MsgExecuteContract(
|
||||
wallet.key.accAddress,
|
||||
contract_address,
|
||||
{ ...msg }, { }
|
||||
);
|
||||
|
||||
const executeTx = await wallet.createAndSignTx({
|
||||
msgs: [execute]
|
||||
});
|
||||
|
||||
const result = await terra.tx.broadcast(executeTx);
|
||||
return result;
|
||||
} catch (err) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function execute_contract_with_fee(contract_address: string, msg: object) : Promise<any> {
|
||||
try {
|
||||
const execute = new MsgExecuteContract(
|
||||
wallet.key.accAddress,
|
||||
contract_address,
|
||||
{ ...msg }, { uluna: 10000 }
|
||||
);
|
||||
|
||||
const executeTx = await wallet.createAndSignTx({
|
||||
msgs: [execute]
|
||||
});
|
||||
|
||||
const result = await terra.tx.broadcast(executeTx);
|
||||
return result;
|
||||
} catch (err) {
|
||||
console.log(`Error ${err}`);
|
||||
if (err.response) {
|
||||
console.log(err.response.data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function query_contract(contract_address: string, query: object) : Promise<any> {
|
||||
const result = await terra.wasm.contractQuery(
|
||||
contract_address, query
|
||||
);
|
||||
return result;
|
||||
}
|
Loading…
Reference in New Issue