Use signTypedData in poll init (#10)
This commit is contained in:
parent
dd9079554e
commit
f6203b783f
|
@ -30,6 +30,7 @@
|
|||
"typescript": "^4.3.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"eth-sig-util": "^3.0.1",
|
||||
"ethers": "^5.4.4",
|
||||
"js-waku": "^0.10.0",
|
||||
"protons": "^2.0.1"
|
||||
|
|
|
@ -52,12 +52,14 @@ class WakuVoting {
|
|||
endTime?: number
|
||||
) {
|
||||
const pollInit = await PollInitMsg.create(signer, question, answers, pollType, minToken, endTime)
|
||||
const payload = PollInit.encode(pollInit)
|
||||
if (payload && pollInit) {
|
||||
const wakuMessage = await WakuMessage.fromBytes(payload, this.pollInitTopic, {
|
||||
timestamp: new Date(pollInit.timestamp),
|
||||
})
|
||||
await this.waku?.relay.send(wakuMessage)
|
||||
if (pollInit) {
|
||||
const payload = PollInit.encode(pollInit)
|
||||
if (payload) {
|
||||
const wakuMessage = await WakuMessage.fromBytes(payload, this.pollInitTopic, {
|
||||
timestamp: new Date(pollInit.timestamp),
|
||||
})
|
||||
await this.waku?.relay.send(wakuMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,58 @@
|
|||
import { PollType } from '../types/PollType'
|
||||
import { BigNumber, utils } from 'ethers'
|
||||
import { BigNumber, utils, Wallet } from 'ethers'
|
||||
import { JsonRpcSigner } from '@ethersproject/providers'
|
||||
import { PollInit } from 'protons'
|
||||
import { Wallet } from 'ethers'
|
||||
|
||||
type Message = {
|
||||
owner: string
|
||||
timestamp: number
|
||||
question: string
|
||||
answers: string[]
|
||||
pollType: PollType
|
||||
endTime: number
|
||||
minToken: BigNumber | undefined
|
||||
}
|
||||
|
||||
export function createSignMsgParams(message: Message) {
|
||||
const msgParams: any = {
|
||||
domain: {
|
||||
name: 'Waku polling',
|
||||
version: '1',
|
||||
},
|
||||
message: {
|
||||
owner: message.owner,
|
||||
timestamp: new Date(message.timestamp).toLocaleDateString(),
|
||||
question: message.question,
|
||||
answers: message.answers,
|
||||
pollType: message.pollType === PollType.WEIGHTED ? 'Weighted' : 'Non weighted',
|
||||
endTime: new Date(message.endTime).toLocaleDateString(),
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'owner', type: 'address' },
|
||||
{ name: 'timestamp', type: 'string' },
|
||||
{ name: 'question', type: 'string' },
|
||||
{ name: 'answers', type: 'string[]' },
|
||||
{ name: 'pollType', type: 'string' },
|
||||
{ name: 'endTime', type: 'string' },
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
if (message.pollType === PollType.NON_WEIGHTED) {
|
||||
if (message.minToken) {
|
||||
msgParams.message = { ...msgParams.message, minToken: message.minToken.toString() }
|
||||
msgParams.types.Mail.push({ name: 'minToken', type: 'uint256' })
|
||||
}
|
||||
}
|
||||
return msgParams
|
||||
}
|
||||
|
||||
export class PollInitMsg {
|
||||
public owner: string
|
||||
public timestamp: number
|
||||
|
@ -37,14 +87,15 @@ export class PollInitMsg {
|
|||
this.signature = signature
|
||||
}
|
||||
|
||||
static async create(
|
||||
static async _createWithSignFunction(
|
||||
signFunction: (params: string[]) => Promise<string | undefined>,
|
||||
signer: JsonRpcSigner | Wallet,
|
||||
question: string,
|
||||
answers: string[],
|
||||
pollType: PollType,
|
||||
minToken?: BigNumber,
|
||||
endTime?: number
|
||||
): Promise<PollInitMsg> {
|
||||
): Promise<PollInitMsg | undefined> {
|
||||
const owner = await signer.getAddress()
|
||||
const timestamp = Date.now()
|
||||
let newEndTime = timestamp + 10000000
|
||||
|
@ -52,32 +103,48 @@ export class PollInitMsg {
|
|||
newEndTime = endTime
|
||||
}
|
||||
|
||||
const msg: (string | number | BigNumber | PollType)[] = [
|
||||
if (pollType === PollType.NON_WEIGHTED && !minToken) {
|
||||
minToken = BigNumber.from(1)
|
||||
}
|
||||
|
||||
const params = createSignMsgParams({
|
||||
owner,
|
||||
timestamp,
|
||||
question,
|
||||
answers.join(),
|
||||
answers,
|
||||
pollType,
|
||||
newEndTime,
|
||||
]
|
||||
const types = ['address', 'uint256', 'string', 'string', 'uint8', 'uint256']
|
||||
if (pollType === PollType.NON_WEIGHTED) {
|
||||
if (minToken) {
|
||||
msg.push(minToken)
|
||||
} else {
|
||||
msg.push(BigNumber.from(1))
|
||||
minToken = BigNumber.from(1)
|
||||
}
|
||||
types.push('uint256')
|
||||
endTime: newEndTime,
|
||||
minToken,
|
||||
})
|
||||
|
||||
const signature = await signFunction([owner, JSON.stringify(params)])
|
||||
if (!signature) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const packedData = utils.arrayify(utils.solidityPack(types, msg))
|
||||
const signature = await signer.signMessage(packedData)
|
||||
const id = utils.solidityKeccak256(['address', 'uint256'], [owner, timestamp])
|
||||
return new PollInitMsg(id, owner, signature, timestamp, question, answers, pollType, newEndTime, minToken)
|
||||
}
|
||||
|
||||
static fromProto(payload: PollInit) {
|
||||
static async create(
|
||||
signer: JsonRpcSigner | Wallet,
|
||||
question: string,
|
||||
answers: string[],
|
||||
pollType: PollType,
|
||||
minToken?: BigNumber,
|
||||
endTime?: number
|
||||
): Promise<PollInitMsg | undefined> {
|
||||
const signFunction = async (params: string[]) => {
|
||||
if ('send' in signer.provider) {
|
||||
return signer.provider.send('eth_signTypedData_v4', params)
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
return this._createWithSignFunction(signFunction, signer, question, answers, pollType, minToken, endTime)
|
||||
}
|
||||
|
||||
static fromProto(payload: PollInit, recoverFunction: ({ data, sig }: { data: any; sig: string }) => string) {
|
||||
const owner = utils.getAddress(utils.hexlify(payload.owner))
|
||||
const timestamp = payload.timestamp
|
||||
const question = payload.question
|
||||
|
@ -85,29 +152,21 @@ export class PollInitMsg {
|
|||
const pollType = payload.pollType
|
||||
const endTime = payload.endTime
|
||||
const signature = utils.hexlify(payload.signature)
|
||||
let minToken = payload.minToken ? BigNumber.from(payload.minToken) : undefined
|
||||
const minToken = payload.minToken ? BigNumber.from(payload.minToken) : undefined
|
||||
|
||||
const msg: (string | number | BigNumber | PollType)[] = [
|
||||
const params = createSignMsgParams({
|
||||
owner,
|
||||
timestamp,
|
||||
question,
|
||||
answers.join(),
|
||||
pollType,
|
||||
answers,
|
||||
endTime,
|
||||
]
|
||||
const types = ['address', 'uint256', 'string', 'string', 'uint8', 'uint256']
|
||||
if (pollType === PollType.NON_WEIGHTED) {
|
||||
if (minToken) {
|
||||
msg.push(minToken)
|
||||
types.push('uint256')
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
} else {
|
||||
minToken = undefined
|
||||
}
|
||||
const packedData = utils.arrayify(utils.solidityPack(types, msg))
|
||||
const verifiedAddress = utils.verifyMessage(packedData, signature)
|
||||
minToken,
|
||||
pollType,
|
||||
})
|
||||
const verifiedAddress = recoverFunction({
|
||||
data: params,
|
||||
sig: signature,
|
||||
})
|
||||
if (verifiedAddress != owner) {
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import protons, { PollInit } from 'protons'
|
|||
import { PollType } from '../../types/PollType'
|
||||
import { utils } from 'ethers'
|
||||
import { PollInitMsg } from '../../models/PollInitMsg'
|
||||
import { recoverTypedSignature_v4 } from 'eth-sig-util'
|
||||
|
||||
const proto = protons(`
|
||||
message PollInit {
|
||||
|
@ -46,7 +47,11 @@ export function encode(pollInit: PollInitMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
export function decode(payload: Uint8Array, timestamp: Date | undefined) {
|
||||
export function decode(
|
||||
payload: Uint8Array,
|
||||
timestamp: Date | undefined,
|
||||
recoverFunction?: ({ data, sig }: { data: any; sig: string }) => string
|
||||
) {
|
||||
try {
|
||||
const msg = proto.PollInit.decode(payload)
|
||||
if (!timestamp || timestamp.getTime() != msg.timestamp) {
|
||||
|
@ -61,7 +66,10 @@ export function decode(payload: Uint8Array, timestamp: Date | undefined) {
|
|||
msg.endTime &&
|
||||
msg.signature
|
||||
) {
|
||||
return PollInitMsg.fromProto(msg)
|
||||
if (recoverFunction) {
|
||||
return PollInitMsg.fromProto(msg, recoverFunction)
|
||||
}
|
||||
return PollInitMsg.fromProto(msg, (e) => utils.getAddress(recoverTypedSignature_v4(e)))
|
||||
}
|
||||
} catch {
|
||||
return undefined
|
||||
|
|
|
@ -1,82 +1,117 @@
|
|||
import { expect } from 'chai'
|
||||
import { PollInitMsg } from '../../src/models/PollInitMsg'
|
||||
import { createSignMsgParams, PollInitMsg } from '../../src/models/PollInitMsg'
|
||||
import { MockProvider } from 'ethereum-waffle'
|
||||
import { PollType } from '../../src/types/PollType'
|
||||
import { BigNumber, utils } from 'ethers'
|
||||
import { BigNumber } from 'ethers'
|
||||
|
||||
describe('PollInitMsg', () => {
|
||||
const provider = new MockProvider()
|
||||
const [alice] = provider.getWallets()
|
||||
|
||||
it('success', async () => {
|
||||
const poll = await PollInitMsg.create(alice, 'test', ['one', 'two', 'three'], PollType.WEIGHTED)
|
||||
const poll = await PollInitMsg._createWithSignFunction(
|
||||
async (params) => params.join(),
|
||||
alice,
|
||||
'test',
|
||||
['one', 'two', 'three'],
|
||||
PollType.WEIGHTED
|
||||
)
|
||||
|
||||
expect(poll).to.not.be.undefined
|
||||
expect(poll.owner).to.eq(alice.address)
|
||||
expect(poll.endTime).to.eq(poll.timestamp + 10000000)
|
||||
expect(poll.answers).to.deep.eq(['one', 'two', 'three'])
|
||||
expect(poll.minToken).to.be.undefined
|
||||
expect(poll.pollType).to.eq(PollType.WEIGHTED)
|
||||
expect(poll.question).to.eq('test')
|
||||
if (poll) {
|
||||
expect(poll.owner).to.eq(alice.address)
|
||||
expect(poll.endTime).to.eq(poll.timestamp + 10000000)
|
||||
expect(poll.answers).to.deep.eq(['one', 'two', 'three'])
|
||||
expect(poll.minToken).to.be.undefined
|
||||
expect(poll.pollType).to.eq(PollType.WEIGHTED)
|
||||
expect(poll.question).to.eq('test')
|
||||
|
||||
const types = ['address', 'uint256', 'string', 'string', 'uint8', 'uint256']
|
||||
const msg = [poll.owner, poll.timestamp, poll.question, poll.answers.join(), poll.pollType, poll.endTime]
|
||||
const packedData = utils.arrayify(utils.solidityPack(types, msg))
|
||||
|
||||
const verifiedAddress = utils.verifyMessage(packedData, poll.signature)
|
||||
expect(verifiedAddress).to.eq(alice.address)
|
||||
expect(poll.signature).to.eq(
|
||||
[
|
||||
poll.owner,
|
||||
JSON.stringify(
|
||||
createSignMsgParams({
|
||||
owner: poll.owner,
|
||||
answers: poll.answers,
|
||||
endTime: poll.endTime,
|
||||
pollType: poll.pollType,
|
||||
minToken: poll.minToken,
|
||||
question: poll.question,
|
||||
timestamp: poll.timestamp,
|
||||
})
|
||||
),
|
||||
].join()
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('success NON_WEIGHTED', async () => {
|
||||
const poll = await PollInitMsg.create(
|
||||
const poll = await PollInitMsg._createWithSignFunction(
|
||||
async (params) => params.join(),
|
||||
alice,
|
||||
'test',
|
||||
['one', 'two', 'three'],
|
||||
PollType.NON_WEIGHTED,
|
||||
BigNumber.from(123)
|
||||
)
|
||||
|
||||
expect(poll).to.not.be.undefined
|
||||
expect(poll?.minToken?.toNumber()).to.eq(123)
|
||||
|
||||
const types = ['address', 'uint256', 'string', 'string', 'uint8', 'uint256', 'uint256']
|
||||
const msg = [
|
||||
poll.owner,
|
||||
poll.timestamp,
|
||||
poll.question,
|
||||
poll.answers.join(),
|
||||
poll.pollType,
|
||||
poll.endTime,
|
||||
poll.minToken,
|
||||
]
|
||||
const packedData = utils.arrayify(utils.solidityPack(types, msg))
|
||||
|
||||
const verifiedAddress = utils.verifyMessage(packedData, poll.signature)
|
||||
expect(verifiedAddress).to.eq(alice.address)
|
||||
if (poll) {
|
||||
expect(poll.signature).to.eq(
|
||||
[
|
||||
poll.owner,
|
||||
JSON.stringify(
|
||||
createSignMsgParams({
|
||||
owner: poll.owner,
|
||||
answers: poll.answers,
|
||||
endTime: poll.endTime,
|
||||
pollType: poll.pollType,
|
||||
minToken: poll.minToken,
|
||||
question: poll.question,
|
||||
timestamp: poll.timestamp,
|
||||
})
|
||||
),
|
||||
].join()
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
it('NON_WEIGHTED no minToken', async () => {
|
||||
const poll = await PollInitMsg.create(alice, 'test', ['one', 'two', 'three'], PollType.NON_WEIGHTED)
|
||||
const poll = await PollInitMsg._createWithSignFunction(
|
||||
async (params) => params.join(),
|
||||
alice,
|
||||
'test',
|
||||
['one', 'two', 'three'],
|
||||
PollType.NON_WEIGHTED
|
||||
)
|
||||
|
||||
expect(poll?.minToken?.toNumber()).to.eq(1)
|
||||
expect(poll).to.not.be.undefined
|
||||
if (poll) {
|
||||
const msg = createSignMsgParams({
|
||||
owner: poll.owner,
|
||||
answers: poll.answers,
|
||||
endTime: poll.endTime,
|
||||
pollType: poll.pollType,
|
||||
minToken: poll.minToken,
|
||||
question: poll.question,
|
||||
timestamp: poll.timestamp,
|
||||
})
|
||||
|
||||
const types = ['address', 'uint256', 'string', 'string', 'uint8', 'uint256', 'uint256']
|
||||
const msg = [
|
||||
poll.owner,
|
||||
poll.timestamp,
|
||||
poll.question,
|
||||
poll.answers.join(),
|
||||
poll.pollType,
|
||||
poll.endTime,
|
||||
poll.minToken,
|
||||
]
|
||||
const packedData = utils.arrayify(utils.solidityPack(types, msg))
|
||||
|
||||
const verifiedAddress = utils.verifyMessage(packedData, poll.signature)
|
||||
expect(verifiedAddress).to.eq(alice.address)
|
||||
expect(poll.signature).to.eq([poll.owner, JSON.stringify(msg)].join())
|
||||
}
|
||||
})
|
||||
|
||||
it('specific end time', async () => {
|
||||
const poll = await PollInitMsg.create(alice, 'test', ['one', 'two', 'three'], PollType.NON_WEIGHTED, undefined, 100)
|
||||
const poll = await PollInitMsg._createWithSignFunction(
|
||||
async () => 'a',
|
||||
alice,
|
||||
'test',
|
||||
['one', 'two', 'three'],
|
||||
PollType.NON_WEIGHTED,
|
||||
undefined,
|
||||
100
|
||||
)
|
||||
|
||||
expect(poll?.endTime).to.eq(100)
|
||||
})
|
||||
|
|
|
@ -9,13 +9,20 @@ describe('PollInit', () => {
|
|||
const provider = new MockProvider()
|
||||
const [alice] = provider.getWallets()
|
||||
it('success', async () => {
|
||||
const data = await PollInitMsg.create(alice, 'whats up', ['ab', 'cd', 'ef'], PollType.WEIGHTED)
|
||||
|
||||
const payload = PollInit.encode(data)
|
||||
|
||||
expect(payload).to.not.be.undefined
|
||||
if (payload) {
|
||||
expect(PollInit.decode(payload, new Date(data.timestamp))).to.deep.eq(data)
|
||||
const data = await PollInitMsg._createWithSignFunction(
|
||||
async () => '0x01',
|
||||
alice,
|
||||
'whats up',
|
||||
['ab', 'cd', 'ef'],
|
||||
PollType.WEIGHTED
|
||||
)
|
||||
expect(data).to.not.be.undefined
|
||||
if (data) {
|
||||
const payload = PollInit.encode(data)
|
||||
expect(payload).to.not.be.undefined
|
||||
if (payload) {
|
||||
expect(PollInit.decode(payload, new Date(data.timestamp), () => data.owner)).to.deep.eq(data)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -28,29 +35,43 @@ describe('PollInit', () => {
|
|||
})
|
||||
|
||||
it('NON_WEIGHTED init', async () => {
|
||||
const data = await PollInitMsg.create(
|
||||
const data = await PollInitMsg._createWithSignFunction(
|
||||
async () => '0x01',
|
||||
alice,
|
||||
'whats up',
|
||||
['ab', 'cd', 'ef'],
|
||||
PollType.NON_WEIGHTED,
|
||||
BigNumber.from(10)
|
||||
)
|
||||
|
||||
const payload = PollInit.encode(data)
|
||||
expect(payload).to.not.be.undefined
|
||||
if (payload) {
|
||||
expect(PollInit.decode(payload, new Date(data.timestamp))).to.deep.eq(data)
|
||||
expect(data).to.not.be.undefined
|
||||
if (data) {
|
||||
const payload = PollInit.encode(data)
|
||||
expect(payload).to.not.be.undefined
|
||||
if (payload) {
|
||||
expect(PollInit.decode(payload, new Date(data.timestamp), () => data.owner)).to.deep.eq(data)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
it('NON_WEIGHTED no min token', async () => {
|
||||
const data = await PollInitMsg.create(alice, 'whats up', ['ab', 'cd', 'ef'], PollType.NON_WEIGHTED)
|
||||
const data = await PollInitMsg._createWithSignFunction(
|
||||
async () => '0x01',
|
||||
alice,
|
||||
'whats up',
|
||||
['ab', 'cd', 'ef'],
|
||||
PollType.NON_WEIGHTED
|
||||
)
|
||||
expect(data).to.not.be.undefined
|
||||
if (data) {
|
||||
const payload = PollInit.encode(data)
|
||||
|
||||
const payload = PollInit.encode(data)
|
||||
|
||||
expect(payload).to.not.be.undefined
|
||||
if (payload) {
|
||||
expect(PollInit.decode(payload, new Date(data.timestamp))).to.deep.eq({ ...data, minToken: BigNumber.from(1) })
|
||||
expect(payload).to.not.be.undefined
|
||||
if (payload) {
|
||||
expect(PollInit.decode(payload, new Date(data.timestamp), () => data.owner)).to.deep.eq({
|
||||
...data,
|
||||
minToken: BigNumber.from(1),
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@status-waku-voting/react-components": "link:../react-components",
|
||||
"assert": "^2.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"prettier": "^2.3.2",
|
||||
|
|
|
@ -22,7 +22,8 @@ module.exports = (env) => {
|
|||
fallback: {
|
||||
"buffer": require.resolve("buffer/"),
|
||||
"crypto": require.resolve("crypto-browserify"),
|
||||
"stream": require.resolve("stream-browserify")
|
||||
"stream": require.resolve("stream-browserify"),
|
||||
"assert": require.resolve("assert")
|
||||
}
|
||||
},
|
||||
module: {
|
||||
|
|
|
@ -5,9 +5,7 @@ import { PollList } from './PollList'
|
|||
import styled from 'styled-components'
|
||||
import { PollType } from '@status-waku-voting/core/dist/esm/src/types/PollType'
|
||||
|
||||
const ethereum = (window as any).ethereum
|
||||
|
||||
const provider = new providers.Web3Provider(ethereum)
|
||||
const provider = new providers.Web3Provider((window as any).ethereum)
|
||||
|
||||
type ExampleProps = {
|
||||
appName: string
|
||||
|
@ -24,14 +22,13 @@ function Example({ appName }: ExampleProps) {
|
|||
const [selectedType, setSelectedType] = useState(PollType.WEIGHTED)
|
||||
|
||||
useEffect(() => {
|
||||
ethereum.ethereum.on('accountsChanged', async () => {
|
||||
provider.on('accountsChanged', async () => {
|
||||
provider.send('eth_requestAccounts', [])
|
||||
setSigner(provider.getSigner())
|
||||
})
|
||||
WakuVoting.create(appName, '0x01').then((e) => setWakuVoting(e))
|
||||
provider.send('eth_requestAccounts', [])
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
{showNewPollBox && (
|
||||
|
|
112
yarn.lock
112
yarn.lock
|
@ -895,8 +895,8 @@
|
|||
"@status-waku-voting/core@link:packages/core":
|
||||
version "1.0.0"
|
||||
dependencies:
|
||||
eth-sig-util "^3.0.1"
|
||||
ethers "^5.4.4"
|
||||
js-waku "^0.10.0"
|
||||
protons "^2.0.1"
|
||||
|
||||
"@status-waku-voting/react-components@link:packages/react-components":
|
||||
|
@ -1103,9 +1103,9 @@
|
|||
integrity sha512-zxrTNFl9Z8boMJXs6ieqZP0wAhvkdzmHSxTlJabM16cf5G9xBc1uPRH5Bbv2omEDDiM8MzTfqTJXBf0Ba4xFWA==
|
||||
|
||||
"@types/node@>=13.7.0":
|
||||
version "16.4.13"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.13.tgz#7dfd9c14661edc65cccd43a29eb454174642370d"
|
||||
integrity sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==
|
||||
version "16.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.6.0.tgz#0d5685f85066f94e97f19e8a67fe003c5fadacc4"
|
||||
integrity sha512-OyiZPohMMjZEYqcVo/UJ04GyAxXOJEZO/FpzyXxcH4r/ArrVoXHf4MbUrkLp0Tz7/p1mMKpo5zJ6ZHl8XBNthQ==
|
||||
|
||||
"@types/node@^12.12.6":
|
||||
version "12.20.19"
|
||||
|
@ -1825,6 +1825,16 @@ assert-plus@1.0.0, assert-plus@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
|
||||
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
|
||||
|
||||
assert@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32"
|
||||
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"
|
||||
|
||||
assertion-error@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
|
||||
|
@ -1896,6 +1906,11 @@ atob@^2.1.2:
|
|||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9"
|
||||
integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==
|
||||
|
||||
available-typed-arrays@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9"
|
||||
integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
|
@ -3991,7 +4006,7 @@ error-ex@^1.2.0, error-ex@^1.3.1:
|
|||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2:
|
||||
es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.18.5:
|
||||
version "1.18.5"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.5.tgz#9b10de7d4c206a3581fd5b2124233e04db49ae19"
|
||||
integrity sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==
|
||||
|
@ -4046,6 +4061,11 @@ es6-iterator@~2.0.3:
|
|||
es5-ext "^0.10.35"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
es6-object-assign@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c"
|
||||
integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
|
||||
|
||||
es6-promisify@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.1.1.tgz#46837651b7b06bf6fff893d03f29393668d01621"
|
||||
|
@ -4341,6 +4361,16 @@ eth-sig-util@^1.4.2:
|
|||
ethereumjs-abi "git+https://github.com/ethereumjs/ethereumjs-abi.git"
|
||||
ethereumjs-util "^5.1.1"
|
||||
|
||||
eth-sig-util@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/eth-sig-util/-/eth-sig-util-3.0.1.tgz#8753297c83a3f58346bd13547b59c4b2cd110c96"
|
||||
integrity sha512-0Us50HiGGvZgjtWTyAI/+qTzYPMLy5Q451D0Xy68bxq1QMWdoOddDwGvsqcFT27uohKgalM9z/yxplyt+mY2iQ==
|
||||
dependencies:
|
||||
ethereumjs-abi "^0.6.8"
|
||||
ethereumjs-util "^5.1.1"
|
||||
tweetnacl "^1.0.3"
|
||||
tweetnacl-util "^0.15.0"
|
||||
|
||||
eth-tx-summary@^3.1.2:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/eth-tx-summary/-/eth-tx-summary-3.2.4.tgz#e10eb95eb57cdfe549bf29f97f1e4f1db679035c"
|
||||
|
@ -4424,7 +4454,7 @@ ethereumjs-abi@0.6.5:
|
|||
bn.js "^4.10.0"
|
||||
ethereumjs-util "^4.3.0"
|
||||
|
||||
ethereumjs-abi@0.6.8:
|
||||
ethereumjs-abi@0.6.8, ethereumjs-abi@^0.6.8:
|
||||
version "0.6.8"
|
||||
resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae"
|
||||
integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==
|
||||
|
@ -5051,6 +5081,11 @@ for-in@^1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
|
||||
|
||||
foreach@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
||||
integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k=
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
|
@ -6166,6 +6201,13 @@ is-function@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08"
|
||||
integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==
|
||||
|
||||
is-generator-function@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
|
||||
integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
|
||||
dependencies:
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
is-glob@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a"
|
||||
|
@ -6197,6 +6239,14 @@ is-loopback-addr@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/is-loopback-addr/-/is-loopback-addr-1.0.1.tgz#d4adf50d12d53100da62a397c61d6c83fe40aab9"
|
||||
integrity sha512-DhWU/kqY7X2F6KrrVTu7mHlbd2Pbo4D1YkAzasBMjQs6lJAoefxaA6m6CpSX0K6pjt9D0b9PNFI5zduy/vzOYw==
|
||||
|
||||
is-nan@^1.2.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d"
|
||||
integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==
|
||||
dependencies:
|
||||
call-bind "^1.0.0"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
is-negative-zero@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24"
|
||||
|
@ -6308,6 +6358,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
|
|||
dependencies:
|
||||
has-symbols "^1.0.2"
|
||||
|
||||
is-typed-array@^1.1.3, is-typed-array@^1.1.6:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.7.tgz#881ddc660b13cb8423b2090fa88c0fe37a83eb2f"
|
||||
integrity sha512-VxlpTBGknhQ3o7YiVjIhdLU6+oD8dPz/79vvvH4F+S/c8608UCVa9fgDpa1kZgFoUST2DCgacc70UszKgzKuvA==
|
||||
dependencies:
|
||||
available-typed-arrays "^1.0.4"
|
||||
call-bind "^1.0.2"
|
||||
es-abstract "^1.18.5"
|
||||
foreach "^2.0.5"
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
is-typedarray@^1.0.0, is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
|
@ -7851,9 +7912,9 @@ multibase@^0.7.0:
|
|||
buffer "^5.5.0"
|
||||
|
||||
multibase@^4.0.1, multibase@^4.0.2:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.4.tgz#55ef53e6acce223c5a09341a8a3a3d973871a577"
|
||||
integrity sha512-8/JmrdSGzlw6KTgAJCOqUBSGd1V6186i/X8dDCGy/lbCKrQ+1QB6f3HE+wPr7Tpdj4U3gutaj9jG2rNX6UpiJg==
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/multibase/-/multibase-4.0.5.tgz#620293b524e01f504b750cef585c2bdc6ee1c64c"
|
||||
integrity sha512-oqFkOYXdUkakxT8MqGyn5sE1KYeVt1zataOTvg688skQp6TVBv9XnouCcVO86XKFzh/UTiCGmEImTx6ZnPZ0qQ==
|
||||
dependencies:
|
||||
"@multiformats/base-x" "^4.0.1"
|
||||
|
||||
|
@ -7955,11 +8016,16 @@ nano-json-stream-parser@^0.1.2:
|
|||
resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f"
|
||||
integrity sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=
|
||||
|
||||
nanoid@3.1.23, nanoid@^3.0.2, nanoid@^3.1.20:
|
||||
nanoid@3.1.23:
|
||||
version "3.1.23"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
|
||||
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
|
||||
|
||||
nanoid@^3.0.2, nanoid@^3.1.20:
|
||||
version "3.1.24"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.24.tgz#d7ac20215f595c26d314ee5671169a27b609025f"
|
||||
integrity sha512-WNhqqgD4qH7TQdU9ujXfFa/hQI5rOGGnZq+JRmz4JwMZFCgSZVquTq3ORUSv6IC+Y41ACBYV8a8J1kPkqGIiQg==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
|
||||
|
@ -10794,7 +10860,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
|||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
tweetnacl@^1.0.0:
|
||||
tweetnacl@^1.0.0, tweetnacl@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
|
||||
integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
|
||||
|
@ -11066,6 +11132,18 @@ util.promisify@^1.0.0:
|
|||
has-symbols "^1.0.1"
|
||||
object.getownpropertydescriptors "^2.1.1"
|
||||
|
||||
util@^0.12.0:
|
||||
version "0.12.4"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
|
||||
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"
|
||||
|
||||
utila@~0.4:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c"
|
||||
|
@ -11662,6 +11740,18 @@ which-module@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||
|
||||
which-typed-array@^1.1.2:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.6.tgz#f3713d801da0720a7f26f50c596980a9f5c8b383"
|
||||
integrity sha512-DdY984dGD5sQ7Tf+x1CkXzdg85b9uEel6nr4UkFg1LoE9OXv3uRuZhe5CoWdawhGACeFpEZXH8fFLQnDhbpm/Q==
|
||||
dependencies:
|
||||
available-typed-arrays "^1.0.4"
|
||||
call-bind "^1.0.2"
|
||||
es-abstract "^1.18.5"
|
||||
foreach "^2.0.5"
|
||||
has-tostringtag "^1.0.0"
|
||||
is-typed-array "^1.1.6"
|
||||
|
||||
which@2.0.2, which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
|
|
Loading…
Reference in New Issue