bridge_ui: eth wrapped assets and getSignedVAA
Change-Id: I1beaeefb7863c0543e180ed2e15e91c645b89299
This commit is contained in:
parent
3aecf65f4d
commit
5187120fa0
|
@ -9,6 +9,7 @@
|
|||
"version": "0.1.0",
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@improbable-eng/grpc-web": "^0.13.0",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@metamask/detect-provider": "^1.2.0",
|
||||
"@project-serum/sol-wallet-adapter": "^0.2.5",
|
||||
|
@ -4011,8 +4012,6 @@
|
|||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.13.0.tgz",
|
||||
"integrity": "sha512-vaxxT+Qwb7GPqDQrBV4vAAfH0HywgOLw6xGIKXd9Q8hcV63CQhmS3p4+pZ9/wVvt4Ph3ZDK9fdC983b9aGMUFg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"browser-headers": "^0.4.0"
|
||||
},
|
||||
|
@ -10309,9 +10308,7 @@
|
|||
"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==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg=="
|
||||
},
|
||||
"node_modules/browser-process-hrtime": {
|
||||
"version": "1.0.0",
|
||||
|
@ -17417,9 +17414,7 @@
|
|||
"node_modules/google-protobuf": {
|
||||
"version": "3.17.3",
|
||||
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.17.3.tgz",
|
||||
"integrity": "sha512-OVPzcSWIAJ+d5yiHyeaLrdufQtrvaBrF4JQg+z8ynTkbO3uFcujqXszTumqg1cGsAsjkWnI+M5B1xZ19yR4Wyg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-OVPzcSWIAJ+d5yiHyeaLrdufQtrvaBrF4JQg+z8ynTkbO3uFcujqXszTumqg1cGsAsjkWnI+M5B1xZ19yR4Wyg=="
|
||||
},
|
||||
"node_modules/got": {
|
||||
"version": "9.6.0",
|
||||
|
@ -41493,8 +41488,6 @@
|
|||
"version": "0.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@improbable-eng/grpc-web/-/grpc-web-0.13.0.tgz",
|
||||
"integrity": "sha512-vaxxT+Qwb7GPqDQrBV4vAAfH0HywgOLw6xGIKXd9Q8hcV63CQhmS3p4+pZ9/wVvt4Ph3ZDK9fdC983b9aGMUFg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"browser-headers": "^0.4.0"
|
||||
}
|
||||
|
@ -46695,9 +46688,7 @@
|
|||
"browser-headers": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-headers/-/browser-headers-0.4.1.tgz",
|
||||
"integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-CA9hsySZVo9371qEHjHZtYxV2cFtVj5Wj/ZHi8ooEsrtm4vOnl9Y9HmyYWk9q+05d7K3rdoAE0j3MVEFVvtQtg=="
|
||||
},
|
||||
"browser-process-hrtime": {
|
||||
"version": "1.0.0",
|
||||
|
@ -52508,9 +52499,7 @@
|
|||
"google-protobuf": {
|
||||
"version": "3.17.3",
|
||||
"resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.17.3.tgz",
|
||||
"integrity": "sha512-OVPzcSWIAJ+d5yiHyeaLrdufQtrvaBrF4JQg+z8ynTkbO3uFcujqXszTumqg1cGsAsjkWnI+M5B1xZ19yR4Wyg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"integrity": "sha512-OVPzcSWIAJ+d5yiHyeaLrdufQtrvaBrF4JQg+z8ynTkbO3uFcujqXszTumqg1cGsAsjkWnI+M5B1xZ19yR4Wyg=="
|
||||
},
|
||||
"got": {
|
||||
"version": "9.6.0",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@improbable-eng/grpc-web": "^0.13.0",
|
||||
"@material-ui/core": "^4.12.2",
|
||||
"@metamask/detect-provider": "^1.2.0",
|
||||
"@project-serum/sol-wallet-adapter": "^0.2.5",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
Button,
|
||||
CircularProgress,
|
||||
Grid,
|
||||
makeStyles,
|
||||
MenuItem,
|
||||
|
@ -11,6 +12,7 @@ import { useEthereumProvider } from "../contexts/EthereumProviderContext";
|
|||
import { useSolanaWallet } from "../contexts/SolanaWalletContext";
|
||||
import useEthereumBalance from "../hooks/useEthereumBalance";
|
||||
import useSolanaBalance from "../hooks/useSolanaBalance";
|
||||
import useWrappedAsset from "../hooks/useWrappedAsset";
|
||||
import {
|
||||
ChainId,
|
||||
CHAINS,
|
||||
|
@ -105,8 +107,18 @@ function Transfer() {
|
|||
decimals: solDecimals,
|
||||
uiAmount: solBalance,
|
||||
} = useSolanaBalance(assetAddress, solPK, fromChain === CHAIN_ID_SOLANA);
|
||||
const { isLoading: isCheckingWrapped, wrappedAsset } = useWrappedAsset(
|
||||
toChain,
|
||||
fromChain,
|
||||
assetAddress,
|
||||
provider
|
||||
);
|
||||
console.log(isCheckingWrapped, wrappedAsset);
|
||||
// TODO: make a helper function for this
|
||||
const isWrapped = true;
|
||||
//wrappedAsset && wrappedAsset !== ethers.constants.AddressZero;
|
||||
// TODO: dynamically get "to" wallet
|
||||
const handleClick = useCallback(() => {
|
||||
const handleTransferClick = useCallback(() => {
|
||||
// TODO: more generic way of calling these
|
||||
if (transferFrom[fromChain]) {
|
||||
if (
|
||||
|
@ -210,39 +222,77 @@ function Transfer() {
|
|||
value={assetAddress}
|
||||
onChange={handleAssetChange}
|
||||
/>
|
||||
<TextField
|
||||
placeholder="Amount"
|
||||
type="number"
|
||||
fullWidth
|
||||
className={classes.transferField}
|
||||
value={amount}
|
||||
onChange={handleAmountChange}
|
||||
/>
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className={classes.transferButton}
|
||||
onClick={handleClick}
|
||||
disabled={!canAttemptTransfer}
|
||||
>
|
||||
Transfer
|
||||
</Button>
|
||||
{canAttemptTransfer ? null : (
|
||||
<Typography variant="body2" color="error">
|
||||
{!isTransferImplemented
|
||||
? `Transfer is not yet implemented for ${CHAINS_BY_ID[fromChain].name}`
|
||||
: !isProviderConnected
|
||||
? "The source wallet is not connected"
|
||||
: !isRecipientAvailable
|
||||
? "The receiving wallet is not connected"
|
||||
: !isAddressDefined
|
||||
? "Please provide an asset address"
|
||||
: !isAmountPositive
|
||||
? "The amount must be positive"
|
||||
: !isBalanceAtLeastAmount
|
||||
? "The amount may not be greater than the balance"
|
||||
: ""}
|
||||
</Typography>
|
||||
{isWrapped ? (
|
||||
<>
|
||||
<TextField
|
||||
placeholder="Amount"
|
||||
type="number"
|
||||
fullWidth
|
||||
className={classes.transferField}
|
||||
value={amount}
|
||||
onChange={handleAmountChange}
|
||||
/>
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
className={classes.transferButton}
|
||||
onClick={handleTransferClick}
|
||||
disabled={!canAttemptTransfer}
|
||||
>
|
||||
Transfer
|
||||
</Button>
|
||||
{canAttemptTransfer ? null : (
|
||||
<Typography variant="body2" color="error">
|
||||
{!isTransferImplemented
|
||||
? `Transfer is not yet implemented for ${CHAINS_BY_ID[fromChain].name}`
|
||||
: !isProviderConnected
|
||||
? "The source wallet is not connected"
|
||||
: !isRecipientAvailable
|
||||
? "The receiving wallet is not connected"
|
||||
: !isAddressDefined
|
||||
? "Please provide an asset address"
|
||||
: !isAmountPositive
|
||||
? "The amount must be positive"
|
||||
: !isBalanceAtLeastAmount
|
||||
? "The amount may not be greater than the balance"
|
||||
: ""}
|
||||
</Typography>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div style={{ position: "relative" }}>
|
||||
<Button
|
||||
color="primary"
|
||||
variant="contained"
|
||||
disabled={isCheckingWrapped}
|
||||
className={classes.transferButton}
|
||||
>
|
||||
Attest
|
||||
</Button>
|
||||
{isCheckingWrapped ? (
|
||||
<CircularProgress
|
||||
size={24}
|
||||
color="inherit"
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: "50%",
|
||||
marginLeft: -12,
|
||||
marginBottom: 6,
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
{isCheckingWrapped ? null : (
|
||||
<Typography variant="body2">
|
||||
<br />
|
||||
This token does not exist on {CHAINS_BY_ID[toChain].name}. Someone
|
||||
must attest the the token to the target chain before it can be
|
||||
transferred.
|
||||
</Typography>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -20,12 +20,10 @@ function useEthereumBalance(
|
|||
token
|
||||
.decimals()
|
||||
.then((decimals) => {
|
||||
console.log(decimals);
|
||||
provider
|
||||
?.getSigner()
|
||||
.getAddress()
|
||||
.then((pk) => {
|
||||
console.log(pk);
|
||||
token.balanceOf(pk).then((n) => {
|
||||
if (!cancelled) {
|
||||
setBalance(formatUnits(n, decimals));
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
import { ethers } from "ethers";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ChainId, CHAIN_ID_ETH } from "../utils/consts";
|
||||
import { wrappedAssetEth } from "../utils/wrappedAsset";
|
||||
|
||||
export interface WrappedAssetState {
|
||||
isLoading: boolean;
|
||||
wrappedAsset: string | null;
|
||||
}
|
||||
|
||||
function useWrappedAsset(
|
||||
checkChain: ChainId,
|
||||
originChain: ChainId,
|
||||
originAsset: string,
|
||||
provider: ethers.providers.Web3Provider | undefined
|
||||
) {
|
||||
const [state, setState] = useState<WrappedAssetState>({
|
||||
isLoading: false,
|
||||
wrappedAsset: null,
|
||||
});
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
(async () => {
|
||||
if (provider && checkChain === CHAIN_ID_ETH) {
|
||||
setState({ isLoading: true, wrappedAsset: null });
|
||||
const asset = await wrappedAssetEth(provider, originChain, originAsset);
|
||||
if (!cancelled) {
|
||||
setState({ isLoading: false, wrappedAsset: asset });
|
||||
}
|
||||
} else {
|
||||
setState({ isLoading: false, wrappedAsset: null });
|
||||
}
|
||||
})();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [checkChain, originChain, originAsset, provider]);
|
||||
return state;
|
||||
}
|
||||
|
||||
export default useWrappedAsset;
|
|
@ -8,7 +8,7 @@ export const theme = responsiveFontSizes(
|
|||
default: "#010114",
|
||||
paper: "#010114",
|
||||
},
|
||||
divider: "#FFFFFF",
|
||||
divider: "#4e4e54",
|
||||
primary: {
|
||||
main: "#0074FF",
|
||||
},
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
import {
|
||||
GrpcWebImpl,
|
||||
PublicrpcClientImpl,
|
||||
} from "../proto/publicrpc/v1/publicrpc";
|
||||
import { ChainId } from "../utils/consts";
|
||||
|
||||
export async function getSignedVAA(
|
||||
emitterChain: ChainId,
|
||||
emitterAddress: string,
|
||||
sequence: string
|
||||
) {
|
||||
const rpc = new GrpcWebImpl("http://localhost:8080", {});
|
||||
const api = new PublicrpcClientImpl(rpc);
|
||||
// TODO: potential infinite loop, support cancellation?
|
||||
let result;
|
||||
while (!result) {
|
||||
console.log("wait 1 second");
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
console.log("check for signed vaa", emitterChain, emitterAddress, sequence);
|
||||
try {
|
||||
result = await api.GetSignedVAA({
|
||||
messageId: {
|
||||
emitterChain,
|
||||
emitterAddress,
|
||||
sequence,
|
||||
},
|
||||
});
|
||||
console.log(result);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
import { getAddress } from "ethers/lib/utils";
|
||||
|
||||
export type ChainId = 1 | 2 | 3 | 4;
|
||||
export const CHAIN_ID_SOLANA: ChainId = 1;
|
||||
export const CHAIN_ID_ETH: ChainId = 2;
|
||||
|
@ -31,10 +33,15 @@ export const CHAINS_BY_ID: ChainsById = CHAINS.reduce((obj, chain) => {
|
|||
return obj;
|
||||
}, {} as ChainsById);
|
||||
export const SOLANA_HOST = "http://localhost:8899";
|
||||
export const ETH_TEST_TOKEN_ADDRESS =
|
||||
"0x0290FB167208Af455bB137780163b7B7a9a10C16";
|
||||
export const ETH_TOKEN_BRIDGE_ADDRESS =
|
||||
"0xe982e462b094850f12af94d21d470e21be9d0e9c";
|
||||
export const ETH_TEST_TOKEN_ADDRESS = getAddress(
|
||||
"0x0290FB167208Af455bB137780163b7B7a9a10C16"
|
||||
);
|
||||
export const ETH_BRIDGE_ADDRESS = getAddress(
|
||||
"0x254dffcd3277c0b1660f6d42efbb754edababc2b"
|
||||
);
|
||||
export const ETH_TOKEN_BRIDGE_ADDRESS = getAddress(
|
||||
"0xe982e462b094850f12af94d21d470e21be9d0e9c"
|
||||
);
|
||||
export const SOL_TEST_TOKEN_ADDRESS =
|
||||
"2WDq7wSs9zYrpx2kbHDA4RUTRch2CCTP6ZWaH4GNfnQQ";
|
||||
export const SOL_BRIDGE_ADDRESS = "Bridge1p5gheXUvJ6jGWGeCsgPKgnE3YgdGKRVCMY9o";
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Wallet from "@project-serum/sol-wallet-adapter";
|
||||
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import {
|
||||
AccountMeta,
|
||||
Connection,
|
||||
|
@ -7,17 +8,19 @@ import {
|
|||
Transaction,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js";
|
||||
import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { ethers } from "ethers";
|
||||
import { arrayify, formatUnits, parseUnits, zeroPad } from "ethers/lib/utils";
|
||||
import {
|
||||
Bridge__factory,
|
||||
Implementation__factory,
|
||||
TokenImplementation__factory,
|
||||
} from "../ethers-contracts";
|
||||
import { getSignedVAA } from "../sdk";
|
||||
import {
|
||||
ChainId,
|
||||
CHAIN_ID_ETH,
|
||||
CHAIN_ID_SOLANA,
|
||||
ETH_BRIDGE_ADDRESS,
|
||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||
SOLANA_HOST,
|
||||
SOL_BRIDGE_ADDRESS,
|
||||
|
@ -41,46 +44,60 @@ export function transferFromEth(
|
|||
//TODO: don't hardcode, fetch decimals / share them with balance, how do we determine recipient chain?
|
||||
//TODO: more catches
|
||||
const amountParsed = parseUnits(amount, 18);
|
||||
signer.getAddress().then((signerAddress) => {
|
||||
(async () => {
|
||||
const signerAddress = await signer.getAddress();
|
||||
console.log("Signer:", signerAddress);
|
||||
console.log("Token:", tokenAddress);
|
||||
const token = TokenImplementation__factory.connect(tokenAddress, signer);
|
||||
token
|
||||
.allowance(signerAddress, ETH_TOKEN_BRIDGE_ADDRESS)
|
||||
.then((allowance) => {
|
||||
console.log("Allowance", allowance.toString()); //TODO: should we check that this is zero and warn if it isn't?
|
||||
token
|
||||
.approve(ETH_TOKEN_BRIDGE_ADDRESS, amountParsed)
|
||||
.then((transaction) => {
|
||||
console.log(transaction);
|
||||
const fee = 0; // for now, this won't do anything, we may add later
|
||||
const nonceConst = Math.random() * 100000;
|
||||
const nonceBuffer = Buffer.alloc(4);
|
||||
nonceBuffer.writeUInt32LE(nonceConst, 0);
|
||||
console.log("Initiating transfer");
|
||||
console.log("Amount:", formatUnits(amountParsed, 18));
|
||||
console.log("To chain:", recipientChain);
|
||||
console.log("To address:", recipientAddress);
|
||||
console.log("Fees:", fee);
|
||||
console.log("Nonce:", nonceBuffer);
|
||||
const bridge = Bridge__factory.connect(
|
||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||
signer
|
||||
);
|
||||
bridge
|
||||
.transferTokens(
|
||||
tokenAddress,
|
||||
amountParsed,
|
||||
recipientChain,
|
||||
recipientAddress,
|
||||
fee,
|
||||
nonceBuffer
|
||||
)
|
||||
.then((v) => console.log("Success:", v))
|
||||
.catch((r) => console.error(r)); //TODO: integrate toast messages
|
||||
});
|
||||
});
|
||||
});
|
||||
const allowance = await token.allowance(
|
||||
signerAddress,
|
||||
ETH_TOKEN_BRIDGE_ADDRESS
|
||||
);
|
||||
console.log("Allowance", allowance.toString()); //TODO: should we check that this is zero and warn if it isn't?
|
||||
const transaction = await token.approve(
|
||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||
amountParsed
|
||||
);
|
||||
console.log(transaction);
|
||||
const fee = 0; // for now, this won't do anything, we may add later
|
||||
const nonceConst = Math.random() * 100000;
|
||||
const nonceBuffer = Buffer.alloc(4);
|
||||
nonceBuffer.writeUInt32LE(nonceConst, 0);
|
||||
console.log("Initiating transfer");
|
||||
console.log("Amount:", formatUnits(amountParsed, 18));
|
||||
console.log("To chain:", recipientChain);
|
||||
console.log("To address:", recipientAddress);
|
||||
console.log("Fees:", fee);
|
||||
console.log("Nonce:", nonceBuffer);
|
||||
const bridge = Bridge__factory.connect(ETH_TOKEN_BRIDGE_ADDRESS, signer);
|
||||
const v = await bridge.transferTokens(
|
||||
tokenAddress,
|
||||
amountParsed,
|
||||
recipientChain,
|
||||
recipientAddress,
|
||||
fee,
|
||||
nonceBuffer
|
||||
);
|
||||
const receipt = await v.wait();
|
||||
// TODO: dangerous!(?)
|
||||
const bridgeLog = receipt.logs.filter((l) => {
|
||||
console.log(l.address, ETH_BRIDGE_ADDRESS);
|
||||
return l.address === ETH_BRIDGE_ADDRESS;
|
||||
})[0];
|
||||
const {
|
||||
args: { sender, sequence },
|
||||
} = Implementation__factory.createInterface().parseLog(bridgeLog);
|
||||
console.log(sender, sequence);
|
||||
const emitterAddress = Buffer.from(
|
||||
zeroPad(arrayify(ETH_TOKEN_BRIDGE_ADDRESS), 32)
|
||||
).toString("hex");
|
||||
const { vaaBytes } = await getSignedVAA(
|
||||
CHAIN_ID_ETH,
|
||||
emitterAddress,
|
||||
sequence
|
||||
);
|
||||
console.log("SIGNED VAA:", vaaBytes);
|
||||
})();
|
||||
}
|
||||
|
||||
// TODO: should we share this with client? ooh, should client use the SDK ;)
|
||||
|
@ -201,8 +218,8 @@ export function transferFromSolana(
|
|||
console.log("SIGNED", signed);
|
||||
const txid = await connection.sendRawTransaction(signed.serialize());
|
||||
console.log("SENT", txid);
|
||||
await connection.confirmTransaction(txid);
|
||||
console.log("CONFIRMED");
|
||||
const conf = await connection.confirmTransaction(txid);
|
||||
console.log("CONFIRMED", conf);
|
||||
})();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
import { PublicKey } from "@solana/web3.js";
|
||||
import { ethers } from "ethers";
|
||||
import { arrayify, zeroPad } from "ethers/lib/utils";
|
||||
import { Bridge__factory } from "../ethers-contracts";
|
||||
import { ChainId, CHAIN_ID_SOLANA, ETH_TOKEN_BRIDGE_ADDRESS } from "./consts";
|
||||
|
||||
export function wrappedAssetEth(
|
||||
provider: ethers.providers.Web3Provider,
|
||||
originChain: ChainId,
|
||||
originAsset: string
|
||||
) {
|
||||
const tokenBridge = Bridge__factory.connect(
|
||||
ETH_TOKEN_BRIDGE_ADDRESS,
|
||||
provider
|
||||
);
|
||||
// TODO: address conversion may be more complex than this
|
||||
const originAssetBytes = zeroPad(
|
||||
originChain === CHAIN_ID_SOLANA
|
||||
? new PublicKey(originAsset).toBytes()
|
||||
: arrayify(originAsset),
|
||||
32
|
||||
);
|
||||
return tokenBridge.wrappedAsset(originChain, originAssetBytes);
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"downlevelIteration": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
|
|
|
@ -19,4 +19,4 @@ plugins:
|
|||
- env=browser
|
||||
- forceLong=string
|
||||
- outputClientImpl=grpc-web
|
||||
- explorer/src/proto
|
||||
- bridge_ui/src/proto
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"": {
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"ts-proto": "^1.81.1"
|
||||
"ts-proto": "^1.82.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@protobufjs/aspromise": {
|
||||
|
@ -175,9 +175,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/ts-proto": {
|
||||
"version": "1.82.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.82.0.tgz",
|
||||
"integrity": "sha512-vo4QN4QhR0D4/+C/pSbRIVSV6U7dooNcuyW3SL9DvhKRQA4lnAbF5QBs77ge3JRi+aSZJm8MlzTNk7+e++fvvQ==",
|
||||
"version": "1.82.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.82.3.tgz",
|
||||
"integrity": "sha512-ODveOXK2imsgTiqkBcJu9mIOklmCTSzs7Xu+mT8Xljwh3Wenhax7bhty+x2eO4J7AfNkikXH0Xs7K3lk3UT8VA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/object-hash": "^1.3.0",
|
||||
|
@ -354,9 +354,9 @@
|
|||
}
|
||||
},
|
||||
"ts-proto": {
|
||||
"version": "1.82.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.82.0.tgz",
|
||||
"integrity": "sha512-vo4QN4QhR0D4/+C/pSbRIVSV6U7dooNcuyW3SL9DvhKRQA4lnAbF5QBs77ge3JRi+aSZJm8MlzTNk7+e++fvvQ==",
|
||||
"version": "1.82.3",
|
||||
"resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-1.82.3.tgz",
|
||||
"integrity": "sha512-ODveOXK2imsgTiqkBcJu9mIOklmCTSzs7Xu+mT8Xljwh3Wenhax7bhty+x2eO4J7AfNkikXH0Xs7K3lk3UT8VA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/object-hash": "^1.3.0",
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
"version": "1.0.0",
|
||||
"description": "tooling for building web code from protobufs",
|
||||
"devDependencies": {
|
||||
"ts-proto": "^1.81.1"
|
||||
},
|
||||
"dependencies": {}
|
||||
"ts-proto": "^1.82.3"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue