|
| 1 | +import { isEvmCoinType } from "@ensdomains/address-encoder/utils"; |
1 | 2 | import { trace } from "@opentelemetry/api"; |
2 | 3 | import { |
3 | 4 | type Address, |
4 | 5 | asLiteralName, |
| 6 | + bigintToCoinType, |
5 | 7 | type ContentType, |
| 8 | + ETH_COIN_TYPE, |
6 | 9 | type Hex, |
7 | 10 | type Name, |
8 | 11 | type RecordVersion, |
@@ -90,10 +93,40 @@ export async function executeOperations({ |
90 | 93 |
|
91 | 94 | if (size(value) === 0) return interpretOperationWithRawResult(op, null); |
92 | 95 |
|
93 | | - const results = decodeAbiParameters( |
94 | | - getAbiItem({ abi: ResolverABI, name: op.functionName, args: op.args }).outputs, |
95 | | - value, |
96 | | - ); |
| 96 | + const results = (() => { |
| 97 | + // resolve() may return a non-empty but malformed response, so catch the decoding error |
| 98 | + try { |
| 99 | + return decodeAbiParameters( |
| 100 | + getAbiItem({ |
| 101 | + abi: ResolverABI, |
| 102 | + name: op.functionName, |
| 103 | + args: op.args, |
| 104 | + }).outputs, |
| 105 | + value, |
| 106 | + ); |
| 107 | + } catch (error) { |
| 108 | + // record the exception for the trace |
| 109 | + if (error instanceof Error) span.recordException(error); |
| 110 | + |
| 111 | + // some resolvers (world.id) return raw results instead of encoding them correctly |
| 112 | + // so check for that and fix them |
| 113 | + if (op.functionName === "addr") { |
| 114 | + const coinType = bigintToCoinType(op.args[1]); |
| 115 | + const _isEvmCoinType = coinType === ETH_COIN_TYPE || isEvmCoinType(coinType); |
| 116 | + if (_isEvmCoinType && size(value) === 32) { |
| 117 | + try { |
| 118 | + return decodeAbiParameters([{ type: "address" }], value); |
| 119 | + } catch {} |
| 120 | + } |
| 121 | + } |
| 122 | + |
| 123 | + // if our special decoding logic above didn't help, we were unable to resolve this record |
| 124 | + return null; |
| 125 | + } |
| 126 | + })(); |
| 127 | + |
| 128 | + // if we failed to decode anything, interpret as null |
| 129 | + if (results === null) return interpretOperationWithRawResult(op, null); |
97 | 130 |
|
98 | 131 | // Some calls (ABI, pubkey) return a tuple; single-output calls unwrap. |
99 | 132 | const raw = results.length === 1 ? results[0] : results; |
|
0 commit comments