diff --git a/examples/voting/contract.algo.spec.ts b/examples/voting/contract.algo.spec.ts index 8d52cb3..fab5618 100644 --- a/examples/voting/contract.algo.spec.ts +++ b/examples/voting/contract.algo.spec.ts @@ -16,7 +16,7 @@ describe('VotingRoundApp', () => { const createContract = () => { const contract = ctx.contract.create(VotingRoundApp) - const snapshotPublicKey = Bytes<32>(keyPair.publicKey) + const snapshotPublicKey = Bytes(keyPair.publicKey).toFixed({ length: 32 }) const metadataIpfsCid = ctx.any.string(16) const startTime = ctx.any.uint64(Date.now() - 10_000, Date.now()) const endTime = ctx.any.uint64(Date.now() + 10_000, Date.now() + 100_000) @@ -52,7 +52,7 @@ describe('VotingRoundApp', () => { const account = ctx.any.account() const signature = nacl.sign.detached(toExternalValue(account.bytes), keyPair.secretKey) ctx.txn.createScope([ctx.any.txn.applicationCall({ sender: account })]).execute(() => { - const preconditions = contract.getPreconditions(Bytes(signature)) + const preconditions = contract.getPreconditions(Bytes(signature).toFixed({ length: 64 })) expect(preconditions.is_allowed_to_vote).toEqual(1) expect(preconditions.is_voting_open).toEqual(1) @@ -75,7 +75,11 @@ describe('VotingRoundApp', () => { ) ctx.txn.createScope([ctx.any.txn.applicationCall({ appId: app, sender: account })]).execute(() => { - contract.vote(ctx.any.txn.payment({ receiver: app.address, amount: voteMinBalanceReq }), Bytes(signature), answerIds) + contract.vote( + ctx.any.txn.payment({ receiver: app.address, amount: voteMinBalanceReq }), + Bytes(signature).toFixed({ length: 64 }), + answerIds, + ) expect(contract.votesByAccount(account).value.bytes).toEqual(answerIds.bytes) expect(contract.voterCount.value).toEqual(13) diff --git a/package-lock.json b/package-lock.json index 3c179da..e0d2514 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,8 @@ "name": "@algorandfoundation/algorand-typescript-testing", "version": "1.0.0", "dependencies": { - "@algorandfoundation/algorand-typescript": "1.0.0-alpha.84", - "@algorandfoundation/puya-ts": "1.0.0-alpha.84", + "@algorandfoundation/algorand-typescript": "1.0.0-alpha.85", + "@algorandfoundation/puya-ts": "1.0.0-alpha.85", "elliptic": "^6.6.1", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", @@ -76,21 +76,21 @@ } }, "node_modules/@algorandfoundation/algorand-typescript": { - "version": "1.0.0-alpha.84", - "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-1.0.0-alpha.84.tgz", - "integrity": "sha512-JhAPv2DAUEdVTKifQ7RNtynH2A0uJqifL9HTTLkJpJiiYEJlUN/Td3nwwntpVW5uIHunPPzdKjiTbh4HW2nluA==", + "version": "1.0.0-alpha.85", + "resolved": "https://registry.npmjs.org/@algorandfoundation/algorand-typescript/-/algorand-typescript-1.0.0-alpha.85.tgz", + "integrity": "sha512-lTOeDCRVNUhhDn03vILJIOY1++ZLJfo3tps4mRaENtD1+fqSMaUfH6msJaKsblY4XqBhrOWtBTPKpx1yyj7OkQ==", "peerDependencies": { "tslib": "^2.6.2" } }, "node_modules/@algorandfoundation/puya-ts": { - "version": "1.0.0-alpha.84", - "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.84.tgz", - "integrity": "sha512-veHuRk9RVrpEXuXBa8U5VeM5gqL6z+B/yNzSXvgEqub1H3ERxfYI7iWGcG0LDC/zVtMFLhCo42P/fwL/81tzpg==", + "version": "1.0.0-alpha.85", + "resolved": "https://registry.npmjs.org/@algorandfoundation/puya-ts/-/puya-ts-1.0.0-alpha.85.tgz", + "integrity": "sha512-Y21eXPgHo81yDsOy9a79qsdCGaLvQpz4BO1Bv9xct/Kjioq2InnWFmcV2LuKzCZC7a/kaBlvJkE8ChR6BU6M8g==", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@algorandfoundation/algorand-typescript": "1.0.0-alpha.84", + "@algorandfoundation/algorand-typescript": "1.0.0-alpha.85", "arcsecond": "^5.0.0", "argparse": "^2.0.1", "chalk": "^5.4.1", diff --git a/package.json b/package.json index 069636c..cbffb16 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,8 @@ "vitest": "3.2.4" }, "dependencies": { - "@algorandfoundation/algorand-typescript": "1.0.0-alpha.84", - "@algorandfoundation/puya-ts": "1.0.0-alpha.84", + "@algorandfoundation/algorand-typescript": "1.0.0-alpha.85", + "@algorandfoundation/puya-ts": "1.0.0-alpha.85", "elliptic": "^6.6.1", "js-sha256": "^0.11.0", "js-sha3": "^0.9.3", diff --git a/src/constants.ts b/src/constants.ts index 1d8d9ec..c217650 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -1,4 +1,4 @@ -import { Bytes, FixedBytes } from './impl/primitives' +import { Bytes } from './impl/primitives' /** @internal */ export const UINT64_SIZE = 64 @@ -40,13 +40,12 @@ export const DEFAULT_ASSET_OPT_IN_MIN_BALANCE = 10_000 /** @internal * from python code: list(b"\x85Y\xb5\x14x\xfd\x89\xc1vC\xd0]\x15\xa8\xaek\x10\xabG\xbbm\x8a1\x88\x11V\xe6\xbd;\xae\x95\xd1") */ -export const DEFAULT_GLOBAL_GENESIS_HASH = FixedBytes( - 32, +export const DEFAULT_GLOBAL_GENESIS_HASH = Bytes( new Uint8Array([ 133, 89, 181, 20, 120, 253, 137, 193, 118, 67, 208, 93, 21, 168, 174, 107, 16, 171, 71, 187, 109, 138, 49, 136, 17, 86, 230, 189, 59, 174, 149, 209, ]), -) +).toFixed({ length: 32 }) /** @internal * algorand encoded address of 32 zero bytes diff --git a/src/impl/crypto.ts b/src/impl/crypto.ts index 00ce5b5..2f3302d 100644 --- a/src/impl/crypto.ts +++ b/src/impl/crypto.ts @@ -10,13 +10,13 @@ import { lazyContext } from '../context-helpers/internal-context' import { InternalError, NotImplementedError } from '../errors' import { asBytes, asBytesCls, asUint8Array, concatUint8Arrays } from '../util' import type { StubBytesCompat, StubUint64Compat } from './primitives' -import { Bytes, BytesCls, FixedBytes, Uint64Cls } from './primitives' +import { Bytes, BytesCls, Uint64Cls } from './primitives' /** @internal */ export const sha256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha256.sha256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = FixedBytes(32, new Uint8Array(hashArray)) + const hashBytes = Bytes(new Uint8Array(hashArray)).toFixed({ length: 32 }) return hashBytes } @@ -24,7 +24,7 @@ export const sha256 = (a: StubBytesCompat): bytes<32> => { export const sha3_256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha3.sha3_256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = FixedBytes(32, new Uint8Array(hashArray)) + const hashBytes = Bytes(new Uint8Array(hashArray)).toFixed({ length: 32 }) return hashBytes } @@ -32,7 +32,7 @@ export const sha3_256 = (a: StubBytesCompat): bytes<32> => { export const keccak256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha3.keccak256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = FixedBytes(32, new Uint8Array(hashArray)) + const hashBytes = Bytes(new Uint8Array(hashArray)).toFixed({ length: 32 }) return hashBytes } @@ -40,7 +40,7 @@ export const keccak256 = (a: StubBytesCompat): bytes<32> => { export const sha512_256 = (a: StubBytesCompat): bytes<32> => { const bytesA = BytesCls.fromCompat(a) const hashArray = js_sha512.sha512_256.create().update(bytesA.asUint8Array()).digest() - const hashBytes = FixedBytes(32, new Uint8Array(hashArray)) + const hashBytes = Bytes(new Uint8Array(hashArray)).toFixed({ length: 32 }) return hashBytes } @@ -114,7 +114,7 @@ export const ecdsaPkRecover = ( const x = pubKey.getX().toArray('be') const y = pubKey.getY().toArray('be') - return [FixedBytes(32, x), FixedBytes(32, y)] + return [Bytes(x).toFixed({ length: 32 }), Bytes(y).toFixed({ length: 32 })] } /** @internal */ @@ -127,7 +127,7 @@ export const ecdsaPkDecompress = (v: Ecdsa, a: StubBytesCompat): readonly [bytes const x = pubKey.getX().toArray('be') const y = pubKey.getY().toArray('be') - return [FixedBytes(32, new Uint8Array(x)), FixedBytes(32, new Uint8Array(y))] + return [Bytes(x).toFixed({ length: 32 }), Bytes(y).toFixed({ length: 32 })] } /** @internal */ diff --git a/src/impl/primitives.ts b/src/impl/primitives.ts index 8c33273..9394b03 100644 --- a/src/impl/primitives.ts +++ b/src/impl/primitives.ts @@ -1,7 +1,6 @@ import type { biguint, BigUintCompat, bytes, BytesCompat, uint64, Uint64Compat } from '@algorandfoundation/algorand-typescript' import { encodingUtil } from '@algorandfoundation/puya-ts' import { avmError, AvmError, avmInvariant, CodeError, InternalError } from '../errors' -import type { DeliberateAny } from '../typescript-helpers' import { nameOfType } from '../typescript-helpers' import { base32ToUint8Array } from './base-32' @@ -88,97 +87,6 @@ export function BigUint(v?: BigUintCompat | string): biguint { return BigUintCls.fromCompat(v).asAlgoTs() } -/** - * @internal - * Create a byte array from a string interpolation template and compatible replacements - * @param value * - * @param replacements * - */ -export function FixedBytes( - length: TLength, - value: TemplateStringsArray, - ...replacements: BytesCompat[] -): bytes -/** - * @internal - * Create a byte array from a utf8 string - */ -export function FixedBytes(length: TLength, value: string): bytes -/** - * @internal - * No op, returns the provided byte array. - */ -export function FixedBytes(length: TLength, value: bytes): bytes -/** - * @internal - * Create a byte array from a biguint value encoded as a variable length big-endian number * - */ -export function FixedBytes(length: TLength, value: biguint): bytes -/** - * @internal - * Create a byte array from a uint64 value encoded as a fixed length 64-bit number - */ -export function FixedBytes(length: TLength, value: uint64): bytes -/** - * @internal - * Create a byte array from an Iterable where each item is interpreted as a single byte and must be between 0 and 255 inclusively - */ -export function FixedBytes(length: TLength, value: Iterable): bytes -/** - * @internal - * Create an empty byte array - */ -export function FixedBytes(length: TLength): bytes -export function FixedBytes( - length: TLength, - value?: BytesCompat | TemplateStringsArray | biguint | uint64 | Iterable, - ...replacements: BytesCompat[] -): bytes { - const result = Bytes((value ?? new Uint8Array(length)) as DeliberateAny, ...replacements) - if (length && length !== getNumber(result.length)) { - throw new CodeError(`Invalid bytes constant length of ${result.length}, expected ${length}`) - } - return result.toFixed({ length }) -} - -/** - * @internal - * Create a new bytes value from a hexadecimal encoded string - * @param hex - */ -FixedBytes.fromHex = (length: TLength, hex: string): bytes => { - const result = BytesCls.fromHex(hex).asAlgoTs() - if (length && length !== getNumber(result.length)) { - throw new CodeError(`Expected decoded bytes value of length ${length}, received ${result.length}`) - } - return result.toFixed({ length }) -} -/** - * @internal - * Create a new bytes value from a base 64 encoded string - * @param b64 - */ -FixedBytes.fromBase64 = (length: TLength, b64: string): bytes => { - const result = BytesCls.fromBase64(b64).asAlgoTs() - if (length && length !== getNumber(result.length)) { - throw new CodeError(`Expected decoded bytes value of length ${length}, received ${result.length}`) - } - return result.toFixed({ length }) -} - -/** - * @internal - * Create a new bytes value from a base 32 encoded string - * @param b32 - */ -FixedBytes.fromBase32 = (length: TLength, b32: string): bytes => { - const result = BytesCls.fromBase32(b32).asAlgoTs() - if (length && length !== getNumber(result.length)) { - throw new CodeError(`Expected decoded bytes value of length ${length}, received ${result.length}`) - } - return result.toFixed({ length }) -} - /** * @internal * Create a byte array from a string interpolation template and compatible replacements diff --git a/src/runtime-helpers.ts b/src/runtime-helpers.ts index b3f32ad..bf66e61 100644 --- a/src/runtime-helpers.ts +++ b/src/runtime-helpers.ts @@ -11,8 +11,6 @@ import { flattenAsBytes } from './util' /** @internal */ export { attachAbiMetadata } from './abi-metadata' -/** @internal */ -export { FixedBytes } from './impl/primitives' /** @internal */ export function switchableValue(x: unknown): bigint | string | boolean { diff --git a/src/test-transformer/node-factory.ts b/src/test-transformer/node-factory.ts index 8688dc0..484de3f 100644 --- a/src/test-transformer/node-factory.ts +++ b/src/test-transformer/node-factory.ts @@ -149,17 +149,4 @@ export const nodeFactory = { } return node }, - - callFixedBytesFunction(functionName: string, node: ts.CallExpression, length: number) { - const updatedPropertyAccessExpression = factory.createPropertyAccessExpression( - factory.createIdentifier('runtimeHelpers'), - `FixedBytes${functionName === 'Bytes' ? '' : `.${functionName}`}`, - ) - - return factory.createCallExpression( - updatedPropertyAccessExpression, - node.typeArguments, - [factory.createNumericLiteral(length), ...(node.arguments ?? [])].filter((arg) => !!arg), - ) - }, } satisfies Record ts.Node | ts.Node[]> diff --git a/src/test-transformer/visitors.ts b/src/test-transformer/visitors.ts index 9116654..37bde05 100644 --- a/src/test-transformer/visitors.ts +++ b/src/test-transformer/visitors.ts @@ -218,9 +218,6 @@ class ExpressionVisitor { updatedNode = nodeFactory.callAbiCallFunction(updatedNode, typeParams) } else if (isCallingItxnCompose(stubbedFunctionName)) { updatedNode = nodeFactory.callItxnComposeFunction(updatedNode) - } else if (isCallingBytes(stubbedFunctionName)) { - if (type instanceof ptypes.BytesPType && type.length) - updatedNode = nodeFactory.callFixedBytesFunction(stubbedFunctionName, updatedNode, Number(type.length)) } else { updatedNode = nodeFactory.callStubbedFunction(updatedNode, infoArg) } @@ -506,7 +503,7 @@ const tryGetStubbedFunctionName = (node: ts.CallExpression, helper: VisitorHelpe : (node.expression as ts.Identifier) const functionName = tryGetAlgoTsSymbolName(identityExpression, helper) if (functionName === undefined) return undefined - const stubbedFunctionNames = ['convertBytes', 'decodeArc4', 'encodeArc4', 'emit', 'methodSelector', 'sizeOf', 'abiCall', 'clone', 'Bytes'] + const stubbedFunctionNames = ['convertBytes', 'decodeArc4', 'encodeArc4', 'emit', 'methodSelector', 'sizeOf', 'abiCall', 'clone'] if (stubbedFunctionNames.includes(functionName)) { if (ts.isPropertyAccessExpression(node.expression)) { @@ -516,10 +513,10 @@ const tryGetStubbedFunctionName = (node: ts.CallExpression, helper: VisitorHelpe return functionName } - if (['begin', 'next', 'fromHex', 'fromBase64', 'fromBase32'].includes(functionName) && ts.isPropertyAccessExpression(node.expression)) { + if (['begin', 'next'].includes(functionName) && ts.isPropertyAccessExpression(node.expression)) { const objectExpression = node.expression.expression const objectName = tryGetAlgoTsSymbolName(objectExpression, helper) - if (['itxnCompose', 'Bytes'].includes(objectName || '')) return functionName + if (['itxnCompose'].includes(objectName || '')) return functionName } return undefined @@ -550,5 +547,3 @@ const isCallingMethodSelector = (functionName: string | undefined): boolean => ' const isCallingAbiCall = (functionName: string | undefined): boolean => ['abiCall'].includes(functionName ?? '') const isCallingItxnCompose = (functionName: string | undefined): boolean => ['begin', 'next'].includes(functionName ?? '') const isCallingClone = (functionName: string | undefined): boolean => 'clone' === (functionName ?? '') -const isCallingBytes = (functionName: string | undefined): boolean => - ['Bytes', 'fromHex', 'fromBase64', 'fromBase32'].includes(functionName ?? '') diff --git a/tests/crypto-op-codes.algo.spec.ts b/tests/crypto-op-codes.algo.spec.ts index f8acd13..9200e13 100644 --- a/tests/crypto-op-codes.algo.spec.ts +++ b/tests/crypto-op-codes.algo.spec.ts @@ -163,17 +163,17 @@ describe('crypto op codes', async () => { }) }) test('should throw error when no active txn group', async () => { - expect(() => op.ed25519verify(Bytes(''), Bytes<64>(), Bytes<32>())).toThrow('no active txn group') + expect(() => op.ed25519verify(Bytes(''), op.bzero(64), op.bzero(32))).toThrow('no active txn group') }) }) describe('ecdsaVerify', async () => { test('should be able to verify k1 signature', async ({ appClientCryptoOpsContract: appClient }) => { - const messageHash = Bytes.fromHex<32>('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1') - const sigR = Bytes.fromHex<32>('f7f913754e5c933f3825d3aef22e8bf75cfe35a18bede13e15a6e4adcfe816d2') - const sigS = Bytes.fromHex<32>('0b5599159aa859d79677f33280848ae4c09c2061e8b5881af8507f8112966754') - const pubkeyX = Bytes.fromHex<32>('a710244d62747aa8db022ddd70617240adaf881b439e5f69993800e614214076') - const pubkeyY = Bytes.fromHex<32>('48d0d337704fe2c675909d2c93f7995e199156f302f63c74a8b96827b28d777b') + const messageHash = Bytes.fromHex('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1').toFixed({ length: 32 }) + const sigR = Bytes.fromHex('f7f913754e5c933f3825d3aef22e8bf75cfe35a18bede13e15a6e4adcfe816d2').toFixed({ length: 32 }) + const sigS = Bytes.fromHex('0b5599159aa859d79677f33280848ae4c09c2061e8b5881af8507f8112966754').toFixed({ length: 32 }) + const pubkeyX = Bytes.fromHex('a710244d62747aa8db022ddd70617240adaf881b439e5f69993800e614214076').toFixed({ length: 32 }) + const pubkeyY = Bytes.fromHex('48d0d337704fe2c675909d2c93f7995e199156f302f63c74a8b96827b28d777b').toFixed({ length: 32 }) const avmResult = await getAvmResult( { @@ -194,11 +194,11 @@ describe('crypto op codes', async () => { expect(result).toEqual(avmResult) }) test('should be able to verify r1 signature', async ({ appClientCryptoOpsContract: appClient }) => { - const messageHash = Bytes.fromHex<32>('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1') - const sigR = Bytes.fromHex<32>('18d96c7cda4bc14d06277534681ded8a94828eb731d8b842e0da8105408c83cf') - const sigS = Bytes.fromHex<32>('7d33c61acf39cbb7a1d51c7126f1718116179adebd31618c4604a1f03b5c274a') - const pubkeyX = Bytes.fromHex<32>('f8140e3b2b92f7cbdc8196bc6baa9ce86cf15c18e8ad0145d50824e6fa890264') - const pubkeyY = Bytes.fromHex<32>('bd437b75d6f1db67155a95a0da4b41f2b6b3dc5d42f7db56238449e404a6c0a3') + const messageHash = Bytes.fromHex('f809fd0aa0bb0f20b354c6b2f86ea751957a4e262a546bd716f34f69b9516ae1').toFixed({ length: 32 }) + const sigR = Bytes.fromHex('18d96c7cda4bc14d06277534681ded8a94828eb731d8b842e0da8105408c83cf').toFixed({ length: 32 }) + const sigS = Bytes.fromHex('7d33c61acf39cbb7a1d51c7126f1718116179adebd31618c4604a1f03b5c274a').toFixed({ length: 32 }) + const pubkeyX = Bytes.fromHex('f8140e3b2b92f7cbdc8196bc6baa9ce86cf15c18e8ad0145d50824e6fa890264').toFixed({ length: 32 }) + const pubkeyY = Bytes.fromHex('bd437b75d6f1db67155a95a0da4b41f2b6b3dc5d42f7db56238449e404a6c0a3').toFixed({ length: 32 }) const avmResult = await getAvmResult( { @@ -291,11 +291,11 @@ describe('crypto op codes', async () => { describe('vrfVerify', async () => { const a = Bytes.fromHex('528b9e23d93d0e020a119d7ba213f6beb1c1f3495a217166ecd20f5a70e7c2d7') - const b = Bytes.fromHex<80>( + const b = Bytes.fromHex( '372a3afb42f55449c94aaa5f274f26543e77e8d8af4babee1a6fbc1c0391aa9e6e0b8d8d7f4ed045d5b517fea8ad3566025ae90d2f29f632e38384b4c4f5b9eb741c6e446b0f540c1b3761d814438b04', - ) + ).toFixed({ length: 80 }) - const c = Bytes.fromHex<32>('3a2740da7a0788ebb12a52154acbcca1813c128ca0b249e93f8eb6563fee418d') + const c = Bytes.fromHex('3a2740da7a0788ebb12a52154acbcca1813c128ca0b249e93f8eb6563fee418d').toFixed({ length: 32 }) test('should throw not available error', async () => { const mockedVrfVerify = op.vrfVerify as Mock @@ -313,7 +313,7 @@ describe('crypto op codes', async () => { asUint8Array(c), ) const mockedVrfVerify = op.vrfVerify as Mock - mockedVrfVerify.mockReturnValue([Bytes<64>(new Uint8Array(avmResult[0])), avmResult[1]]) + mockedVrfVerify.mockReturnValue([Bytes(new Uint8Array(avmResult[0])).toFixed({ length: 64 }), avmResult[1]]) const result = op.vrfVerify(VrfVerify.VrfAlgorand, asBytes(a), b, c) expect(asUint8Array(result[0])).toEqual(new Uint8Array(avmResult[0])) @@ -338,7 +338,7 @@ describe('crypto op codes', async () => { asUint8Array(a), ) const mockedMimc = op.mimc as Mock - mockedMimc.mockReturnValue(Bytes(avmResult)) + mockedMimc.mockReturnValue(Bytes(avmResult).toFixed({ length: 32 })) const result = op.mimc(MimcConfigurations.BN254Mp110, Bytes(a)) expect(result).toEqual(avmResult) @@ -396,9 +396,9 @@ const generateEcdsaTestData = (v: Ecdsa) => { const recoveryId = 0 // Recovery ID is typically 0 or 1 return { - data: Bytes<32>(new Uint8Array(messageHash)), - r: Bytes<32>(new Uint8Array(signature.r.toArray('be', 32))), - s: Bytes<32>(new Uint8Array(signature.s.toArray('be', 32))), + data: Bytes(new Uint8Array(messageHash)).toFixed({ length: 32 }), + r: Bytes(new Uint8Array(signature.r.toArray('be', 32))).toFixed({ length: 32 }), + s: Bytes(new Uint8Array(signature.s.toArray('be', 32))).toFixed({ length: 32 }), recoveryId: Uint64Cls.fromCompat(recoveryId), pubkeyX: Bytes(new Uint8Array(pk.slice(0, 32))), pubkeyY: Bytes(new Uint8Array(pk.slice(32))), diff --git a/tests/primitives/bytes.algo.spec.ts b/tests/primitives/bytes.algo.spec.ts index a3546e5..46b733c 100644 --- a/tests/primitives/bytes.algo.spec.ts +++ b/tests/primitives/bytes.algo.spec.ts @@ -1,5 +1,5 @@ import type { bytes } from '@algorandfoundation/algorand-typescript' -import { Bytes, FixedArray } from '@algorandfoundation/algorand-typescript' +import { Bytes, FixedArray, op } from '@algorandfoundation/algorand-typescript' import { encodingUtil } from '@algorandfoundation/puya-ts' import { beforeAll, describe, expect, it } from 'vitest' import { MAX_BYTES_SIZE } from '../../src/constants' @@ -200,19 +200,19 @@ describe('Bytes', async () => { describe('fixed size', () => { it('should be able to create fixed size bytes with no parameter', () => { - const x = Bytes<32>() + const x = op.bzero(32) expect(x.length).toEqual(32) - expect(x).toEqual(Bytes.fromHex<32>('0000000000000000000000000000000000000000000000000000000000000000')) - expect(x).toEqual(Bytes.fromBase64<32>('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=')) - expect(x).toEqual(Bytes.fromBase32<32>('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==')) + expect(x).toEqual(Bytes.fromHex('0000000000000000000000000000000000000000000000000000000000000000').toFixed({ length: 32 })) + expect(x).toEqual(Bytes.fromBase64('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=').toFixed({ length: 32 })) + expect(x).toEqual(Bytes.fromBase32('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==').toFixed({ length: 32 })) }) it('should be able to create fixed size bytes with parameter', () => { - const x1 = Bytes<32>(new Uint8Array(32)) + const x1 = Bytes(new Uint8Array(32)).toFixed({ length: 32 }) expect(x1.length).toEqual(32) - expect(x1).toEqual(Bytes<32>()) + expect(x1).toEqual(op.bzero(32)) - const x2 = Bytes<32>('abcdefghijklmnopqrstuvwxyz123456') + const x2 = Bytes('abcdefghijklmnopqrstuvwxyz123456').toFixed({ length: 32 }) expect(x2.length).toEqual(32) expect(x2).toEqual(Bytes('abcdefghijklmnopqrstuvwxyz123456')) expect(x2).toEqual(Bytes.fromHex('6162636465666768696a6b6c6d6e6f707172737475767778797a313233343536')) @@ -228,18 +228,18 @@ describe('Bytes', async () => { expect(x1.length).toEqual(2) expect(x1[0].length).toEqual(32) expect(x1[1].length).toEqual(32) - expect(x1[0]).toEqual(Bytes<32>(new Uint8Array(32))) - expect(x1[1]).toEqual(Bytes<32>(new Uint8Array(32))) + expect(x1[0]).toEqual(op.bzero(32)) + expect(x1[1]).toEqual(op.bzero(32)) - const x2 = decodeArc4, 2>>(Bytes<64>()) + const x2 = decodeArc4, 2>>(op.bzero(64)) expect(x2.length).toEqual(2) expect(x2[0].length).toEqual(32) expect(x2[1].length).toEqual(32) - const x3 = convertBytes, 2>>(Bytes<64>(), { strategy: 'unsafe-cast' }) + const x3 = convertBytes, 2>>(op.bzero(64), { strategy: 'unsafe-cast' }) expect(x3.length).toEqual(2) - expect(x3[0].bytes).toEqual(Bytes.fromHex<32>('0000000000000000000000000000000000000000000000000000000000000000')) - expect(x3[1].bytes).toEqual(Bytes.fromHex<32>('0000000000000000000000000000000000000000000000000000000000000000')) + expect(x3[0].bytes).toEqual(Bytes.fromHex('0000000000000000000000000000000000000000000000000000000000000000').toFixed({ length: 32 })) + expect(x3[1].bytes).toEqual(Bytes.fromHex('0000000000000000000000000000000000000000000000000000000000000000').toFixed({ length: 32 })) }) }) }) diff --git a/tests/references/asset.algo.spec.ts b/tests/references/asset.algo.spec.ts index 5ee954c..23fc862 100644 --- a/tests/references/asset.algo.spec.ts +++ b/tests/references/asset.algo.spec.ts @@ -1,4 +1,4 @@ -import { Account, Bytes, Uint64 } from '@algorandfoundation/algorand-typescript' +import { Account, op, Uint64 } from '@algorandfoundation/algorand-typescript' import { afterEach, describe, expect, it, test } from 'vitest' import { TestExecutionContext } from '../../src' import { AssetCls } from '../../src/impl/reference' @@ -55,7 +55,7 @@ describe('Asset', () => { unitName: asBytes('TEST'), name: asBytes('Test Asset'), url: asBytes('https://test.com'), - metadataHash: Bytes<32>(new Uint8Array(32)), + metadataHash: op.bzero(32), manager: Account(), freeze: Account(), clawback: Account(),