ox 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/dist/core/AbiFunction.d.ts +1 -1
- package/dist/core/AbiFunction.d.ts.map +1 -1
- package/dist/core/AbiFunction.js +6 -2
- package/dist/core/AbiFunction.js.map +1 -1
- package/dist/core/AbiParameters.d.ts +1 -1
- package/dist/core/AbiParameters.d.ts.map +1 -1
- package/dist/core/AbiParameters.js +1 -13
- package/dist/core/AbiParameters.js.map +1 -1
- package/dist/core/AesGcm.d.ts +36 -1
- package/dist/core/AesGcm.d.ts.map +1 -1
- package/dist/core/AesGcm.js +44 -0
- package/dist/core/AesGcm.js.map +1 -1
- package/dist/core/Ed25519.d.ts +46 -1
- package/dist/core/Ed25519.d.ts.map +1 -1
- package/dist/core/Ed25519.js +43 -0
- package/dist/core/Ed25519.js.map +1 -1
- package/dist/core/Engine.d.ts +1 -1
- package/dist/core/Engine.d.ts.map +1 -1
- package/dist/core/Engine.js.map +1 -1
- package/dist/core/Hash.d.ts +164 -1
- package/dist/core/Hash.d.ts.map +1 -1
- package/dist/core/Hash.js +172 -0
- package/dist/core/Hash.js.map +1 -1
- package/dist/core/Hex.d.ts.map +1 -1
- package/dist/core/Hex.js +1 -4
- package/dist/core/Hex.js.map +1 -1
- package/dist/core/Rlp.d.ts +32 -0
- package/dist/core/Rlp.d.ts.map +1 -1
- package/dist/core/Rlp.js +146 -0
- package/dist/core/Rlp.js.map +1 -1
- package/dist/core/Secp256k1.d.ts +46 -1
- package/dist/core/Secp256k1.d.ts.map +1 -1
- package/dist/core/Secp256k1.js +48 -0
- package/dist/core/Secp256k1.js.map +1 -1
- package/dist/core/WebAuthn.d.ts +224 -0
- package/dist/core/WebAuthn.d.ts.map +1 -0
- package/dist/core/WebAuthn.js +343 -0
- package/dist/core/WebAuthn.js.map +1 -0
- package/dist/core/WebAuthnP256.d.ts +46 -50
- package/dist/core/WebAuthnP256.d.ts.map +1 -1
- package/dist/core/WebAuthnP256.js +44 -50
- package/dist/core/WebAuthnP256.js.map +1 -1
- package/dist/core/internal/abiParameters.d.ts +7 -87
- package/dist/core/internal/abiParameters.d.ts.map +1 -1
- package/dist/core/internal/abiParameters.js +339 -194
- package/dist/core/internal/abiParameters.js.map +1 -1
- package/dist/core/internal/engine.d.ts +35 -2
- package/dist/core/internal/engine.d.ts.map +1 -1
- package/dist/core/internal/engine.js +12 -1
- package/dist/core/internal/engine.js.map +1 -1
- package/dist/core/internal/hash.d.ts +10 -0
- package/dist/core/internal/hash.d.ts.map +1 -1
- package/dist/core/internal/hash.js +26 -1
- package/dist/core/internal/hash.js.map +1 -1
- package/dist/index.d.ts +23 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -14
- package/dist/index.js.map +1 -1
- package/dist/node/Engine.d.ts +1 -1
- package/dist/node/Engine.d.ts.map +1 -1
- package/dist/node/Engine.js.map +1 -1
- package/dist/node/Hash.d.ts +6 -4
- package/dist/node/Hash.d.ts.map +1 -1
- package/dist/node/Hash.js +35 -3
- package/dist/node/Hash.js.map +1 -1
- package/dist/tempo/AuthorizationTempo.d.ts +6 -6
- package/dist/tempo/AuthorizationTempo.js +6 -6
- package/dist/tempo/KeyAuthorization.d.ts +3 -8
- package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
- package/dist/tempo/KeyAuthorization.js +3 -8
- package/dist/tempo/KeyAuthorization.js.map +1 -1
- package/dist/tempo/SignatureEnvelope.d.ts +8 -8
- package/dist/tempo/SignatureEnvelope.js +8 -8
- package/dist/wasm/Engine.d.ts +1 -1
- package/dist/wasm/Engine.d.ts.map +1 -1
- package/dist/wasm/Engine.js.map +1 -1
- package/dist/wasm/Hash.d.ts +1 -1
- package/dist/wasm/Hash.d.ts.map +1 -1
- package/dist/wasm/Hash.js +5 -0
- package/dist/wasm/Hash.js.map +1 -1
- package/dist/wasm/internal/blake3.d.ts +10 -1
- package/dist/wasm/internal/blake3.d.ts.map +1 -1
- package/dist/wasm/internal/blake3.js +12 -1
- package/dist/wasm/internal/blake3.js.map +1 -1
- package/dist/wasm/internal/blake3.wasm.d.ts +3 -1
- package/dist/wasm/internal/blake3.wasm.d.ts.map +1 -1
- package/dist/wasm/internal/blake3.wasm.js +3 -1
- package/dist/wasm/internal/blake3.wasm.js.map +1 -1
- package/dist/wasm/internal/hash.d.ts +9 -0
- package/dist/wasm/internal/hash.d.ts.map +1 -1
- package/dist/wasm/internal/hash.js +13 -1
- package/dist/wasm/internal/hash.js.map +1 -1
- package/dist/wasm/internal/hashState.d.ts +25 -0
- package/dist/wasm/internal/hashState.d.ts.map +1 -0
- package/dist/wasm/internal/hashState.js +105 -0
- package/dist/wasm/internal/hashState.js.map +1 -0
- package/dist/wasm/internal/hashes.d.ts +12 -1
- package/dist/wasm/internal/hashes.d.ts.map +1 -1
- package/dist/wasm/internal/hashes.js +18 -1
- package/dist/wasm/internal/hashes.js.map +1 -1
- package/dist/wasm/internal/hashes.wasm.d.ts +11 -3
- package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -1
- package/dist/wasm/internal/hashes.wasm.js +11 -3
- package/dist/wasm/internal/hashes.wasm.js.map +1 -1
- package/dist/webauthn/Authentication.d.ts +2 -0
- package/dist/webauthn/Authentication.d.ts.map +1 -1
- package/dist/webauthn/Authentication.js +2 -1
- package/dist/webauthn/Authentication.js.map +1 -1
- package/dist/webauthn/Registration.d.ts.map +1 -1
- package/dist/webauthn/Registration.js +2 -1
- package/dist/webauthn/Registration.js.map +1 -1
- package/dist/webauthn/Types.d.ts +27 -6
- package/dist/webauthn/Types.d.ts.map +1 -1
- package/dist/webauthn/internal/utils.d.ts.map +1 -1
- package/dist/webauthn/internal/utils.js +35 -9
- package/dist/webauthn/internal/utils.js.map +1 -1
- package/dist/zod/TypedData.d.ts +2 -2
- package/package.json +9 -1
- package/src/benchmarks/Ox.bench.ts +6 -0
- package/src/benchmarks/OxNode.bench.ts +8 -0
- package/src/benchmarks/OxV0.bench.ts +4 -0
- package/src/benchmarks/OxWasm.bench.ts +22 -0
- package/src/core/AbiFunction.ts +5 -5
- package/src/core/AbiParameters.ts +8 -20
- package/src/core/AesGcm.ts +86 -1
- package/src/core/Ed25519.ts +87 -1
- package/src/core/Engine.ts +1 -0
- package/src/core/Hash.ts +262 -1
- package/src/core/Hex.ts +1 -4
- package/src/core/Rlp.ts +172 -5
- package/src/core/Secp256k1.ts +92 -1
- package/src/core/WebAuthn.ts +579 -0
- package/src/core/WebAuthnP256.ts +47 -50
- package/src/core/_test/AbiFunction.test.ts +9 -0
- package/src/core/_test/AbiParameters.differential.fuzz.ts +156 -0
- package/src/core/_test/AbiParameters.encode.test.ts +22 -0
- package/src/core/_test/AbiParameters.fuzz.ts +4 -0
- package/src/core/_test/AesGcm.test.ts +76 -0
- package/src/core/_test/Ed25519.test-d.ts +13 -1
- package/src/core/_test/Ed25519.test.ts +120 -1
- package/src/core/_test/Engine.test-d.ts +9 -0
- package/src/core/_test/Engine.test.ts +1 -1
- package/src/core/_test/Hash.test-d.ts +23 -0
- package/src/core/_test/Hash.test.ts +179 -1
- package/src/core/_test/Hex.test.ts +2 -0
- package/src/core/_test/Rlp.test-d.ts +18 -0
- package/src/core/_test/Rlp.test.ts +109 -0
- package/src/core/_test/Secp256k1.test-d.ts +14 -0
- package/src/core/_test/Secp256k1.test.ts +91 -1
- package/src/core/_test/WebAuthn.test-d.ts +142 -0
- package/src/core/_test/WebAuthn.test.ts +766 -0
- package/src/core/_test/index.test.ts +1 -0
- package/src/core/internal/abiParameters.ts +466 -326
- package/src/core/internal/engine.ts +47 -2
- package/src/core/internal/hash.ts +53 -1
- package/src/index.ts +24 -14
- package/src/node/Engine.ts +1 -0
- package/src/node/Hash.ts +43 -6
- package/src/node/_test/Engine.test-d.ts +1 -0
- package/src/node/_test/Engine.test.ts +2 -0
- package/src/node/_test/Hash.test-d.ts +10 -0
- package/src/node/_test/Hash.test.ts +46 -0
- package/src/tempo/AuthorizationTempo.ts +6 -6
- package/src/tempo/KeyAuthorization.ts +3 -8
- package/src/tempo/SignatureEnvelope.ts +8 -8
- package/src/version.ts +1 -1
- package/src/wasm/Engine.ts +1 -0
- package/src/wasm/Hash.ts +10 -0
- package/src/wasm/_test/Engine.test-d.ts +1 -0
- package/src/wasm/_test/Engine.test.ts +5 -0
- package/src/wasm/_test/Hash.browser.test.ts +28 -0
- package/src/wasm/_test/Hash.test-d.ts +16 -0
- package/src/wasm/_test/Hash.test.ts +250 -1
- package/src/wasm/internal/blake3.ts +23 -2
- package/src/wasm/internal/blake3.wasm.ts +4 -1
- package/src/wasm/internal/hash.ts +27 -1
- package/src/wasm/internal/hashState.ts +154 -0
- package/src/wasm/internal/hashes.ts +56 -15
- package/src/wasm/internal/hashes.wasm.ts +15 -3
- package/src/webauthn/Authentication.ts +4 -0
- package/src/webauthn/Registration.ts +2 -0
- package/src/webauthn/Types.ts +32 -2
- package/src/webauthn/_test/Authentication.test.ts +123 -1
- package/src/webauthn/_test/Registration.test.ts +26 -6
- package/src/webauthn/_test/WebAuthn.browser.test.ts +28 -0
- package/src/webauthn/internal/utils.ts +41 -8
|
@@ -3,7 +3,8 @@ import * as Address from '../Address.js';
|
|
|
3
3
|
import * as Bytes from '../Bytes.js';
|
|
4
4
|
import * as Errors from '../Errors.js';
|
|
5
5
|
import * as Hex from '../Hex.js';
|
|
6
|
-
import { integerRegex } from '../Solidity.js';
|
|
6
|
+
import { bytesRegex, integerRegex } from '../Solidity.js';
|
|
7
|
+
import { encoder } from './codec/utf8.js';
|
|
7
8
|
/** @internal */
|
|
8
9
|
export function decodeParameter(cursor, param, options) {
|
|
9
10
|
const { checksumAddress, staticPosition } = options;
|
|
@@ -236,229 +237,373 @@ export function decodeString(cursor, { staticPosition }) {
|
|
|
236
237
|
return [value, 32];
|
|
237
238
|
}
|
|
238
239
|
/** @internal */
|
|
239
|
-
export function
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
240
|
+
export function encodeParameters(parameters, values, options = {}) {
|
|
241
|
+
const { checksumAddress = false, prefix } = options;
|
|
242
|
+
if (parameters.length !== values.length)
|
|
243
|
+
throw new AbiParameters.LengthMismatchError({
|
|
244
|
+
expectedLength: parameters.length,
|
|
245
|
+
givenLength: values.length,
|
|
246
|
+
});
|
|
247
|
+
// Compile the wire shape before walking values so recursive writes only
|
|
248
|
+
// handle offsets and data.
|
|
249
|
+
const compiled = compileParameters(parameters);
|
|
250
|
+
const context = {
|
|
251
|
+
checksumAddress,
|
|
252
|
+
};
|
|
253
|
+
const size = measureParameters(compiled, values, context);
|
|
254
|
+
const prefixSize = prefix ? Hex.size(prefix) : 0;
|
|
255
|
+
const bytes = new Uint8Array(prefixSize + size);
|
|
256
|
+
const writer = {
|
|
257
|
+
bytes,
|
|
258
|
+
patches: [],
|
|
259
|
+
view: new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
260
|
+
};
|
|
261
|
+
if (prefix)
|
|
262
|
+
writeHex(writer, 0, prefix);
|
|
263
|
+
writeParameters(writer, prefixSize, compiled, values);
|
|
264
|
+
let data = Hex.fromBytes(bytes);
|
|
265
|
+
for (let i = 0; i < writer.patches.length; i++) {
|
|
266
|
+
const patch = writer.patches[i];
|
|
267
|
+
const start = 2 + patch.offset * 2;
|
|
268
|
+
data =
|
|
269
|
+
`${data.slice(0, start)}${patch.value}${data.slice(start + patch.value.length)}`;
|
|
247
270
|
}
|
|
248
|
-
return
|
|
271
|
+
return data;
|
|
249
272
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
273
|
+
function compileParameters(parameters) {
|
|
274
|
+
const compiled = [];
|
|
275
|
+
for (let i = 0; i < parameters.length; i++)
|
|
276
|
+
compiled.push(compileParameter(parameters[i]));
|
|
277
|
+
return compiled;
|
|
278
|
+
}
|
|
279
|
+
function compileParameter(parameter) {
|
|
280
|
+
const name = parameter.name;
|
|
281
|
+
const array = getArrayComponents(parameter.type);
|
|
282
|
+
if (array) {
|
|
283
|
+
const [length, type] = array;
|
|
284
|
+
const child = compileParameter({ ...parameter, type });
|
|
285
|
+
const dynamic = length === null || child.dynamic;
|
|
286
|
+
return {
|
|
287
|
+
child,
|
|
288
|
+
dynamic,
|
|
289
|
+
kind: 'array',
|
|
258
290
|
length,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
});
|
|
291
|
+
name,
|
|
292
|
+
staticSize: dynamic ? 32 : child.staticSize * length,
|
|
293
|
+
type: parameter.type,
|
|
294
|
+
};
|
|
264
295
|
}
|
|
265
296
|
if (parameter.type === 'tuple') {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
297
|
+
const children = compileParameters(parameter.components);
|
|
298
|
+
let dynamic = false;
|
|
299
|
+
let staticSize = 0;
|
|
300
|
+
for (let i = 0; i < children.length; i++) {
|
|
301
|
+
const child = children[i];
|
|
302
|
+
if (child.dynamic)
|
|
303
|
+
dynamic = true;
|
|
304
|
+
staticSize += child.staticSize;
|
|
305
|
+
}
|
|
306
|
+
return {
|
|
307
|
+
children,
|
|
308
|
+
dynamic,
|
|
309
|
+
kind: 'tuple',
|
|
310
|
+
name,
|
|
311
|
+
staticSize: dynamic ? 32 : staticSize,
|
|
312
|
+
};
|
|
278
313
|
}
|
|
314
|
+
if (parameter.type === 'address')
|
|
315
|
+
return {
|
|
316
|
+
dynamic: false,
|
|
317
|
+
kind: 'address',
|
|
318
|
+
name,
|
|
319
|
+
staticSize: 32,
|
|
320
|
+
};
|
|
321
|
+
if (parameter.type === 'bool')
|
|
322
|
+
return {
|
|
323
|
+
dynamic: false,
|
|
324
|
+
kind: 'boolean',
|
|
325
|
+
name,
|
|
326
|
+
staticSize: 32,
|
|
327
|
+
};
|
|
279
328
|
if (parameter.type.startsWith('uint') || parameter.type.startsWith('int')) {
|
|
280
329
|
const signed = parameter.type.startsWith('int');
|
|
281
330
|
const [, , size = '256'] = integerRegex.exec(parameter.type) ?? [];
|
|
282
|
-
|
|
331
|
+
const size_ = Number(size);
|
|
332
|
+
const max = 2n ** (BigInt(size_) - (signed ? 1n : 0n)) - 1n;
|
|
333
|
+
return {
|
|
334
|
+
dynamic: false,
|
|
335
|
+
kind: 'integer',
|
|
336
|
+
max,
|
|
337
|
+
min: signed ? -max - 1n : 0n,
|
|
338
|
+
name,
|
|
283
339
|
signed,
|
|
284
|
-
size:
|
|
285
|
-
|
|
340
|
+
size: size_,
|
|
341
|
+
staticSize: 32,
|
|
342
|
+
};
|
|
286
343
|
}
|
|
287
344
|
if (parameter.type.startsWith('bytes')) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return
|
|
345
|
+
if (!bytesRegex.test(parameter.type))
|
|
346
|
+
throw new AbiParameters.InvalidTypeError(parameter.type);
|
|
347
|
+
const [, size] = parameter.type.split('bytes');
|
|
348
|
+
return {
|
|
349
|
+
dynamic: !size,
|
|
350
|
+
kind: 'bytes',
|
|
351
|
+
name,
|
|
352
|
+
size: size ? Number.parseInt(size, 10) : null,
|
|
353
|
+
staticSize: 32,
|
|
354
|
+
};
|
|
292
355
|
}
|
|
293
|
-
|
|
356
|
+
if (parameter.type === 'string')
|
|
357
|
+
return {
|
|
358
|
+
dynamic: true,
|
|
359
|
+
kind: 'string',
|
|
360
|
+
name,
|
|
361
|
+
staticSize: 32,
|
|
362
|
+
};
|
|
363
|
+
return {
|
|
364
|
+
dynamic: false,
|
|
365
|
+
kind: 'invalid',
|
|
366
|
+
name,
|
|
367
|
+
staticSize: 0,
|
|
368
|
+
type: parameter.type,
|
|
369
|
+
};
|
|
294
370
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
staticSize += 32;
|
|
303
|
-
else
|
|
304
|
-
staticSize += Hex.size(encoded);
|
|
371
|
+
function measureParameters(parameters, values, context) {
|
|
372
|
+
let size = getHeadSize(parameters);
|
|
373
|
+
for (let i = 0; i < parameters.length; i++) {
|
|
374
|
+
const parameter = parameters[i];
|
|
375
|
+
const parameterSize = measureParameter(parameter, getParameterValue(parameter, values, i), context);
|
|
376
|
+
if (parameter.dynamic)
|
|
377
|
+
size += parameterSize;
|
|
305
378
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
if (
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
379
|
+
return size;
|
|
380
|
+
}
|
|
381
|
+
function measureParameter(parameter, value, context) {
|
|
382
|
+
if (parameter.kind === 'array') {
|
|
383
|
+
if (!Array.isArray(value))
|
|
384
|
+
throw new AbiParameters.InvalidArrayError(value);
|
|
385
|
+
if (parameter.length !== null && value.length !== parameter.length)
|
|
386
|
+
throw new AbiParameters.ArrayLengthMismatchError({
|
|
387
|
+
expectedLength: parameter.length,
|
|
388
|
+
givenLength: value.length,
|
|
389
|
+
type: parameter.type,
|
|
390
|
+
});
|
|
391
|
+
let size = parameter.length === null ? 32 : 0;
|
|
392
|
+
size +=
|
|
393
|
+
value.length * (parameter.child.dynamic ? 32 : parameter.child.staticSize);
|
|
394
|
+
for (let i = 0; i < value.length; i++) {
|
|
395
|
+
const childSize = measureParameter(parameter.child, value[i], context);
|
|
396
|
+
if (parameter.child.dynamic)
|
|
397
|
+
size += childSize;
|
|
319
398
|
}
|
|
399
|
+
return size;
|
|
320
400
|
}
|
|
321
|
-
|
|
322
|
-
|
|
401
|
+
if (parameter.kind === 'tuple')
|
|
402
|
+
return measureParameters(parameter.children, value, context);
|
|
403
|
+
if (parameter.kind === 'address') {
|
|
404
|
+
Address.assert(value, {
|
|
405
|
+
strict: context.checksumAddress,
|
|
406
|
+
});
|
|
407
|
+
return 32;
|
|
408
|
+
}
|
|
409
|
+
if (parameter.kind === 'boolean') {
|
|
410
|
+
if (typeof value !== 'boolean')
|
|
411
|
+
throw new Errors.BaseError(`Invalid boolean value: "${value}" (type: ${typeof value}). Expected: \`true\` or \`false\`.`);
|
|
412
|
+
return 32;
|
|
413
|
+
}
|
|
414
|
+
if (parameter.kind === 'integer') {
|
|
415
|
+
const value_ = value;
|
|
416
|
+
if (value_ > parameter.max || value_ < parameter.min)
|
|
417
|
+
throw new Hex.IntegerOutOfRangeError({
|
|
418
|
+
max: parameter.max.toString(),
|
|
419
|
+
min: parameter.min.toString(),
|
|
420
|
+
signed: parameter.signed,
|
|
421
|
+
size: parameter.size / 8,
|
|
422
|
+
value: value_.toString(),
|
|
423
|
+
});
|
|
424
|
+
BigInt(value_);
|
|
425
|
+
return 32;
|
|
426
|
+
}
|
|
427
|
+
if (parameter.kind === 'bytes') {
|
|
428
|
+
const value_ = value;
|
|
429
|
+
const size = Hex.size(value_);
|
|
430
|
+
if (parameter.size !== null && size !== parameter.size)
|
|
431
|
+
throw new AbiParameters.BytesSizeMismatchError({
|
|
432
|
+
expectedSize: parameter.size,
|
|
433
|
+
value: value_,
|
|
434
|
+
});
|
|
435
|
+
if (parameter.size !== null)
|
|
436
|
+
return 32;
|
|
437
|
+
return 32 + Math.ceil(size / 32) * 32;
|
|
438
|
+
}
|
|
439
|
+
if (parameter.kind === 'string') {
|
|
440
|
+
const size = getUtf8Size(normalizeString(value));
|
|
441
|
+
return 32 + Math.ceil(size / 32) * 32;
|
|
442
|
+
}
|
|
443
|
+
throw new AbiParameters.InvalidTypeError(parameter.type);
|
|
323
444
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
};
|
|
445
|
+
function getHeadSize(parameters) {
|
|
446
|
+
let size = 0;
|
|
447
|
+
for (let i = 0; i < parameters.length; i++) {
|
|
448
|
+
const parameter = parameters[i];
|
|
449
|
+
size += parameter.dynamic ? 32 : parameter.staticSize;
|
|
450
|
+
}
|
|
451
|
+
return size;
|
|
332
452
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
throw new AbiParameters.ArrayLengthMismatchError({
|
|
341
|
-
expectedLength: length,
|
|
342
|
-
givenLength: value.length,
|
|
343
|
-
type: `${parameter.type}[${length}]`,
|
|
344
|
-
});
|
|
345
|
-
// Zero-length fixed arrays of dynamic types (e.g. `string[0]`) are dynamic
|
|
346
|
-
// per the ABI spec, even though they have no elements to inspect.
|
|
347
|
-
let dynamicChild = value.length === 0 && hasDynamicChild(parameter);
|
|
348
|
-
const preparedParameters = [];
|
|
453
|
+
function getParameterValue(parameter, values, index) {
|
|
454
|
+
if (Array.isArray(values))
|
|
455
|
+
return values[index];
|
|
456
|
+
return values[parameter.name];
|
|
457
|
+
}
|
|
458
|
+
function getUtf8Size(value) {
|
|
459
|
+
let size = 0;
|
|
349
460
|
for (let i = 0; i < value.length; i++) {
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
if (dynamic) {
|
|
362
|
-
const length = Hex.fromNumber(preparedParameters.length, { size: 32 });
|
|
363
|
-
return {
|
|
364
|
-
dynamic: true,
|
|
365
|
-
encoded: preparedParameters.length > 0 ? Hex.concat(length, data) : length,
|
|
366
|
-
};
|
|
461
|
+
const code = value.charCodeAt(i);
|
|
462
|
+
if (code < 0x80)
|
|
463
|
+
size++;
|
|
464
|
+
else if (code < 0x800)
|
|
465
|
+
size += 2;
|
|
466
|
+
else if (code >= 0xd800 &&
|
|
467
|
+
code <= 0xdbff &&
|
|
468
|
+
value.charCodeAt(i + 1) >= 0xdc00 &&
|
|
469
|
+
value.charCodeAt(i + 1) <= 0xdfff) {
|
|
470
|
+
size += 4;
|
|
471
|
+
i++;
|
|
367
472
|
}
|
|
368
|
-
|
|
369
|
-
|
|
473
|
+
else
|
|
474
|
+
size += 3;
|
|
370
475
|
}
|
|
371
|
-
return
|
|
372
|
-
dynamic: false,
|
|
373
|
-
encoded: Hex.concat(...preparedParameters.map(({ encoded }) => encoded)),
|
|
374
|
-
};
|
|
476
|
+
return size;
|
|
375
477
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (!parametersize) {
|
|
381
|
-
let value_ = value;
|
|
382
|
-
// If the size is not divisible by 32 bytes, pad the end
|
|
383
|
-
// with empty bytes to the ceiling 32 bytes.
|
|
384
|
-
if (bytesSize % 32 !== 0)
|
|
385
|
-
value_ = Hex.padRight(value_, Math.ceil((value.length - 2) / 2 / 32) * 32);
|
|
386
|
-
return {
|
|
387
|
-
dynamic: true,
|
|
388
|
-
encoded: Hex.concat(Hex.padLeft(Hex.fromNumber(bytesSize, { size: 32 })), value_),
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
if (bytesSize !== Number.parseInt(parametersize, 10))
|
|
392
|
-
throw new AbiParameters.BytesSizeMismatchError({
|
|
393
|
-
expectedSize: Number.parseInt(parametersize, 10),
|
|
394
|
-
value,
|
|
395
|
-
});
|
|
396
|
-
return { dynamic: false, encoded: Hex.padRight(value) };
|
|
478
|
+
function normalizeString(value) {
|
|
479
|
+
if (value === undefined)
|
|
480
|
+
return '';
|
|
481
|
+
return `${value}`;
|
|
397
482
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
483
|
+
function isWritableHex(value) {
|
|
484
|
+
if (typeof value !== 'string' ||
|
|
485
|
+
value.charCodeAt(0) !== 48 ||
|
|
486
|
+
value.charCodeAt(1) !== 120)
|
|
487
|
+
return false;
|
|
488
|
+
for (let i = 2; i < value.length; i++)
|
|
489
|
+
if (toNibble(value.charCodeAt(i)) === -1)
|
|
490
|
+
return false;
|
|
491
|
+
return true;
|
|
403
492
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
493
|
+
function writeParameters(context, offset, parameters, values) {
|
|
494
|
+
let head = offset;
|
|
495
|
+
let tail = offset + getHeadSize(parameters);
|
|
496
|
+
for (let i = 0; i < parameters.length; i++) {
|
|
497
|
+
const parameter = parameters[i];
|
|
498
|
+
const value = getParameterValue(parameter, values, i);
|
|
499
|
+
if (parameter.dynamic) {
|
|
500
|
+
writeWord(context, head, tail - offset);
|
|
501
|
+
head += 32;
|
|
502
|
+
tail = writeParameter(context, tail, parameter, value);
|
|
503
|
+
}
|
|
504
|
+
else
|
|
505
|
+
head = writeParameter(context, head, parameter, value);
|
|
417
506
|
}
|
|
418
|
-
return
|
|
419
|
-
dynamic: false,
|
|
420
|
-
encoded: Hex.fromNumber(value, {
|
|
421
|
-
size: 32,
|
|
422
|
-
signed,
|
|
423
|
-
}),
|
|
424
|
-
};
|
|
507
|
+
return Math.max(head, tail);
|
|
425
508
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
509
|
+
function writeParameter(context, offset, parameter, value) {
|
|
510
|
+
if (parameter.kind === 'array') {
|
|
511
|
+
const values = value;
|
|
512
|
+
let head = offset;
|
|
513
|
+
if (parameter.length === null) {
|
|
514
|
+
writeWord(context, head, values.length);
|
|
515
|
+
head += 32;
|
|
516
|
+
}
|
|
517
|
+
let tail = head +
|
|
518
|
+
values.length *
|
|
519
|
+
(parameter.child.dynamic ? 32 : parameter.child.staticSize);
|
|
520
|
+
for (let i = 0; i < values.length; i++) {
|
|
521
|
+
if (parameter.child.dynamic) {
|
|
522
|
+
writeWord(context, head, tail - (parameter.length === null ? offset + 32 : offset));
|
|
523
|
+
head += 32;
|
|
524
|
+
tail = writeParameter(context, tail, parameter.child, values[i]);
|
|
525
|
+
}
|
|
526
|
+
else
|
|
527
|
+
head = writeParameter(context, head, parameter.child, values[i]);
|
|
528
|
+
}
|
|
529
|
+
return Math.max(head, tail);
|
|
433
530
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
531
|
+
if (parameter.kind === 'tuple')
|
|
532
|
+
return writeParameters(context, offset, parameter.children, value);
|
|
533
|
+
if (parameter.kind === 'address') {
|
|
534
|
+
writeHex(context, offset + 12, value);
|
|
535
|
+
return offset + 32;
|
|
536
|
+
}
|
|
537
|
+
if (parameter.kind === 'boolean') {
|
|
538
|
+
context.bytes[offset + 31] = value ? 1 : 0;
|
|
539
|
+
return offset + 32;
|
|
540
|
+
}
|
|
541
|
+
if (parameter.kind === 'integer') {
|
|
542
|
+
writeWord(context, offset, value);
|
|
543
|
+
return offset + 32;
|
|
544
|
+
}
|
|
545
|
+
if (parameter.kind === 'bytes') {
|
|
546
|
+
const value_ = value;
|
|
547
|
+
if (parameter.size === null) {
|
|
548
|
+
const size = Hex.size(value_);
|
|
549
|
+
writeWord(context, offset, size);
|
|
550
|
+
writeHex(context, offset + 32, value_);
|
|
551
|
+
return offset + 32 + Math.ceil(size / 32) * 32;
|
|
552
|
+
}
|
|
553
|
+
writeHex(context, offset, value_);
|
|
554
|
+
return offset + 32;
|
|
555
|
+
}
|
|
556
|
+
if (parameter.kind === 'string') {
|
|
557
|
+
const value_ = normalizeString(value);
|
|
558
|
+
const size = getUtf8Size(value_);
|
|
559
|
+
writeWord(context, offset, size);
|
|
560
|
+
const { written } = encoder.encodeInto(value_, context.bytes.subarray(offset + 32, offset + 32 + size));
|
|
561
|
+
if (written !== size)
|
|
562
|
+
throw new Error('Failed to encode string.');
|
|
563
|
+
return offset + 32 + Math.ceil(size / 32) * 32;
|
|
564
|
+
}
|
|
565
|
+
return offset;
|
|
438
566
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
for (let i = 0; i < parameter.components.length; i++) {
|
|
445
|
-
const param_ = parameter.components[i];
|
|
446
|
-
const index = Array.isArray(value) ? i : param_.name;
|
|
447
|
-
const preparedParam = prepareParameter({
|
|
448
|
-
checksumAddress,
|
|
449
|
-
parameter: param_,
|
|
450
|
-
value: value[index],
|
|
451
|
-
});
|
|
452
|
-
preparedParameters.push(preparedParam);
|
|
453
|
-
if (preparedParam.dynamic)
|
|
454
|
-
dynamic = true;
|
|
567
|
+
function writeHex(context, offset, value) {
|
|
568
|
+
if (!isWritableHex(value)) {
|
|
569
|
+
const patch = value.slice(2);
|
|
570
|
+
context.patches.push({ offset, value: patch });
|
|
571
|
+
return offset + Math.ceil(patch.length / 2);
|
|
455
572
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
573
|
+
let i = 2;
|
|
574
|
+
for (; i + 1 < value.length; i += 2)
|
|
575
|
+
context.bytes[offset++] =
|
|
576
|
+
(toNibble(value.charCodeAt(i)) << 4) | toNibble(value.charCodeAt(i + 1));
|
|
577
|
+
if (i < value.length)
|
|
578
|
+
context.bytes[offset++] = toNibble(value.charCodeAt(i)) << 4;
|
|
579
|
+
return offset;
|
|
580
|
+
}
|
|
581
|
+
function writeWord(context, offset, value) {
|
|
582
|
+
let value_ = BigInt(value);
|
|
583
|
+
if (value_ < 0n)
|
|
584
|
+
value_ = BigInt.asUintN(256, value_);
|
|
585
|
+
// DataView avoids 32 BigInt shifts for the common word-sized case.
|
|
586
|
+
if (value_ <= 0xffffffffffffffffn) {
|
|
587
|
+
context.view.setBigUint64(offset + 24, value_);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
const hex = value_.toString(16);
|
|
591
|
+
let cursor = offset + 32 - Math.ceil(hex.length / 2);
|
|
592
|
+
let i = hex.length % 2;
|
|
593
|
+
if (i === 1)
|
|
594
|
+
context.bytes[cursor++] = toNibble(hex.charCodeAt(0));
|
|
595
|
+
for (; i < hex.length; i += 2)
|
|
596
|
+
context.bytes[cursor++] =
|
|
597
|
+
(toNibble(hex.charCodeAt(i)) << 4) | toNibble(hex.charCodeAt(i + 1));
|
|
598
|
+
}
|
|
599
|
+
function toNibble(code) {
|
|
600
|
+
if (code >= 48 && code <= 57)
|
|
601
|
+
return code - 48;
|
|
602
|
+
if (code >= 65 && code <= 70)
|
|
603
|
+
return code - 55;
|
|
604
|
+
if (code >= 97 && code <= 102)
|
|
605
|
+
return code - 87;
|
|
606
|
+
return -1;
|
|
462
607
|
}
|
|
463
608
|
/** @internal */
|
|
464
609
|
export function getArrayComponents(type) {
|