Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/red-wasps-smash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@mimicprotocol/lib-ts": patch
"@mimicprotocol/cli": patch
"@mimicprotocol/test-ts": patch
---

Refactor Result to use unwrap instead of value
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export default class FunctionHandler {
if (isVoid) {
lines.push(`return Result.ok<${LibTypes.Void}, string>(new ${LibTypes.Void}())`)
} else {
lines.push(`const decoded = ${contractName}Utils.decode${capitalizedName}(response.value)`)
lines.push(`const decoded = ${contractName}Utils.decode${capitalizedName}(response.unwrap())`)
lines.push(`return Result.ok<${returnType}, string>(decoded)`)
}

Expand Down
4 changes: 2 additions & 2 deletions packages/cli/tests/AbisInterfaceGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ describe('AbisInterfaceGenerator', () => {
`const response = environment.evmCallQuery(this._address, this._chainId, encodedData.toHexString(), this._timestamp)`
)
expect(result).to.contain(`if (response.isError) return Result.err<${LibTypes.BigInt}, string>(response.error)`)
expect(result).to.contain(`const decoded = ${CONTRACT_NAME}Utils.decodeGetBalance(response.value)`)
expect(result).to.contain(`const decoded = ${CONTRACT_NAME}Utils.decodeGetBalance(response.unwrap())`)
expect(result).to.contain(`return Result.ok<${LibTypes.BigInt}, string>(decoded)`)
expect(result).to.contain(`export class ${CONTRACT_NAME}Utils {`)
expect(result).to.contain(`static encodeGetBalance(owner: Address): Bytes {`)
Expand Down Expand Up @@ -907,7 +907,7 @@ describe('AbisInterfaceGenerator', () => {
// Read function should call both helpers
expect(result).to.contain(`const encodedData = ${CONTRACT_NAME}Utils.encodeGetValue()`)
expect(result).to.contain(`if (response.isError) return Result.err<${LibTypes.BigInt}, string>(response.error)`)
expect(result).to.contain(`const decoded = ${CONTRACT_NAME}Utils.decodeGetValue(response.value)`)
expect(result).to.contain(`const decoded = ${CONTRACT_NAME}Utils.decodeGetValue(response.unwrap())`)
expect(result).to.contain(`return Result.ok<${LibTypes.BigInt}, string>(decoded)`)

// Write function should call encoded data helper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,9 @@ export default function main(): void {

const context = environment.getContext()

const userTokensResult = environment.relevantTokensQuery(
context.user,
[chainId],
USD.zero(),
[aUSDC],
ListType.AllowList
)
if (userTokensResult.isError) throw new Error(userTokensResult.error)

const userTokens = userTokensResult.value
const userTokens = environment
.relevantTokensQuery(context.user, [chainId], USD.zero(), [aUSDC], ListType.AllowList)
.unwrap()

const feeUsdt = TokenAmount.fromStringDecimal(USDT, inputs.usdFeeAmount)

Expand Down
4 changes: 2 additions & 2 deletions packages/lib-ts/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export namespace environment {

if (pricesResult.isError) return Result.err<USD, string>(pricesResult.error)

const prices = pricesResult.value
const prices = pricesResult.unwrap()
if (prices.length === 0) return Result.err<USD, string>('Prices not found for token ' + token.toString())

const sortedPrices = prices.sort((a: USD, b: USD) => a.compare(b))
Expand Down Expand Up @@ -173,7 +173,7 @@ export namespace environment {

if (responseResult.isError) return Result.err<TokenAmount[], string>(responseResult.error)

const response = responseResult.value
const response = responseResult.unwrap()
const resultMap: Map<string, TokenAmount> = new Map()
for (let i = 0; i < response.length; i++) {
for (let j = 0; j < response[i].length; j++) {
Expand Down
4 changes: 2 additions & 2 deletions packages/lib-ts/src/tokens/ERC20Token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export class ERC20Token extends BlockchainToken {
this._symbol = ERC20Token.EMPTY_SYMBOL
return
}
this._symbol = evm.decode(new EvmDecodeParam('string', response.value))
this._symbol = evm.decode(new EvmDecodeParam('string', response.unwrap()))
}

/**
Expand All @@ -181,6 +181,6 @@ export class ERC20Token extends BlockchainToken {
this._decimals = ERC20Token.EMPTY_DECIMALS
return
}
this._decimals = u8.parse(evm.decode(new EvmDecodeParam('uint8', result.value)))
this._decimals = u8.parse(evm.decode(new EvmDecodeParam('uint8', result.unwrap())))
}
}
6 changes: 3 additions & 3 deletions packages/lib-ts/src/tokens/SPLToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class SPLToken extends BlockchainToken {
this._decimals = SPLToken.EMPTY_DECIMALS
return
}
const decimals = SvmMint.fromHex(result.value.accountsInfo[0].data).decimals
const decimals = SvmMint.fromHex(result.unwrap().accountsInfo[0].data).decimals
this._decimals = decimals
}

Expand All @@ -120,12 +120,12 @@ export class SPLToken extends BlockchainToken {
this._symbol = SPLToken.EMPTY_SYMBOL
return
}
const data = result.value.accountsInfo[0].data
const data = result.unwrap().accountsInfo[0].data
// Return placeholder symbol from address if TokenMetadata standard is not used
this._symbol =
data === '0x'
? `${this.address.toString().slice(0, 5)}...${this.address.toString().slice(-5)}`
: SvmTokenMetadataData.fromTokenMetadataHex(result.value.accountsInfo[0].data).symbol
: SvmTokenMetadataData.fromTokenMetadataHex(result.unwrap().accountsInfo[0].data).symbol
}

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/lib-ts/src/tokens/TokenAmount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export class TokenAmount {
const tokenPriceResult = environment.tokenPriceQuery(this.token)
if (tokenPriceResult.isError) return Result.err<USD, string>(tokenPriceResult.error)

const tokenPrice = tokenPriceResult.value
const tokenPrice = tokenPriceResult.unwrap()
const amountUsd = this.amount.times(tokenPrice.value).downscale(this.decimals)
return Result.ok<USD, string>(USD.fromBigInt(amountUsd))
}
Expand All @@ -237,7 +237,7 @@ export class TokenAmount {
const usdResult = this.toUsd()
if (usdResult.isError) return Result.err<TokenAmount, string>(usdResult.error)

return usdResult.value.toTokenAmount(other)
return usdResult.unwrap().toTokenAmount(other)
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/lib-ts/src/tokens/USD.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export class USD {
const tokenPriceResult = environment.tokenPriceQuery(token)
if (tokenPriceResult.isError) return Result.err<TokenAmount, string>(tokenPriceResult.error)

const tokenPrice = tokenPriceResult.value
const tokenPrice = tokenPriceResult.unwrap()
const tokenAmount = this.value.upscale(token.decimals).div(tokenPrice.value)
return Result.ok<TokenAmount, string>(TokenAmount.fromBigInt(token, tokenAmount))
}
Expand Down
28 changes: 20 additions & 8 deletions packages/lib-ts/src/types/Result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@
// Copyright (c) 2018 Graph Protocol, Inc. and contributors.
// Modified by Mimic Protocol, 2025.

import { Stringable } from '../helpers'

/**
* The result of an operation, with a corresponding value and error type.
*/
export class Result<V, E> {
export class Result<V, E extends Stringable> {
constructor(
private _value: Wrapped<V> | null,
private _error: Wrapped<E> | null
) {}

static ok<V, E>(value: V): Result<V, E> {
static ok<V, E extends Stringable>(value: V): Result<V, E> {
return new Result<V, E>(new Wrapped<V>(value), null)
}

static err<V, E>(error: E): Result<V, E> {
static err<V, E extends Stringable>(error: E): Result<V, E> {
return new Result<V, E>(null, new Wrapped<E>(error))
}

Expand All @@ -29,15 +31,25 @@ export class Result<V, E> {
return this._error !== null
}

get value(): V {
if (this.isError) throw new Error('Trying to get a value from an error result')
return changetype<Wrapped<V>>(this._value).inner
}

get error(): E {
if (this.isOk) throw new Error('Trying to get an error from a successful result')
return changetype<Wrapped<E>>(this._error).inner
}

unwrap(): V {
if (this.isError) throw new Error(this.error.toString())
return changetype<Wrapped<V>>(this._value).inner
}

unwrapOr(defaultValue: V): V {
if (this.isError) return defaultValue
return this.unwrap()
}

unwrapOrElse(defaultValue: () => V): V {
if (this.isError) return defaultValue()
return this.unwrap()
}
}

// This is used to wrap a generic so that it can be unioned with `null`, working around limitations
Expand Down
14 changes: 7 additions & 7 deletions packages/lib-ts/tests/tokens/TokenAmount.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ describe('TokenAmount', () => {
const tokenAmount = TokenAmount.fromI32(randomERC20Token(), 0)
const result = tokenAmount.toUsd()
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe('0')
expect(result.unwrap().toString()).toBe('0')
})
})

Expand All @@ -452,7 +452,7 @@ describe('TokenAmount', () => {
const result = tokenAmount.toUsd()
const expectedAmount = decimalTokenAmount * price
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe(expectedAmount.toString())
expect(result.unwrap().toString()).toBe(expectedAmount.toString())
})

it('converts correctly for a token with standard decimals', () => {
Expand All @@ -466,7 +466,7 @@ describe('TokenAmount', () => {
const result = tokenAmount.toUsd()
const expectedAmount = decimalTokenAmount * price
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe(expectedAmount.toString())
expect(result.unwrap().toString()).toBe(expectedAmount.toString())
})

it('converts correctly for a token with more than standard decimals', () => {
Expand All @@ -480,7 +480,7 @@ describe('TokenAmount', () => {
const result = tokenAmount.toUsd()
const expectedAmount = decimalTokenAmount * price
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe(expectedAmount.toString())
expect(result.unwrap().toString()).toBe(expectedAmount.toString())
})
})
})
Expand All @@ -491,7 +491,7 @@ describe('TokenAmount', () => {
const tokenAmount = TokenAmount.fromI32(DenominationToken.USD(), 0)
const result = tokenAmount.toUsd()
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe('0')
expect(result.unwrap().toString()).toBe('0')
})
})

Expand All @@ -502,7 +502,7 @@ describe('TokenAmount', () => {

const result = tokenAmount.toUsd()
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe(decimalTokenAmount.toString())
expect(result.unwrap().toString()).toBe(decimalTokenAmount.toString())
})
})
})
Expand All @@ -513,7 +513,7 @@ describe('TokenAmount', () => {
const tokenAmount = TokenAmount.fromI32(DenominationToken.USD(), 0)
const result = tokenAmount.toUsd()
expect(result.isOk).toBe(true)
expect(result.value.toString()).toBe('0')
expect(result.unwrap().toString()).toBe('0')
})
})

Expand Down
8 changes: 4 additions & 4 deletions packages/lib-ts/tests/tokens/USD.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ describe('USD', () => {
const result = usdAmount.toTokenAmount(token)

expect(result.isOk).toBe(true)
expect(result.value.amount.toString()).toBe('0')
expect(result.unwrap().amount.toString()).toBe('0')
})
})

Expand All @@ -374,7 +374,7 @@ describe('USD', () => {

const expectedAmount = BigInt.fromI32(decimalAmountUsd / price)
expect(result.isOk).toBe(true)
expect(result.value.amount.toString()).toBe(zeroPadded(expectedAmount, tokenDecimals))
expect(result.unwrap().amount.toString()).toBe(zeroPadded(expectedAmount, tokenDecimals))
})

it('converts correctly for a token with standard decimals', () => {
Expand All @@ -388,7 +388,7 @@ describe('USD', () => {

const expectedAmount = BigInt.fromI32(decimalAmountUsd / price)
expect(result.isOk).toBe(true)
expect(result.value.amount.toString()).toBe(zeroPadded(expectedAmount, tokenDecimals))
expect(result.unwrap().amount.toString()).toBe(zeroPadded(expectedAmount, tokenDecimals))
})

it('converts correctly for a token with more than standard decimals', () => {
Expand All @@ -402,7 +402,7 @@ describe('USD', () => {

const expectedAmount = BigInt.fromI32(decimalAmountUsd / price)
expect(result.isOk).toBe(true)
expect(result.value.amount.toString()).toBe(zeroPadded(expectedAmount, tokenDecimals))
expect(result.unwrap().amount.toString()).toBe(zeroPadded(expectedAmount, tokenDecimals))
})
})
})
Expand Down
Loading