Commit 380dc2e9 authored by Will Cory's avatar Will Cory

make the types better

parent c88e8607
......@@ -25,6 +25,7 @@ describe(`cli:${write.name}`, () => {
value,
contract: ATTESTATION_STATION_ADDRESS,
rpcUrl,
dataType: 'string',
})
expect(txHash.startsWith('0x')).toBe(true)
......
// constants
export { ATTESTATION_STATION_ADDRESS } from './constants/attestationStationAddress'
// lib
export { readAttestation } from './lib/readAttestation'
export {
readAttestation,
readAttestationAddress,
readAttestationBool,
readAttestationNumber,
readAttestationString,
} from './lib/readAttestation'
export { readAttestations } from './lib/readAttestations'
export { prepareWriteAttestation } from './lib/prepareWriteAttestation'
export { prepareWriteAttestations } from './lib/prepareWriteAttestations'
export { writeAttestation } from './lib/writeAttestation'
export { abi } from './lib/abi'
export { parseAttestationBytes } from './lib/parseAttestationBytes'
export { stringifyAttestationBytes } from './lib/stringifyAttestationBytes'
export {
parseAttestationBytes,
parseAddress,
parseNumber,
parseBool,
parseString,
} from './lib/parseAttestationBytes'
// types
export type { AttestationReadParams } from './types/AttestationReadParams'
export type { WagmiBytes } from './types/WagmiBytes'
......
......@@ -3,7 +3,13 @@ import { toUtf8Bytes } from 'ethers/lib/utils.js'
import { expect, describe, it } from 'vitest'
import { WagmiBytes } from '../types/WagmiBytes'
import { parseAttestationBytes } from './parseAttestationBytes'
import {
parseNumber,
parseAddress,
parseBool,
parseString,
parseAttestationBytes,
} from './parseAttestationBytes'
describe(parseAttestationBytes.name, () => {
it('works for strings', () => {
......@@ -15,7 +21,12 @@ describe(parseAttestationBytes.name, () => {
it('works for numbers', () => {
const num = 123
const bytes = BigNumber.from(num).toHexString() as WagmiBytes
expect(parseAttestationBytes(bytes, 'number')).toBe(num.toString())
expect(parseAttestationBytes(bytes, 'number')).toMatchInlineSnapshot(`
{
"hex": "0x7b",
"type": "BigNumber",
}
`)
})
it('works for addresses', () => {
......@@ -26,7 +37,7 @@ describe(parseAttestationBytes.name, () => {
it('works for booleans', () => {
const bytes = BigNumber.from(1).toHexString() as WagmiBytes
expect(parseAttestationBytes(bytes, 'bool')).toBe('true')
expect(parseAttestationBytes(bytes, 'bool')).toBe(true)
})
it('should work for raw bytes', () => {
......@@ -40,3 +51,28 @@ describe(parseAttestationBytes.name, () => {
expect(parseAttestationBytes(bytes, 'foo')).toBe(bytes)
})
})
describe('parseFoo', () => {
it('works for strings', () => {
const str = 'Hello World'
const bytes = BigNumber.from(toUtf8Bytes(str)).toHexString() as WagmiBytes
expect(parseString(bytes)).toBe(str)
})
it('works for numbers', () => {
const num = 123
const bytes = BigNumber.from(num).toHexString() as WagmiBytes
expect(parseNumber(bytes)).toEqual(BigNumber.from(num))
})
it('works for addresses', () => {
const addr = '0x1234567890123456789012345678901234567890'
const bytes = BigNumber.from(addr).toHexString() as WagmiBytes
expect(parseAddress(bytes)).toBe(addr)
})
it('works for booleans', () => {
const bytes = BigNumber.from(1).toHexString() as WagmiBytes
expect(parseBool(bytes)).toBe(true)
})
})
import { BigNumber } from 'ethers'
import { toUtf8String } from 'ethers/lib/utils.js'
import type { Address } from '@wagmi/core'
import type { DataTypeOption } from '../types/DataTypeOption'
import type { WagmiBytes } from '../types/WagmiBytes'
import { ParseBytesReturn } from '../types/ParseBytesReturn'
export const parseAttestationBytes = (
/**
* Parses a string attestion
*/
export const parseString = (rawAttestation: WagmiBytes): string => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation ? toUtf8String(rawAttestation) : ''
}
/**
* Parses a boolean attestion
*/
export const parseBool = (rawAttestation: WagmiBytes): boolean => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation ? BigNumber.from(rawAttestation).gt(0) : false
}
/**
* Parses a number attestion
*/
export const parseNumber = (rawAttestation: WagmiBytes): BigNumber => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation ? BigNumber.from(rawAttestation) : BigNumber.from(0)
}
/**
* Parses a address attestion
*/
export const parseAddress = (rawAttestation: WagmiBytes): Address => {
rawAttestation = rawAttestation === '0x' ? '0x0' : rawAttestation
return rawAttestation
? (BigNumber.from(rawAttestation).toHexString() as Address)
: '0x0000000000000000000000000000000000000000'
}
/**
* Parses a raw attestation
*/
export const parseAttestationBytes = <TDataType extends DataTypeOption>(
attestationBytes: WagmiBytes,
dataType: DataTypeOption
) => {
dataType: TDataType
): ParseBytesReturn<TDataType> => {
if (dataType === 'bytes') {
return attestationBytes
return attestationBytes as ParseBytesReturn<TDataType>
}
if (dataType === 'number') {
return BigNumber.from(attestationBytes).toString()
return parseNumber(attestationBytes) as ParseBytesReturn<TDataType>
}
if (dataType === 'address') {
return BigNumber.from(attestationBytes).toHexString()
return parseAddress(attestationBytes) as ParseBytesReturn<TDataType>
}
if (dataType === 'bool') {
return BigNumber.from(attestationBytes).gt(0) ? 'true' : 'false'
return parseBool(attestationBytes) as ParseBytesReturn<TDataType>
}
if (dataType === 'string') {
return attestationBytes && toUtf8String(attestationBytes)
return parseString(attestationBytes) as ParseBytesReturn<TDataType>
}
console.warn(`unrecognized dataType ${dataType satisfies never}`)
return attestationBytes
return attestationBytes as never
}
......@@ -39,3 +39,4 @@ describe(readAttestation.name, () => {
)
})
})
import type { Address } from '@wagmi/core'
import { BigNumber } from 'ethers'
import { DataTypeOption, DEFAULT_DATA_TYPE } from '../types/DataTypeOption'
import { DataTypeOption } from '../types/DataTypeOption'
import { ParseBytesReturn } from '../types/ParseBytesReturn'
import { readAttestations } from './readAttestations'
/**
......@@ -17,19 +19,166 @@ import { readAttestations } from './readAttestations'
* key: 'my_key',
* },
*/
export const readAttestation = async (
export const readAttestation = async <TDataType extends DataTypeOption>(
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
dataType: DataTypeOption = DEFAULT_DATA_TYPE,
/**
* Data type of the attestation
* string | bool | number | address | bytes
*
* @defaults 'string'
*/
dataType: TDataType,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
): Promise<ParseBytesReturn<TDataType>> => {
const [result] = await readAttestations({
creator,
about,
key,
dataType,
contractAddress,
dataType,
})
return result
return result as ParseBytesReturn<TDataType>
}
/**
* Reads a string attestation
*/
export const readAttestationString = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
creator,
about,
key,
'string',
contractAddress
) as Promise<string>
}
export const readAttestationBool = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
/**
* Creator of the attestation
*/
creator,
about,
key,
'bool',
contractAddress
) as Promise<boolean>
}
export const readAttestationNumber = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
creator,
about,
key,
'number',
contractAddress
) as Promise<BigNumber>
}
export const readAttestationAddress = (
/**
* Creator of the attestation
*/
creator: Address,
/**
* Address the attestation is about
*/
about: Address,
/**
* Key of the attestation
*/
key: string,
/**
* Attestation address
* defaults to the official Optimism attestation station determistic deploy address
*
* @defaults '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
*/
contractAddress: Address = '0xEE36eaaD94d1Cc1d0eccaDb55C38bFfB6Be06C77'
) => {
return readAttestation(
creator,
about,
key,
'address',
contractAddress
) as Promise<Address>
}
......@@ -52,9 +52,12 @@ describe(readAttestation.name, () => {
`
[
"https://assets.optimism.io/4a609661-6774-441f-9fdb-453fdbb89931-bucket/optimist-nft/attributes",
"true",
true,
"0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
"9665973469795080068873111198635018086067645613429821071805084917303478255842407465257371959707311987533859075426222329066766033171696373249109388415320911537042272090516917683029511016473045453921068327933733922308146003731827",
{
"hex": "0x68747470733a2f2f6173736574732e6f7074696d69736d2e696f2f34613630393636312d363737342d343431662d396664622d3435336664626238393933312d6275636b65742f6f7074696d6973742d6e66742f61747472696275746573",
"type": "BigNumber",
},
]
`
)
......
import { BigNumber } from 'ethers'
import { Address } from 'wagmi'
import { DataTypeOption } from './DataTypeOption'
import { WagmiBytes } from './WagmiBytes'
/**
* @internal
* Returns the correct typescript type of a DataOption
*/
export type ParseBytesReturn<T extends DataTypeOption> = T extends 'bytes'
? WagmiBytes
: T extends 'number'
? BigNumber
: T extends 'address'
? Address
: T extends 'bool'
? boolean
: T extends 'string'
? string
: never
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment