-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
tuple.ts
43 lines (35 loc) · 1.31 KB
/
tuple.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { concat } from '@ethersproject/bytes';
import type { TypesOfCoder } from './abstract-coder';
import Coder from './abstract-coder';
type InputValueOf<TCoders extends Coder[]> = {
[P in keyof TCoders]: TypesOfCoder<TCoders[P]>['Input'];
};
type DecodedValueOf<TCoders extends Coder[]> = {
[P in keyof TCoders]: TypesOfCoder<TCoders[P]>['Decoded'];
};
export default class TupleCoder<TCoders extends Coder[]> extends Coder<
InputValueOf<TCoders>,
DecodedValueOf<TCoders>
> {
coders: TCoders;
constructor(coders: TCoders) {
const encodedLength = coders.reduce((acc, coder) => acc + coder.encodedLength, 0);
super('tuple', `(${coders.map((coder) => coder.type).join(', ')})`, encodedLength);
this.coders = coders;
}
encode(value: InputValueOf<TCoders>): Uint8Array {
if (this.coders.length !== value.length) {
this.throwError('Types/values length mismatch', { value });
}
return concat(this.coders.map((coder, i) => coder.encode(value[i])));
}
decode(data: Uint8Array, offset: number): [DecodedValueOf<TCoders>, number] {
let newOffset = offset;
const decodedValue = this.coders.map((coder) => {
let decoded;
[decoded, newOffset] = coder.decode(data, newOffset);
return decoded;
});
return [decodedValue as DecodedValueOf<TCoders>, newOffset];
}
}