diff --git a/biome.json b/biome.json index 1851a12..2ac04d2 100644 --- a/biome.json +++ b/biome.json @@ -23,9 +23,7 @@ "formatter": { "enabled": true, "indentStyle": "space", - "includes": [ - "**" - ] + "includes": ["**"] }, "assist": { "actions": { @@ -96,9 +94,7 @@ "noConsole": { "level": "error", "options": { - "allow": [ - "log" - ] + "allow": ["log"] } } }, @@ -115,4 +111,4 @@ "indentStyle": "space" } } -} \ No newline at end of file +} diff --git a/packages/simulator/src/factory/createSimulator.ts b/packages/simulator/src/factory/createSimulator.ts index 9f1dd24..5144e1b 100644 --- a/packages/simulator/src/factory/createSimulator.ts +++ b/packages/simulator/src/factory/createSimulator.ts @@ -1,4 +1,7 @@ -import type { WitnessContext } from '@midnight-ntwrk/compact-runtime'; +import type { + EncodedZswapLocalState, + WitnessContext, +} from '@midnight-ntwrk/compact-runtime'; import { sampleContractAddress } from '@midnight-ntwrk/zswap'; import { CircuitContextManager } from '../core/CircuitContextManager.js'; import { ContractSimulator } from '../core/ContractSimulator.js'; @@ -173,5 +176,18 @@ export function createSimulator( contractAddress: circuitCtx.transactionContext.address, }; } + + /** + * Gets the current Zswap local state containing coin inputs/outputs and transaction data. + * + * @returns The encoded Zswap state including: + * - `coinPublicKey`: The public key associated with this transaction + * - `currentIndex`: The current index in the Zswap state + * - `inputs`: Array of consumed coin inputs + * - `outputs`: Array of created coin outputs + */ + public getZswapState(): EncodedZswapLocalState { + return this.circuitContext.currentZswapLocalState; + } }; } diff --git a/packages/simulator/src/index.ts b/packages/simulator/src/index.ts index 9785188..59523ed 100644 --- a/packages/simulator/src/index.ts +++ b/packages/simulator/src/index.ts @@ -9,6 +9,6 @@ export type { ExtractImpureCircuits, ExtractPureCircuits, IContractSimulator, - IMinimalContract + IMinimalContract, } from './types/index.js'; export type { BaseSimulatorOptions } from './types/Options.js'; diff --git a/packages/simulator/test/fixtures/sample-contracts/UTXO.compact b/packages/simulator/test/fixtures/sample-contracts/UTXO.compact new file mode 100644 index 0000000..9cdc469 --- /dev/null +++ b/packages/simulator/test/fixtures/sample-contracts/UTXO.compact @@ -0,0 +1,38 @@ +pragma language_version >= 0.18.0; + +import CompactStandardLibrary; + +export { ZswapCoinPublicKey, ContractAddress, Either, Maybe, CoinInfo, QualifiedCoinInfo }; + +export ledger _coin: QualifiedCoinInfo; + +export circuit mint( + domain: Bytes<32>, + amount: Uint<64>, + nonce: Bytes<32>, + recipient: Either +): [] { + mintToken(disclose(domain), disclose(amount), disclose(nonce), disclose(recipient)); +} + +export circuit sendToken( + input: QualifiedCoinInfo, + recipient: Either, + value: Uint<64> +): [] { + send(disclose(input), disclose(recipient), disclose(value)); +} + +export circuit receiveToken(coin: CoinInfo): [] { + const disclosedCoin = disclose(coin); + receive(disclosedCoin); + const thisContract = right(kernel.self()); + _coin.writeCoin(disclosedCoin, thisContract); +} + +export circuit receiveTokenSendChange(coin: CoinInfo, change: Uint<64>): [] { + const dislosedCoin = disclose(coin); + receive(dislosedCoin); + const eitherCaller = left(ownPublicKey()); + sendImmediate(dislosedCoin, eitherCaller, disclose(change)); +} diff --git a/packages/simulator/test/fixtures/sample-contracts/witnesses/UTXOWitnesses.ts b/packages/simulator/test/fixtures/sample-contracts/witnesses/UTXOWitnesses.ts new file mode 100644 index 0000000..c0fdb95 --- /dev/null +++ b/packages/simulator/test/fixtures/sample-contracts/witnesses/UTXOWitnesses.ts @@ -0,0 +1,3 @@ +export type UTXOPrivateState = Record; +export const UTXOPrivateState: UTXOPrivateState = {}; +export const UTXOWitnesses = () => ({}); diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/compiler/contract-info.json b/packages/simulator/test/fixtures/test-artifacts/UTXO/compiler/contract-info.json new file mode 100644 index 0000000..636d301 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/compiler/contract-info.json @@ -0,0 +1,278 @@ +{ + "circuits": [ + { + "name": "mint", + "pure": false, + "arguments": [ + { + "name": "domain", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "amount", + "type": { + "type-name": "Uint", + "maxval": 18446744073709551615 + } + }, + { + "name": "nonce", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "recipient", + "type": { + "type-name": "Struct", + "name": "Either", + "elements": [ + { + "name": "is_left", + "type": { + "type-name": "Boolean" + } + }, + { + "name": "left", + "type": { + "type-name": "Struct", + "name": "ZswapCoinPublicKey", + "elements": [ + { + "name": "bytes", + "type": { + "type-name": "Bytes", + "length": 32 + } + } + ] + } + }, + { + "name": "right", + "type": { + "type-name": "Struct", + "name": "ContractAddress", + "elements": [ + { + "name": "bytes", + "type": { + "type-name": "Bytes", + "length": 32 + } + } + ] + } + } + ] + } + } + ], + "result-type": { + "type-name": "Tuple", + "types": [ + ] + } + }, + { + "name": "sendToken", + "pure": false, + "arguments": [ + { + "name": "input", + "type": { + "type-name": "Struct", + "name": "QualifiedCoinInfo", + "elements": [ + { + "name": "nonce", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "color", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "value", + "type": { + "type-name": "Uint", + "maxval": 340282366920938463463374607431768211455 + } + }, + { + "name": "mt_index", + "type": { + "type-name": "Uint", + "maxval": 18446744073709551615 + } + } + ] + } + }, + { + "name": "recipient", + "type": { + "type-name": "Struct", + "name": "Either", + "elements": [ + { + "name": "is_left", + "type": { + "type-name": "Boolean" + } + }, + { + "name": "left", + "type": { + "type-name": "Struct", + "name": "ZswapCoinPublicKey", + "elements": [ + { + "name": "bytes", + "type": { + "type-name": "Bytes", + "length": 32 + } + } + ] + } + }, + { + "name": "right", + "type": { + "type-name": "Struct", + "name": "ContractAddress", + "elements": [ + { + "name": "bytes", + "type": { + "type-name": "Bytes", + "length": 32 + } + } + ] + } + } + ] + } + }, + { + "name": "value", + "type": { + "type-name": "Uint", + "maxval": 18446744073709551615 + } + } + ], + "result-type": { + "type-name": "Tuple", + "types": [ + ] + } + }, + { + "name": "receiveToken", + "pure": false, + "arguments": [ + { + "name": "coin", + "type": { + "type-name": "Struct", + "name": "CoinInfo", + "elements": [ + { + "name": "nonce", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "color", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "value", + "type": { + "type-name": "Uint", + "maxval": 340282366920938463463374607431768211455 + } + } + ] + } + } + ], + "result-type": { + "type-name": "Tuple", + "types": [ + ] + } + }, + { + "name": "receiveTokenSendChange", + "pure": false, + "arguments": [ + { + "name": "coin", + "type": { + "type-name": "Struct", + "name": "CoinInfo", + "elements": [ + { + "name": "nonce", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "color", + "type": { + "type-name": "Bytes", + "length": 32 + } + }, + { + "name": "value", + "type": { + "type-name": "Uint", + "maxval": 340282366920938463463374607431768211455 + } + } + ] + } + }, + { + "name": "change", + "type": { + "type-name": "Uint", + "maxval": 18446744073709551615 + } + } + ], + "result-type": { + "type-name": "Tuple", + "types": [ + ] + } + } + ], + "witnesses": [ + ], + "contracts": [ + ] +} diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.cjs b/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.cjs new file mode 100644 index 0000000..4716fe4 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.cjs @@ -0,0 +1,904 @@ +'use strict'; +const __compactRuntime = require('@midnight-ntwrk/compact-runtime'); +const expectedRuntimeVersionString = '0.9.0'; +const expectedRuntimeVersion = expectedRuntimeVersionString.split('-')[0].split('.').map(Number); +const actualRuntimeVersion = __compactRuntime.versionString.split('-')[0].split('.').map(Number); +if (expectedRuntimeVersion[0] != actualRuntimeVersion[0] + || (actualRuntimeVersion[0] == 0 && expectedRuntimeVersion[1] != actualRuntimeVersion[1]) + || expectedRuntimeVersion[1] > actualRuntimeVersion[1] + || (expectedRuntimeVersion[1] == actualRuntimeVersion[1] && expectedRuntimeVersion[2] > actualRuntimeVersion[2])) + throw new __compactRuntime.CompactError(`Version mismatch: compiled code expects ${expectedRuntimeVersionString}, runtime is ${__compactRuntime.versionString}`); +{ const MAX_FIELD = 52435875175126190479447740508185965837690552500527637822603658699938581184512n; + if (__compactRuntime.MAX_FIELD !== MAX_FIELD) + throw new __compactRuntime.CompactError(`compiler thinks maximum field value is ${MAX_FIELD}; run time thinks it is ${__compactRuntime.MAX_FIELD}`) +} + +const _descriptor_0 = new __compactRuntime.CompactTypeBytes(32); + +const _descriptor_1 = new __compactRuntime.CompactTypeUnsignedInteger(340282366920938463463374607431768211455n, 16); + +class _CoinInfo_0 { + alignment() { + return _descriptor_0.alignment().concat(_descriptor_0.alignment().concat(_descriptor_1.alignment())); + } + fromValue(value_0) { + return { + nonce: _descriptor_0.fromValue(value_0), + color: _descriptor_0.fromValue(value_0), + value: _descriptor_1.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_0.toValue(value_0.nonce).concat(_descriptor_0.toValue(value_0.color).concat(_descriptor_1.toValue(value_0.value))); + } +} + +const _descriptor_2 = new _CoinInfo_0(); + +const _descriptor_3 = new __compactRuntime.CompactTypeUnsignedInteger(18446744073709551615n, 8); + +class _QualifiedCoinInfo_0 { + alignment() { + return _descriptor_0.alignment().concat(_descriptor_0.alignment().concat(_descriptor_1.alignment().concat(_descriptor_3.alignment()))); + } + fromValue(value_0) { + return { + nonce: _descriptor_0.fromValue(value_0), + color: _descriptor_0.fromValue(value_0), + value: _descriptor_1.fromValue(value_0), + mt_index: _descriptor_3.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_0.toValue(value_0.nonce).concat(_descriptor_0.toValue(value_0.color).concat(_descriptor_1.toValue(value_0.value).concat(_descriptor_3.toValue(value_0.mt_index)))); + } +} + +const _descriptor_4 = new _QualifiedCoinInfo_0(); + +const _descriptor_5 = new __compactRuntime.CompactTypeBoolean(); + +class _ZswapCoinPublicKey_0 { + alignment() { + return _descriptor_0.alignment(); + } + fromValue(value_0) { + return { + bytes: _descriptor_0.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_0.toValue(value_0.bytes); + } +} + +const _descriptor_6 = new _ZswapCoinPublicKey_0(); + +class _ContractAddress_0 { + alignment() { + return _descriptor_0.alignment(); + } + fromValue(value_0) { + return { + bytes: _descriptor_0.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_0.toValue(value_0.bytes); + } +} + +const _descriptor_7 = new _ContractAddress_0(); + +class _Either_0 { + alignment() { + return _descriptor_5.alignment().concat(_descriptor_6.alignment().concat(_descriptor_7.alignment())); + } + fromValue(value_0) { + return { + is_left: _descriptor_5.fromValue(value_0), + left: _descriptor_6.fromValue(value_0), + right: _descriptor_7.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_5.toValue(value_0.is_left).concat(_descriptor_6.toValue(value_0.left).concat(_descriptor_7.toValue(value_0.right))); + } +} + +const _descriptor_8 = new _Either_0(); + +class _Maybe_0 { + alignment() { + return _descriptor_5.alignment().concat(_descriptor_2.alignment()); + } + fromValue(value_0) { + return { + is_some: _descriptor_5.fromValue(value_0), + value: _descriptor_2.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_5.toValue(value_0.is_some).concat(_descriptor_2.toValue(value_0.value)); + } +} + +const _descriptor_9 = new _Maybe_0(); + +class _SendResult_0 { + alignment() { + return _descriptor_9.alignment().concat(_descriptor_2.alignment()); + } + fromValue(value_0) { + return { + change: _descriptor_9.fromValue(value_0), + sent: _descriptor_2.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_9.toValue(value_0.change).concat(_descriptor_2.toValue(value_0.sent)); + } +} + +const _descriptor_10 = new _SendResult_0(); + +const _descriptor_11 = new __compactRuntime.CompactTypeField(); + +const _descriptor_12 = new __compactRuntime.CompactTypeVector(2, _descriptor_0); + +const _descriptor_13 = new __compactRuntime.CompactTypeVector(2, _descriptor_11); + +const _descriptor_14 = new __compactRuntime.CompactTypeBytes(6); + +class _CoinPreimage_0 { + alignment() { + return _descriptor_2.alignment().concat(_descriptor_5.alignment().concat(_descriptor_0.alignment().concat(_descriptor_14.alignment()))); + } + fromValue(value_0) { + return { + info: _descriptor_2.fromValue(value_0), + dataType: _descriptor_5.fromValue(value_0), + data: _descriptor_0.fromValue(value_0), + domain_sep: _descriptor_14.fromValue(value_0) + } + } + toValue(value_0) { + return _descriptor_2.toValue(value_0.info).concat(_descriptor_5.toValue(value_0.dataType).concat(_descriptor_0.toValue(value_0.data).concat(_descriptor_14.toValue(value_0.domain_sep)))); + } +} + +const _descriptor_15 = new _CoinPreimage_0(); + +const _descriptor_16 = new __compactRuntime.CompactTypeUnsignedInteger(255n, 1); + +class Contract { + witnesses; + constructor(...args_0) { + if (args_0.length !== 1) { + throw new __compactRuntime.CompactError(`Contract constructor: expected 1 argument, received ${args_0.length}`); + } + const witnesses_0 = args_0[0]; + if (typeof(witnesses_0) !== 'object') { + throw new __compactRuntime.CompactError('first (witnesses) argument to Contract constructor is not an object'); + } + this.witnesses = witnesses_0; + this.circuits = { + mint: (...args_1) => { + if (args_1.length !== 5) { + throw new __compactRuntime.CompactError(`mint: expected 5 arguments (as invoked from Typescript), received ${args_1.length}`); + } + const contextOrig_0 = args_1[0]; + const domain_0 = args_1[1]; + const amount_0 = args_1[2]; + const nonce_0 = args_1[3]; + const recipient_0 = args_1[4]; + if (!(typeof(contextOrig_0) === 'object' && contextOrig_0.originalState != undefined && contextOrig_0.transactionContext != undefined)) { + __compactRuntime.type_error('mint', + 'argument 1 (as invoked from Typescript)', + 'UTXO.compact line 9 char 1', + 'CircuitContext', + contextOrig_0) + } + if (!(domain_0.buffer instanceof ArrayBuffer && domain_0.BYTES_PER_ELEMENT === 1 && domain_0.length === 32)) { + __compactRuntime.type_error('mint', + 'argument 1 (argument 2 as invoked from Typescript)', + 'UTXO.compact line 9 char 1', + 'Bytes<32>', + domain_0) + } + if (!(typeof(amount_0) === 'bigint' && amount_0 >= 0n && amount_0 <= 18446744073709551615n)) { + __compactRuntime.type_error('mint', + 'argument 2 (argument 3 as invoked from Typescript)', + 'UTXO.compact line 9 char 1', + 'Uint<0..18446744073709551615>', + amount_0) + } + if (!(nonce_0.buffer instanceof ArrayBuffer && nonce_0.BYTES_PER_ELEMENT === 1 && nonce_0.length === 32)) { + __compactRuntime.type_error('mint', + 'argument 3 (argument 4 as invoked from Typescript)', + 'UTXO.compact line 9 char 1', + 'Bytes<32>', + nonce_0) + } + if (!(typeof(recipient_0) === 'object' && typeof(recipient_0.is_left) === 'boolean' && typeof(recipient_0.left) === 'object' && recipient_0.left.bytes.buffer instanceof ArrayBuffer && recipient_0.left.bytes.BYTES_PER_ELEMENT === 1 && recipient_0.left.bytes.length === 32 && typeof(recipient_0.right) === 'object' && recipient_0.right.bytes.buffer instanceof ArrayBuffer && recipient_0.right.bytes.BYTES_PER_ELEMENT === 1 && recipient_0.right.bytes.length === 32)) { + __compactRuntime.type_error('mint', + 'argument 4 (argument 5 as invoked from Typescript)', + 'UTXO.compact line 9 char 1', + 'struct Either>, right: struct ContractAddress>>', + recipient_0) + } + const context = { ...contextOrig_0 }; + const partialProofData = { + input: { + value: _descriptor_0.toValue(domain_0).concat(_descriptor_3.toValue(amount_0).concat(_descriptor_0.toValue(nonce_0).concat(_descriptor_8.toValue(recipient_0)))), + alignment: _descriptor_0.alignment().concat(_descriptor_3.alignment().concat(_descriptor_0.alignment().concat(_descriptor_8.alignment()))) + }, + output: undefined, + publicTranscript: [], + privateTranscriptOutputs: [] + }; + const result_0 = this._mint_0(context, + partialProofData, + domain_0, + amount_0, + nonce_0, + recipient_0); + partialProofData.output = { value: [], alignment: [] }; + return { result: result_0, context: context, proofData: partialProofData }; + }, + sendToken: (...args_1) => { + if (args_1.length !== 4) { + throw new __compactRuntime.CompactError(`sendToken: expected 4 arguments (as invoked from Typescript), received ${args_1.length}`); + } + const contextOrig_0 = args_1[0]; + const input_0 = args_1[1]; + const recipient_0 = args_1[2]; + const value_0 = args_1[3]; + if (!(typeof(contextOrig_0) === 'object' && contextOrig_0.originalState != undefined && contextOrig_0.transactionContext != undefined)) { + __compactRuntime.type_error('sendToken', + 'argument 1 (as invoked from Typescript)', + 'UTXO.compact line 18 char 1', + 'CircuitContext', + contextOrig_0) + } + if (!(typeof(input_0) === 'object' && input_0.nonce.buffer instanceof ArrayBuffer && input_0.nonce.BYTES_PER_ELEMENT === 1 && input_0.nonce.length === 32 && input_0.color.buffer instanceof ArrayBuffer && input_0.color.BYTES_PER_ELEMENT === 1 && input_0.color.length === 32 && typeof(input_0.value) === 'bigint' && input_0.value >= 0n && input_0.value <= 340282366920938463463374607431768211455n && typeof(input_0.mt_index) === 'bigint' && input_0.mt_index >= 0n && input_0.mt_index <= 18446744073709551615n)) { + __compactRuntime.type_error('sendToken', + 'argument 1 (argument 2 as invoked from Typescript)', + 'UTXO.compact line 18 char 1', + 'struct QualifiedCoinInfo, color: Bytes<32>, value: Uint<0..340282366920938463463374607431768211455>, mt_index: Uint<0..18446744073709551615>>', + input_0) + } + if (!(typeof(recipient_0) === 'object' && typeof(recipient_0.is_left) === 'boolean' && typeof(recipient_0.left) === 'object' && recipient_0.left.bytes.buffer instanceof ArrayBuffer && recipient_0.left.bytes.BYTES_PER_ELEMENT === 1 && recipient_0.left.bytes.length === 32 && typeof(recipient_0.right) === 'object' && recipient_0.right.bytes.buffer instanceof ArrayBuffer && recipient_0.right.bytes.BYTES_PER_ELEMENT === 1 && recipient_0.right.bytes.length === 32)) { + __compactRuntime.type_error('sendToken', + 'argument 2 (argument 3 as invoked from Typescript)', + 'UTXO.compact line 18 char 1', + 'struct Either>, right: struct ContractAddress>>', + recipient_0) + } + if (!(typeof(value_0) === 'bigint' && value_0 >= 0n && value_0 <= 18446744073709551615n)) { + __compactRuntime.type_error('sendToken', + 'argument 3 (argument 4 as invoked from Typescript)', + 'UTXO.compact line 18 char 1', + 'Uint<0..18446744073709551615>', + value_0) + } + const context = { ...contextOrig_0 }; + const partialProofData = { + input: { + value: _descriptor_4.toValue(input_0).concat(_descriptor_8.toValue(recipient_0).concat(_descriptor_3.toValue(value_0))), + alignment: _descriptor_4.alignment().concat(_descriptor_8.alignment().concat(_descriptor_3.alignment())) + }, + output: undefined, + publicTranscript: [], + privateTranscriptOutputs: [] + }; + const result_0 = this._sendToken_0(context, + partialProofData, + input_0, + recipient_0, + value_0); + partialProofData.output = { value: [], alignment: [] }; + return { result: result_0, context: context, proofData: partialProofData }; + }, + receiveToken: (...args_1) => { + if (args_1.length !== 2) { + throw new __compactRuntime.CompactError(`receiveToken: expected 2 arguments (as invoked from Typescript), received ${args_1.length}`); + } + const contextOrig_0 = args_1[0]; + const coin_0 = args_1[1]; + if (!(typeof(contextOrig_0) === 'object' && contextOrig_0.originalState != undefined && contextOrig_0.transactionContext != undefined)) { + __compactRuntime.type_error('receiveToken', + 'argument 1 (as invoked from Typescript)', + 'UTXO.compact line 26 char 1', + 'CircuitContext', + contextOrig_0) + } + if (!(typeof(coin_0) === 'object' && coin_0.nonce.buffer instanceof ArrayBuffer && coin_0.nonce.BYTES_PER_ELEMENT === 1 && coin_0.nonce.length === 32 && coin_0.color.buffer instanceof ArrayBuffer && coin_0.color.BYTES_PER_ELEMENT === 1 && coin_0.color.length === 32 && typeof(coin_0.value) === 'bigint' && coin_0.value >= 0n && coin_0.value <= 340282366920938463463374607431768211455n)) { + __compactRuntime.type_error('receiveToken', + 'argument 1 (argument 2 as invoked from Typescript)', + 'UTXO.compact line 26 char 1', + 'struct CoinInfo, color: Bytes<32>, value: Uint<0..340282366920938463463374607431768211455>>', + coin_0) + } + const context = { ...contextOrig_0 }; + const partialProofData = { + input: { + value: _descriptor_2.toValue(coin_0), + alignment: _descriptor_2.alignment() + }, + output: undefined, + publicTranscript: [], + privateTranscriptOutputs: [] + }; + const result_0 = this._receiveToken_0(context, partialProofData, coin_0); + partialProofData.output = { value: [], alignment: [] }; + return { result: result_0, context: context, proofData: partialProofData }; + }, + receiveTokenSendChange: (...args_1) => { + if (args_1.length !== 3) { + throw new __compactRuntime.CompactError(`receiveTokenSendChange: expected 3 arguments (as invoked from Typescript), received ${args_1.length}`); + } + const contextOrig_0 = args_1[0]; + const coin_0 = args_1[1]; + const change_0 = args_1[2]; + if (!(typeof(contextOrig_0) === 'object' && contextOrig_0.originalState != undefined && contextOrig_0.transactionContext != undefined)) { + __compactRuntime.type_error('receiveTokenSendChange', + 'argument 1 (as invoked from Typescript)', + 'UTXO.compact line 33 char 1', + 'CircuitContext', + contextOrig_0) + } + if (!(typeof(coin_0) === 'object' && coin_0.nonce.buffer instanceof ArrayBuffer && coin_0.nonce.BYTES_PER_ELEMENT === 1 && coin_0.nonce.length === 32 && coin_0.color.buffer instanceof ArrayBuffer && coin_0.color.BYTES_PER_ELEMENT === 1 && coin_0.color.length === 32 && typeof(coin_0.value) === 'bigint' && coin_0.value >= 0n && coin_0.value <= 340282366920938463463374607431768211455n)) { + __compactRuntime.type_error('receiveTokenSendChange', + 'argument 1 (argument 2 as invoked from Typescript)', + 'UTXO.compact line 33 char 1', + 'struct CoinInfo, color: Bytes<32>, value: Uint<0..340282366920938463463374607431768211455>>', + coin_0) + } + if (!(typeof(change_0) === 'bigint' && change_0 >= 0n && change_0 <= 18446744073709551615n)) { + __compactRuntime.type_error('receiveTokenSendChange', + 'argument 2 (argument 3 as invoked from Typescript)', + 'UTXO.compact line 33 char 1', + 'Uint<0..18446744073709551615>', + change_0) + } + const context = { ...contextOrig_0 }; + const partialProofData = { + input: { + value: _descriptor_2.toValue(coin_0).concat(_descriptor_3.toValue(change_0)), + alignment: _descriptor_2.alignment().concat(_descriptor_3.alignment()) + }, + output: undefined, + publicTranscript: [], + privateTranscriptOutputs: [] + }; + const result_0 = this._receiveTokenSendChange_0(context, + partialProofData, + coin_0, + change_0); + partialProofData.output = { value: [], alignment: [] }; + return { result: result_0, context: context, proofData: partialProofData }; + } + }; + this.impureCircuits = { + mint: this.circuits.mint, + sendToken: this.circuits.sendToken, + receiveToken: this.circuits.receiveToken, + receiveTokenSendChange: this.circuits.receiveTokenSendChange + }; + } + initialState(...args_0) { + if (args_0.length !== 1) { + throw new __compactRuntime.CompactError(`Contract state constructor: expected 1 argument (as invoked from Typescript), received ${args_0.length}`); + } + const constructorContext_0 = args_0[0]; + if (typeof(constructorContext_0) !== 'object') { + throw new __compactRuntime.CompactError(`Contract state constructor: expected 'constructorContext' in argument 1 (as invoked from Typescript) to be an object`); + } + if (!('initialZswapLocalState' in constructorContext_0)) { + throw new __compactRuntime.CompactError(`Contract state constructor: expected 'initialZswapLocalState' in argument 1 (as invoked from Typescript)`); + } + if (typeof(constructorContext_0.initialZswapLocalState) !== 'object') { + throw new __compactRuntime.CompactError(`Contract state constructor: expected 'initialZswapLocalState' in argument 1 (as invoked from Typescript) to be an object`); + } + const state_0 = new __compactRuntime.ContractState(); + let stateValue_0 = __compactRuntime.StateValue.newArray(); + stateValue_0 = stateValue_0.arrayPush(__compactRuntime.StateValue.newNull()); + state_0.data = stateValue_0; + state_0.setOperation('mint', new __compactRuntime.ContractOperation()); + state_0.setOperation('sendToken', new __compactRuntime.ContractOperation()); + state_0.setOperation('receiveToken', new __compactRuntime.ContractOperation()); + state_0.setOperation('receiveTokenSendChange', new __compactRuntime.ContractOperation()); + const context = { + originalState: state_0, + currentPrivateState: constructorContext_0.initialPrivateState, + currentZswapLocalState: constructorContext_0.initialZswapLocalState, + transactionContext: new __compactRuntime.QueryContext(state_0.data, __compactRuntime.dummyContractAddress()) + }; + const partialProofData = { + input: { value: [], alignment: [] }, + output: undefined, + publicTranscript: [], + privateTranscriptOutputs: [] + }; + Contract._query(context, + partialProofData, + [ + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() }).encode() } }, + { push: { storage: true, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_4.toValue({ nonce: new Uint8Array(32), color: new Uint8Array(32), value: 0n, mt_index: 0n }), + alignment: _descriptor_4.alignment() }).encode() } }, + { ins: { cached: false, n: 1 } }]); + state_0.data = context.transactionContext.state; + return { + currentContractState: state_0, + currentPrivateState: context.currentPrivateState, + currentZswapLocalState: context.currentZswapLocalState + } + } + _some_0(value_0) { return { is_some: true, value: value_0 }; } + _none_0() { + return { is_some: false, + value: + { nonce: new Uint8Array(32), color: new Uint8Array(32), value: 0n } }; + } + _left_0(value_0) { + return { is_left: true, left: value_0, right: { bytes: new Uint8Array(32) } }; + } + _right_0(value_0) { + return { is_left: false, left: { bytes: new Uint8Array(32) }, right: value_0 }; + } + _transientHash_0(value_0) { + const result_0 = __compactRuntime.transientHash(_descriptor_13, value_0); + return result_0; + } + _persistentHash_0(value_0) { + const result_0 = __compactRuntime.persistentHash(_descriptor_15, value_0); + return result_0; + } + _persistentCommit_0(value_0, rand_0) { + const result_0 = __compactRuntime.persistentCommit(_descriptor_12, + value_0, + rand_0); + return result_0; + } + _degradeToTransient_0(x_0) { + const result_0 = __compactRuntime.degradeToTransient(x_0); + return result_0; + } + _upgradeFromTransient_0(x_0) { + const result_0 = __compactRuntime.upgradeFromTransient(x_0); + return result_0; + } + _ownPublicKey_0(context, partialProofData) { + const result_0 = __compactRuntime.ownPublicKey(context); + partialProofData.privateTranscriptOutputs.push({ + value: _descriptor_6.toValue(result_0), + alignment: _descriptor_6.alignment() + }); + return result_0; + } + _createZswapInput_0(context, partialProofData, coin_0) { + const result_0 = __compactRuntime.createZswapInput(context, coin_0); + partialProofData.privateTranscriptOutputs.push({ + value: [], + alignment: [] + }); + return result_0; + } + _createZswapOutput_0(context, partialProofData, coin_0, recipient_0) { + const result_0 = __compactRuntime.createZswapOutput(context, + coin_0, + recipient_0); + partialProofData.privateTranscriptOutputs.push({ + value: [], + alignment: [] + }); + return result_0; + } + _tokenType_0(domain_sep_0, contractAddress_0) { + return this._persistentCommit_0([domain_sep_0, contractAddress_0.bytes], + new Uint8Array([109, 105, 100, 110, 105, 103, 104, 116, 58, 100, 101, 114, 105, 118, 101, 95, 116, 111, 107, 101, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])); + } + _mintToken_0(context, + partialProofData, + domain_sep_0, + value_0, + nonce_0, + recipient_0) + { + const coin_0 = { nonce: nonce_0, + color: + this._tokenType_0(domain_sep_0, + _descriptor_7.fromValue(Contract._query(context, + partialProofData, + [ + { dup: { n: 2 } }, + { idx: { cached: true, + pushPath: false, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() } }] } }, + { popeq: { cached: true, + result: undefined } }]).value)), + value: value_0 }; + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(4n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(domain_sep_0), + alignment: _descriptor_0.alignment() }).encode() } }, + { dup: { n: 1 } }, + { dup: { n: 1 } }, + 'member', + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_3.toValue(value_0), + alignment: _descriptor_3.alignment() }).encode() } }, + { swap: { n: 0 } }, + 'neg', + { branch: { skip: 4 } }, + { dup: { n: 2 } }, + { dup: { n: 2 } }, + { idx: { cached: true, + pushPath: false, + path: [ { tag: 'stack' }] } }, + 'add', + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + this._createZswapOutput_0(context, partialProofData, coin_0, recipient_0); + const cm_0 = this._coinCommitment_0(coin_0, recipient_0); + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(2n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(cm_0), + alignment: _descriptor_0.alignment() }).encode() } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newNull().encode() } }, + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + return coin_0; + } + _receive_0(context, partialProofData, coin_0) { + const recipient_0 = this._right_0(_descriptor_7.fromValue(Contract._query(context, + partialProofData, + [ + { dup: { n: 2 } }, + { idx: { cached: true, + pushPath: false, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() } }] } }, + { popeq: { cached: true, + result: undefined } }]).value)); + this._createZswapOutput_0(context, partialProofData, coin_0, recipient_0); + const tmp_0 = this._coinCommitment_0(coin_0, recipient_0); + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(1n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(tmp_0), + alignment: _descriptor_0.alignment() }).encode() } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newNull().encode() } }, + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + return []; + } + _send_0(context, partialProofData, input_0, recipient_0, value_0) { + const selfAddr_0 = _descriptor_7.fromValue(Contract._query(context, + partialProofData, + [ + { dup: { n: 2 } }, + { idx: { cached: true, + pushPath: false, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() } }] } }, + { popeq: { cached: true, + result: undefined } }]).value); + this._createZswapInput_0(context, partialProofData, input_0); + const tmp_0 = this._coinNullifier_0(this._downcastQualifiedCoin_0(input_0), + selfAddr_0); + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(tmp_0), + alignment: _descriptor_0.alignment() }).encode() } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newNull().encode() } }, + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + let t_0; + const change_0 = (t_0 = input_0.value, + (__compactRuntime.assert(!(t_0 < value_0), + 'result of subtraction would be negative'), + t_0 - value_0)); + const output_0 = { nonce: + this._upgradeFromTransient_0(this._transientHash_0([__compactRuntime.convertBytesToField(28, + new Uint8Array([109, 105, 100, 110, 105, 103, 104, 116, 58, 107, 101, 114, 110, 101, 108, 58, 110, 111, 110, 99, 101, 95, 101, 118, 111, 108, 118, 101]), + ''), + this._degradeToTransient_0(input_0.nonce)])), + color: input_0.color, + value: value_0 }; + this._createZswapOutput_0(context, partialProofData, output_0, recipient_0); + const tmp_1 = this._coinCommitment_0(output_0, recipient_0); + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(2n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(tmp_1), + alignment: _descriptor_0.alignment() }).encode() } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newNull().encode() } }, + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + if (this._equal_0(change_0, 0n)) { + return { change: this._none_0(), sent: output_0 }; + } else { + const changeCoin_0 = { nonce: + this._upgradeFromTransient_0(this._transientHash_0([__compactRuntime.convertBytesToField(30, + new Uint8Array([109, 105, 100, 110, 105, 103, 104, 116, 58, 107, 101, 114, 110, 101, 108, 58, 110, 111, 110, 99, 101, 95, 101, 118, 111, 108, 118, 101, 47, 50]), + ''), + this._degradeToTransient_0(input_0.nonce)])), + color: input_0.color, + value: change_0 }; + this._createZswapOutput_0(context, + partialProofData, + changeCoin_0, + this._right_0(selfAddr_0)); + const cm_0 = this._coinCommitment_0(changeCoin_0, + this._right_0(selfAddr_0)); + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(2n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(cm_0), + alignment: _descriptor_0.alignment() }).encode() } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newNull().encode() } }, + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + Contract._query(context, + partialProofData, + [ + { swap: { n: 0 } }, + { idx: { cached: true, + pushPath: true, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(1n), + alignment: _descriptor_16.alignment() } }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_0.toValue(cm_0), + alignment: _descriptor_0.alignment() }).encode() } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newNull().encode() } }, + { ins: { cached: true, n: 2 } }, + { swap: { n: 0 } }]); + return { change: this._some_0(changeCoin_0), sent: output_0 }; + } + } + _sendImmediate_0(context, partialProofData, input_0, target_0, value_0) { + return this._send_0(context, + partialProofData, + this._upcastQualifiedCoin_0(input_0), + target_0, + value_0); + } + _downcastQualifiedCoin_0(coin_0) { + return { nonce: coin_0.nonce, color: coin_0.color, value: coin_0.value }; + } + _upcastQualifiedCoin_0(coin_0) { + return { nonce: coin_0.nonce, + color: coin_0.color, + value: coin_0.value, + mt_index: 0n }; + } + _coinCommitment_0(coin_0, recipient_0) { + return this._persistentHash_0({ info: coin_0, + dataType: recipient_0.is_left, + data: + recipient_0.is_left ? + recipient_0.left.bytes : + recipient_0.right.bytes, + domain_sep: + new Uint8Array([109, 100, 110, 58, 99, 99]) }); + } + _coinNullifier_0(coin_0, addr_0) { + return this._persistentHash_0({ info: coin_0, + dataType: false, + data: addr_0.bytes, + domain_sep: + new Uint8Array([109, 100, 110, 58, 99, 110]) }); + } + _mint_0(context, partialProofData, domain_0, amount_0, nonce_0, recipient_0) { + this._mintToken_0(context, + partialProofData, + domain_0, + amount_0, + nonce_0, + recipient_0); + return []; + } + _sendToken_0(context, partialProofData, input_0, recipient_0, value_0) { + this._send_0(context, partialProofData, input_0, recipient_0, value_0); + return []; + } + _receiveToken_0(context, partialProofData, coin_0) { + const disclosedCoin_0 = coin_0; + this._receive_0(context, partialProofData, disclosedCoin_0); + const thisContract_0 = this._right_0(_descriptor_7.fromValue(Contract._query(context, + partialProofData, + [ + { dup: { n: 2 } }, + { idx: { cached: true, + pushPath: false, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() } }] } }, + { popeq: { cached: true, + result: undefined } }]).value)); + __compactRuntime.hasCoinCommitment(context, disclosedCoin_0, thisContract_0) ? Contract._query(context, + partialProofData, + [ + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() }).encode() } }, + { dup: { n: 3 } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell(__compactRuntime.coinCommitment( + { value: _descriptor_2.toValue(disclosedCoin_0), + alignment: _descriptor_2.alignment() }, + { value: _descriptor_8.toValue(thisContract_0), + alignment: _descriptor_8.alignment() } + )).encode() } }, + { idx: { cached: true, + pushPath: false, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(1n), + alignment: _descriptor_16.alignment() } }, + { tag: 'stack' }] } }, + { push: { storage: false, + value: __compactRuntime.StateValue.newCell({ value: _descriptor_2.toValue(disclosedCoin_0), + alignment: _descriptor_2.alignment() }).encode() } }, + { swap: { n: 0 } }, + { concat: { cached: true, + n: 91 } }, + { ins: { cached: false, + n: 1 } }]) : (() => { throw new __compactRuntime.CompactError(`UTXO.compact line 30 char 3: Coin commitment not found. Check the coin has been received (or call 'createZswapOutput')`); })(); + return []; + } + _receiveTokenSendChange_0(context, partialProofData, coin_0, change_0) { + const dislosedCoin_0 = coin_0; + this._receive_0(context, partialProofData, dislosedCoin_0); + const eitherCaller_0 = this._left_0(this._ownPublicKey_0(context, + partialProofData)); + this._sendImmediate_0(context, + partialProofData, + dislosedCoin_0, + eitherCaller_0, + change_0); + return []; + } + _equal_0(x0, y0) { + if (x0 !== y0) { return false; } + return true; + } + static _query(context, partialProofData, prog) { + var res; + try { + res = context.transactionContext.query(prog, __compactRuntime.CostModel.dummyCostModel()); + } catch (err) { + throw new __compactRuntime.CompactError(err.toString()); + } + context.transactionContext = res.context; + var reads = res.events.filter((e) => e.tag === 'read'); + var i = 0; + partialProofData.publicTranscript = partialProofData.publicTranscript.concat(prog.map((op) => { + if(typeof(op) === 'object' && 'popeq' in op) { + return { popeq: { + ...op.popeq, + result: reads[i++].content, + } }; + } else { + return op; + } + })); + if(res.events.length == 1 && res.events[0].tag === 'read') { + return res.events[0].content; + } else { + return res.events; + } + } +} +function ledger(state) { + const context = { + originalState: state, + transactionContext: new __compactRuntime.QueryContext(state, __compactRuntime.dummyContractAddress()) + }; + const partialProofData = { + input: { value: [], alignment: [] }, + output: undefined, + publicTranscript: [], + privateTranscriptOutputs: [] + }; + return { + get _coin() { + return _descriptor_4.fromValue(Contract._query(context, + partialProofData, + [ + { dup: { n: 0 } }, + { idx: { cached: false, + pushPath: false, + path: [ + { tag: 'value', + value: { value: _descriptor_16.toValue(0n), + alignment: _descriptor_16.alignment() } }] } }, + { popeq: { cached: false, + result: undefined } }]).value); + } + }; +} +const _emptyContext = { + originalState: new __compactRuntime.ContractState(), + transactionContext: new __compactRuntime.QueryContext(new __compactRuntime.ContractState().data, __compactRuntime.dummyContractAddress()) +}; +const _dummyContract = new Contract({ }); +const pureCircuits = {}; +const contractReferenceLocations = { tag: 'publicLedgerArray', indices: { } }; +exports.Contract = Contract; +exports.ledger = ledger; +exports.pureCircuits = pureCircuits; +exports.contractReferenceLocations = contractReferenceLocations; +//# sourceMappingURL=index.cjs.map diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.cjs.map b/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.cjs.map new file mode 100644 index 0000000..6b79216 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.cjs.map @@ -0,0 +1,8 @@ +{ + "version": 3, + "file": "index.cjs", + "sourceRoot": "../../../../../", + "sources": ["test/fixtures/sample-contracts/UTXO.compact", "compiler/standard-library.compact"], + "names": [], + "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAA;;;;;;;;;;MAQA,AAAA,IAOC;;;;;cANC,QAAiB;cACjB,QAAgB;cAChB,OAAgB;cAChB,WAAsD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAHtD,QAAiB,+BACjB,QAAgB,+BAChB,OAAgB,+BAChB,WAAsD;;;;;;;;;sCAHtD,QAAiB;sCACjB,QAAgB;sCAChB,OAAgB;sCAChB,WAAsD;;;OAGvD;MAED,AAAA,SAMC;;;;;cALC,OAAwB;cACxB,WAAsD;cACtD,OAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAFf,OAAwB,+BACxB,WAAsD,+BACtD,OAAe;;;;;;;;;2CAFf,OAAwB;2CACxB,WAAsD;2CACtD,OAAe;;;OAGhB;MAED,AAAA,YAKC;;;;;cAL2B,MAAc;;;;;;;;;;;;;;;;;;yCAAd,MAAc;;;;;;;yEAAd,MAAc;;;OAKzC;MAED,AAAA,sBAKC;;;;;cALqC,MAAc;cAAE,QAAgB;;;;;;;;;;;;;;;;;;;;;;;;;yCAAhC,MAAc,+BAAE,QAAgB;;;;;;;;;wDAAhC,MAAc;wDAAE,QAAgB;;;OAKrE;;;;;;;;GACA;EAtCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMA;;;;;;;;;uDAAuC;;;;;;;GAgCtC;ECfD,AAAA,QAAuB,0CACkB;EAGzC,AAAA;;;;;EAUA,AAAA,QAA0B;kCACkB;;EAG5C,AAAA,SAA2B;yEACqC;;EAIhE,AAAA,iBAAgC;oEAAA;;;EAEhC,AAAA,kBAAiC;qEAAA;;;EACjC,AAAA,oBAAmC,SAAU;;uDAAV;uDAAU;;;EAC7C,AAAA,sBAAkC;yDAAA;;;EAClC,AAAA,wBAAoC;2DAAA;;;EAqFpC,AAAA;;;;;;;;EACA,AAAA,+CAAgC;gEAAA;;;;;;;EAChC,AAAA,gDAAiC,QAAgB;;wDAAhB;wDAAgB;;;;;;;EAGjD,AAAA,aAAyB,cAAuB;qCACC,cAAY;;;EAG7D,AAAA;;eACE;eACA;eACA;eACA;;UAEM,kBAAyB;;yCAAwB;iEAAY;;;;;;;;;;;;4BAAuB;IAC1F;;;;;;;;;;;yGAAY;;;;;;yGAAY;;;;;;;;;;;;;yDACN,QAAM;UAClB,8BAAoB,QAAM;IAChC;;;;;;;;;;;yGAA2B;;;;;;WACpB;;EAeT,AAAA,sCAAuB;UACf,oDAAuD;;;;;;;;;;;;yDAC3C,QAAM;UACxB,+BAA4C,QAAM;IAAlD;;;;;;;;;;;yGAAA;;;;;;;;EAGF,AAAA,mCACE,SACA,aACA;UAEM,qCAAW;;;;;;;;;;;;wDACA;UACjB,4DACsC;wCAAQ;IAD9C;;;;;;;;;;;yGAAA;;;;;;QAEe;UAAT,kBAAS;iDAAA,MAAc;;uBAAd,MAAc;UACvB;;;;wGACoI;8BAClH;8BACA;yDAEN,UAAQ;UAC1B,+BAA0C,UAAQ;IAAlD;;;;;;;;;;;yGAAA;;;;;;sBACG;6CACkD;;YAE7C;;;;8GAC0I;oCACpH;oCACA;;;gCAEV;8CAAuD;YACnE,8BAAoB;wDAAuD;MACjF;;;;;;;;;;;2GAA2B;;;;;;MAC3B;;;;;;;;;;;2GAA6B;;;;;;oCACa,qBAAmB;;;EAIjE,AAAA,4CACE,SACA,UACA;;;oDAEgC;wBAAQ;wBAAQ;;EAgClD,AAAA,yBAA8B;oBACJ,qBAAmB,qBAAmB;;EAGhE,AAAA,uBAA4B;oBACO;oBAAmB;oBAAmB;;;EAUzE,AAAA,kBACE,QACA;0CAIU;8CACI;;sCACJ;sCAAoB;sCAAuB;;;;EAKvD,AAAA,iBACE,QACA;0CAIU;;0CAEA;;;;EDnRZ,AAAA,OAOC,4BANC,QAAiB,EACjB,QAAgB,EAChB,OAAgB,EAChB,WAAsD;;;sBAEnC,QAAM;sBAAY,QAAM;sBAAY,OAAK;sBAAY,WAAS;;GAClF;EAED,AAAA,YAMC,4BALC,OAAwB,EACxB,WAAsD,EACtD,OAAe;4CAED,OAAK,EAAY,WAAS,EAAY,OAAK;;GAC1D;EAED,AAAA,eAKC,4BAL2B,MAAc;UAClC,eAA8B,GAAL,MAAI;+CAC3B,eAAa;UACf,cAAwE,yCAAd;;;;;;;;;;;oHAAM;gDACtD,eAAa,EAAE,cAAY,IAA3C;;;;;;;;;0LAAgB,eAAa;;0LAAE,cAAY;;;;;;;;;;;wLAA3B,eAAa;;;;;;uHAAxB;;GACN;EAED,AAAA,yBAKC,4BALqC,MAAc,EAAE,QAAgB;UAC9D,cAA6B,GAAL,MAAI;+CAC1B,cAAY;UACd,cAAwE;;;;0BAChE,cAAY;0BAAE,cAAY;0BAAW,QAAM;;GAC1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA/BD;qCAAA;;;;;;;;;;;wFAAuC;KAAA;;;;;;;;;;;;;;" +} diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.d.cts b/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.d.cts new file mode 100644 index 0000000..fad21f6 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/contract/index.d.cts @@ -0,0 +1,74 @@ +import type * as __compactRuntime from '@midnight-ntwrk/compact-runtime'; + +export type ZswapCoinPublicKey = { bytes: Uint8Array }; + +export type ContractAddress = { bytes: Uint8Array }; + +export type Either = { is_left: boolean; left: A; right: B }; + +export type Maybe = { is_some: boolean; value: T }; + +export type CoinInfo = { nonce: Uint8Array; color: Uint8Array; value: bigint }; + +export type QualifiedCoinInfo = { nonce: Uint8Array; + color: Uint8Array; + value: bigint; + mt_index: bigint + }; + +export type Witnesses = { +} + +export type ImpureCircuits = { + mint(context: __compactRuntime.CircuitContext, + domain_0: Uint8Array, + amount_0: bigint, + nonce_0: Uint8Array, + recipient_0: Either): __compactRuntime.CircuitResults; + sendToken(context: __compactRuntime.CircuitContext, + input_0: QualifiedCoinInfo, + recipient_0: Either, + value_0: bigint): __compactRuntime.CircuitResults; + receiveToken(context: __compactRuntime.CircuitContext, coin_0: CoinInfo): __compactRuntime.CircuitResults; + receiveTokenSendChange(context: __compactRuntime.CircuitContext, + coin_0: CoinInfo, + change_0: bigint): __compactRuntime.CircuitResults; +} + +export type PureCircuits = { +} + +export type Circuits = { + mint(context: __compactRuntime.CircuitContext, + domain_0: Uint8Array, + amount_0: bigint, + nonce_0: Uint8Array, + recipient_0: Either): __compactRuntime.CircuitResults; + sendToken(context: __compactRuntime.CircuitContext, + input_0: QualifiedCoinInfo, + recipient_0: Either, + value_0: bigint): __compactRuntime.CircuitResults; + receiveToken(context: __compactRuntime.CircuitContext, coin_0: CoinInfo): __compactRuntime.CircuitResults; + receiveTokenSendChange(context: __compactRuntime.CircuitContext, + coin_0: CoinInfo, + change_0: bigint): __compactRuntime.CircuitResults; +} + +export type Ledger = { + readonly _coin: QualifiedCoinInfo; +} + +export type ContractReferenceLocations = any; + +export declare const contractReferenceLocations : ContractReferenceLocations; + +export declare class Contract = Witnesses> { + witnesses: W; + circuits: Circuits; + impureCircuits: ImpureCircuits; + constructor(witnesses: W); + initialState(context: __compactRuntime.ConstructorContext): __compactRuntime.ConstructorResult; +} + +export declare function ledger(state: __compactRuntime.StateValue): Ledger; +export declare const pureCircuits: PureCircuits; diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/mint.prover b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/mint.prover new file mode 100644 index 0000000..53aab3f Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/mint.prover differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/mint.verifier b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/mint.verifier new file mode 100644 index 0000000..e349358 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/mint.verifier differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveToken.prover b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveToken.prover new file mode 100644 index 0000000..d44b235 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveToken.prover differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveToken.verifier b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveToken.verifier new file mode 100644 index 0000000..0e42c74 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveToken.verifier differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveTokenSendChange.prover b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveTokenSendChange.prover new file mode 100644 index 0000000..f2dc569 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveTokenSendChange.prover differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveTokenSendChange.verifier b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveTokenSendChange.verifier new file mode 100644 index 0000000..1c593b1 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/receiveTokenSendChange.verifier differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/sendToken.prover b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/sendToken.prover new file mode 100644 index 0000000..76917ca Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/sendToken.prover differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/sendToken.verifier b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/sendToken.verifier new file mode 100644 index 0000000..a56aa9e Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/keys/sendToken.verifier differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/mint.bzkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/mint.bzkir new file mode 100644 index 0000000..ef656f4 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/mint.bzkir differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/mint.zkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/mint.zkir new file mode 100644 index 0000000..e397944 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/mint.zkir @@ -0,0 +1,123 @@ +{ + "version": { "major": 2, "minor": 0 }, + "do_communications_commitment": true, + "num_inputs": 10, + "instructions": [ + { "op": "constrain_bits", "var": 0, "bits": 8 }, + { "op": "constrain_bits", "var": 1, "bits": 248 }, + { "op": "constrain_bits", "var": 2, "bits": 64 }, + { "op": "constrain_bits", "var": 3, "bits": 8 }, + { "op": "constrain_bits", "var": 4, "bits": 248 }, + { "op": "constrain_to_boolean", "var": 5 }, + { "op": "constrain_bits", "var": 6, "bits": 8 }, + { "op": "constrain_bits", "var": 7, "bits": 248 }, + { "op": "constrain_bits", "var": 8, "bits": 8 }, + { "op": "constrain_bits", "var": 9, "bits": 248 }, + { "op": "load_imm", "imm": "01" }, + { "op": "load_imm", "imm": "32" }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "60" }, + { "op": "load_imm", "imm": "00" }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 13 }, + { "op": "pi_skip", "guard": 10, "count": 4 }, + { "op": "public_input", "guard": null }, + { "op": "public_input", "guard": null }, + { "op": "load_imm", "imm": "20" }, + { "op": "load_imm", "imm": "0D" }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "declare_pub_input", "var": 14 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "pi_skip", "guard": 10, "count": 5 }, + { "op": "load_imm", "imm": "6D69646E696768743A6465726976655F746F6B656E" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }], "inputs": [13, 18, 0, 1, 14, 15] }, + { "op": "load_imm", "imm": "40" }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "80" }, + { "op": "load_imm", "imm": "04" }, + { "op": "declare_pub_input", "var": 22 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "pi_skip", "guard": 10, "count": 4 }, + { "op": "load_imm", "imm": "10" }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "declare_pub_input", "var": 0 }, + { "op": "declare_pub_input", "var": 1 }, + { "op": "pi_skip", "guard": 10, "count": 6 }, + { "op": "load_imm", "imm": "31" }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "18" }, + { "op": "declare_pub_input", "var": 26 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "08" }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 27 }, + { "op": "declare_pub_input", "var": 2 }, + { "op": "pi_skip", "guard": 10, "count": 5 }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "declare_pub_input", "var": 27 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "12" }, + { "op": "declare_pub_input", "var": 28 }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "pi_skip", "guard": 10, "count": 2 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "-01" }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 29 }, + { "op": "pi_skip", "guard": 10, "count": 2 }, + { "op": "load_imm", "imm": "14" }, + { "op": "declare_pub_input", "var": 30 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "A2" }, + { "op": "declare_pub_input", "var": 31 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "cond_select", "bit": 5, "a": 6, "b": 8 }, + { "op": "cond_select", "bit": 5, "a": 7, "b": 9 }, + { "op": "load_imm", "imm": "6D646E3A6363" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [3, 4, 19, 20, 2, 5, 32, 33, 34] }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "load_imm", "imm": "02" }, + { "op": "declare_pub_input", "var": 22 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 37 }, + { "op": "pi_skip", "guard": 10, "count": 4 }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "declare_pub_input", "var": 35 }, + { "op": "declare_pub_input", "var": 36 }, + { "op": "pi_skip", "guard": 10, "count": 6 }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "declare_pub_input", "var": 13 }, + { "op": "pi_skip", "guard": 10, "count": 2 }, + { "op": "declare_pub_input", "var": 31 }, + { "op": "pi_skip", "guard": 10, "count": 1 }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "pi_skip", "guard": 10, "count": 1 } + ] +} diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveToken.bzkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveToken.bzkir new file mode 100644 index 0000000..32757a4 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveToken.bzkir differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveToken.zkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveToken.zkir new file mode 100644 index 0000000..bce05d1 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveToken.zkir @@ -0,0 +1,125 @@ +{ + "version": { "major": 2, "minor": 0 }, + "do_communications_commitment": true, + "num_inputs": 5, + "instructions": [ + { "op": "constrain_bits", "var": 0, "bits": 8 }, + { "op": "constrain_bits", "var": 1, "bits": 248 }, + { "op": "constrain_bits", "var": 2, "bits": 8 }, + { "op": "constrain_bits", "var": 3, "bits": 248 }, + { "op": "constrain_bits", "var": 4, "bits": 128 }, + { "op": "load_imm", "imm": "01" }, + { "op": "load_imm", "imm": "32" }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "load_imm", "imm": "60" }, + { "op": "load_imm", "imm": "00" }, + { "op": "declare_pub_input", "var": 7 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 8 }, + { "op": "pi_skip", "guard": 5, "count": 4 }, + { "op": "public_input", "guard": null }, + { "op": "public_input", "guard": null }, + { "op": "load_imm", "imm": "20" }, + { "op": "load_imm", "imm": "0D" }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "pi_skip", "guard": 5, "count": 5 }, + { "op": "load_imm", "imm": "6D646E3A6363" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [0, 1, 2, 3, 4, 8, 9, 10, 13] }, + { "op": "load_imm", "imm": "40" }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "load_imm", "imm": "80" }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "pi_skip", "guard": 5, "count": 4 }, + { "op": "load_imm", "imm": "10" }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "declare_pub_input", "var": 14 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "pi_skip", "guard": 5, "count": 6 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 8 }, + { "op": "pi_skip", "guard": 5, "count": 2 }, + { "op": "load_imm", "imm": "A2" }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "declare_pub_input", "var": 7 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 8 }, + { "op": "pi_skip", "guard": 5, "count": 4 }, + { "op": "public_input", "guard": null }, + { "op": "public_input", "guard": null }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "declare_pub_input", "var": 20 }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "pi_skip", "guard": 5, "count": 5 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 8 }, + { "op": "pi_skip", "guard": 5, "count": 5 }, + { "op": "load_imm", "imm": "33" }, + { "op": "declare_pub_input", "var": 22 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "cond_select", "bit": 8, "a": 8, "b": 20 }, + { "op": "cond_select", "bit": 8, "a": 8, "b": 21 }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [0, 1, 2, 3, 4, 8, 23, 24, 13] }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "declare_pub_input", "var": 26 }, + { "op": "pi_skip", "guard": 5, "count": 6 }, + { "op": "load_imm", "imm": "61" }, + { "op": "load_imm", "imm": "-01" }, + { "op": "declare_pub_input", "var": 27 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 28 }, + { "op": "pi_skip", "guard": 5, "count": 5 }, + { "op": "load_imm", "imm": "03" }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 5 }, + { "op": "declare_pub_input", "var": 29 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 0 }, + { "op": "declare_pub_input", "var": 1 }, + { "op": "declare_pub_input", "var": 2 }, + { "op": "declare_pub_input", "var": 3 }, + { "op": "declare_pub_input", "var": 4 }, + { "op": "pi_skip", "guard": 5, "count": 11 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "pi_skip", "guard": 5, "count": 1 }, + { "op": "load_imm", "imm": "17" }, + { "op": "load_imm", "imm": "5B" }, + { "op": "declare_pub_input", "var": 30 }, + { "op": "declare_pub_input", "var": 31 }, + { "op": "pi_skip", "guard": 5, "count": 2 }, + { "op": "load_imm", "imm": "91" }, + { "op": "declare_pub_input", "var": 32 }, + { "op": "pi_skip", "guard": 5, "count": 1 } + ] +} diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveTokenSendChange.bzkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveTokenSendChange.bzkir new file mode 100644 index 0000000..0919482 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveTokenSendChange.bzkir differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveTokenSendChange.zkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveTokenSendChange.zkir new file mode 100644 index 0000000..c32f202 --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/receiveTokenSendChange.zkir @@ -0,0 +1,203 @@ +{ + "version": { "major": 2, "minor": 0 }, + "do_communications_commitment": true, + "num_inputs": 6, + "instructions": [ + { "op": "constrain_bits", "var": 0, "bits": 8 }, + { "op": "constrain_bits", "var": 1, "bits": 248 }, + { "op": "constrain_bits", "var": 2, "bits": 8 }, + { "op": "constrain_bits", "var": 3, "bits": 248 }, + { "op": "constrain_bits", "var": 4, "bits": 128 }, + { "op": "constrain_bits", "var": 5, "bits": 64 }, + { "op": "load_imm", "imm": "01" }, + { "op": "load_imm", "imm": "32" }, + { "op": "declare_pub_input", "var": 7 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "load_imm", "imm": "60" }, + { "op": "load_imm", "imm": "00" }, + { "op": "declare_pub_input", "var": 8 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "pi_skip", "guard": 6, "count": 4 }, + { "op": "public_input", "guard": null }, + { "op": "public_input", "guard": null }, + { "op": "load_imm", "imm": "20" }, + { "op": "load_imm", "imm": "0D" }, + { "op": "declare_pub_input", "var": 13 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 10 }, + { "op": "declare_pub_input", "var": 11 }, + { "op": "pi_skip", "guard": 6, "count": 5 }, + { "op": "load_imm", "imm": "6D646E3A6363" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [0, 1, 2, 3, 4, 9, 10, 11, 14] }, + { "op": "load_imm", "imm": "40" }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "load_imm", "imm": "80" }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "pi_skip", "guard": 6, "count": 4 }, + { "op": "load_imm", "imm": "10" }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "pi_skip", "guard": 6, "count": 6 }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "pi_skip", "guard": 6, "count": 2 }, + { "op": "load_imm", "imm": "A2" }, + { "op": "declare_pub_input", "var": 20 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "private_input", "guard": null }, + { "op": "constrain_bits", "var": 21, "bits": 8 }, + { "op": "private_input", "guard": null }, + { "op": "constrain_bits", "var": 22, "bits": 248 }, + { "op": "declare_pub_input", "var": 7 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "declare_pub_input", "var": 8 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "pi_skip", "guard": 6, "count": 4 }, + { "op": "public_input", "guard": null }, + { "op": "public_input", "guard": null }, + { "op": "declare_pub_input", "var": 13 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "pi_skip", "guard": 6, "count": 5 }, + { "op": "load_imm", "imm": "6D646E3A636E" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [0, 1, 2, 3, 4, 9, 23, 24, 25] }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "pi_skip", "guard": 6, "count": 4 }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 26 }, + { "op": "declare_pub_input", "var": 27 }, + { "op": "pi_skip", "guard": 6, "count": 6 }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "pi_skip", "guard": 6, "count": 2 }, + { "op": "declare_pub_input", "var": 20 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "less_than", "a": 4, "b": 5, "bits": 128 }, + { "op": "cond_select", "bit": 28, "a": 9, "b": 6 }, + { "op": "assert", "cond": 29 }, + { "op": "neg", "a": 5 }, + { "op": "add", "a": 4, "b": 30 }, + { "op": "load_imm", "imm": "6D69646E696768743A6B65726E656C3A6E6F6E63655F65766F6C7665" }, + { "op": "transient_hash", "inputs": [32, 1] }, + { "op": "div_mod_power_of_two", "var": 33, "bits": 248 }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [9, 35, 2, 3, 5, 6, 21, 22, 14] }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "load_imm", "imm": "02" }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 38 }, + { "op": "pi_skip", "guard": 6, "count": 4 }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 6 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 36 }, + { "op": "declare_pub_input", "var": 37 }, + { "op": "pi_skip", "guard": 6, "count": 6 }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 9 }, + { "op": "pi_skip", "guard": 6, "count": 2 }, + { "op": "declare_pub_input", "var": 20 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 6, "count": 1 }, + { "op": "test_eq", "a": 31, "b": 9 }, + { "op": "cond_select", "bit": 39, "a": 9, "b": 6 }, + { "op": "load_imm", "imm": "6D69646E696768743A6B65726E656C3A6E6F6E63655F65766F6C76652F32" }, + { "op": "transient_hash", "inputs": [41, 1] }, + { "op": "div_mod_power_of_two", "var": 42, "bits": 248 }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [9, 44, 2, 3, 31, 9, 23, 24, 14] }, + { "op": "cond_select", "bit": 40, "a": 17, "b": 9 }, + { "op": "declare_pub_input", "var": 47 }, + { "op": "pi_skip", "guard": 40, "count": 1 }, + { "op": "cond_select", "bit": 40, "a": 18, "b": 9 }, + { "op": "declare_pub_input", "var": 48 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "cond_select", "bit": 40, "a": 38, "b": 9 }, + { "op": "declare_pub_input", "var": 49 }, + { "op": "pi_skip", "guard": 40, "count": 4 }, + { "op": "cond_select", "bit": 40, "a": 19, "b": 9 }, + { "op": "declare_pub_input", "var": 50 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "cond_select", "bit": 40, "a": 12, "b": 9 }, + { "op": "declare_pub_input", "var": 51 }, + { "op": "cond_select", "bit": 40, "a": 45, "b": 9 }, + { "op": "declare_pub_input", "var": 52 }, + { "op": "cond_select", "bit": 40, "a": 46, "b": 9 }, + { "op": "declare_pub_input", "var": 53 }, + { "op": "pi_skip", "guard": 40, "count": 6 }, + { "op": "cond_select", "bit": 40, "a": 19, "b": 9 }, + { "op": "declare_pub_input", "var": 54 }, + { "op": "cond_select", "bit": 40, "a": 9, "b": 9 }, + { "op": "declare_pub_input", "var": 55 }, + { "op": "pi_skip", "guard": 40, "count": 2 }, + { "op": "cond_select", "bit": 40, "a": 20, "b": 9 }, + { "op": "declare_pub_input", "var": 56 }, + { "op": "pi_skip", "guard": 40, "count": 1 }, + { "op": "cond_select", "bit": 40, "a": 17, "b": 9 }, + { "op": "declare_pub_input", "var": 57 }, + { "op": "pi_skip", "guard": 40, "count": 1 }, + { "op": "cond_select", "bit": 40, "a": 17, "b": 9 }, + { "op": "declare_pub_input", "var": 58 }, + { "op": "pi_skip", "guard": 40, "count": 1 }, + { "op": "cond_select", "bit": 40, "a": 18, "b": 9 }, + { "op": "declare_pub_input", "var": 59 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "pi_skip", "guard": 40, "count": 4 }, + { "op": "cond_select", "bit": 40, "a": 19, "b": 9 }, + { "op": "declare_pub_input", "var": 60 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "cond_select", "bit": 40, "a": 12, "b": 9 }, + { "op": "declare_pub_input", "var": 61 }, + { "op": "cond_select", "bit": 40, "a": 45, "b": 9 }, + { "op": "declare_pub_input", "var": 62 }, + { "op": "cond_select", "bit": 40, "a": 46, "b": 9 }, + { "op": "declare_pub_input", "var": 63 }, + { "op": "pi_skip", "guard": 40, "count": 6 }, + { "op": "cond_select", "bit": 40, "a": 19, "b": 9 }, + { "op": "declare_pub_input", "var": 64 }, + { "op": "cond_select", "bit": 40, "a": 9, "b": 9 }, + { "op": "declare_pub_input", "var": 65 }, + { "op": "pi_skip", "guard": 40, "count": 2 }, + { "op": "cond_select", "bit": 40, "a": 20, "b": 9 }, + { "op": "declare_pub_input", "var": 66 }, + { "op": "pi_skip", "guard": 40, "count": 1 }, + { "op": "cond_select", "bit": 40, "a": 17, "b": 9 }, + { "op": "declare_pub_input", "var": 67 }, + { "op": "pi_skip", "guard": 40, "count": 1 } + ] +} diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/sendToken.bzkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/sendToken.bzkir new file mode 100644 index 0000000..6b04e97 Binary files /dev/null and b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/sendToken.bzkir differ diff --git a/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/sendToken.zkir b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/sendToken.zkir new file mode 100644 index 0000000..864107a --- /dev/null +++ b/packages/simulator/test/fixtures/test-artifacts/UTXO/zkir/sendToken.zkir @@ -0,0 +1,170 @@ +{ + "version": { "major": 2, "minor": 0 }, + "do_communications_commitment": true, + "num_inputs": 12, + "instructions": [ + { "op": "constrain_bits", "var": 0, "bits": 8 }, + { "op": "constrain_bits", "var": 1, "bits": 248 }, + { "op": "constrain_bits", "var": 2, "bits": 8 }, + { "op": "constrain_bits", "var": 3, "bits": 248 }, + { "op": "constrain_bits", "var": 4, "bits": 128 }, + { "op": "constrain_bits", "var": 5, "bits": 64 }, + { "op": "constrain_to_boolean", "var": 6 }, + { "op": "constrain_bits", "var": 7, "bits": 8 }, + { "op": "constrain_bits", "var": 8, "bits": 248 }, + { "op": "constrain_bits", "var": 9, "bits": 8 }, + { "op": "constrain_bits", "var": 10, "bits": 248 }, + { "op": "constrain_bits", "var": 11, "bits": 64 }, + { "op": "load_imm", "imm": "01" }, + { "op": "load_imm", "imm": "32" }, + { "op": "declare_pub_input", "var": 13 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "load_imm", "imm": "60" }, + { "op": "load_imm", "imm": "00" }, + { "op": "declare_pub_input", "var": 14 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "pi_skip", "guard": 12, "count": 4 }, + { "op": "public_input", "guard": null }, + { "op": "public_input", "guard": null }, + { "op": "load_imm", "imm": "20" }, + { "op": "load_imm", "imm": "0D" }, + { "op": "declare_pub_input", "var": 19 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 16 }, + { "op": "declare_pub_input", "var": 17 }, + { "op": "pi_skip", "guard": 12, "count": 5 }, + { "op": "load_imm", "imm": "6D646E3A636E" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [0, 1, 2, 3, 4, 15, 16, 17, 20] }, + { "op": "load_imm", "imm": "40" }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "load_imm", "imm": "80" }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "pi_skip", "guard": 12, "count": 4 }, + { "op": "load_imm", "imm": "10" }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 21 }, + { "op": "declare_pub_input", "var": 22 }, + { "op": "pi_skip", "guard": 12, "count": 6 }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "pi_skip", "guard": 12, "count": 2 }, + { "op": "load_imm", "imm": "A2" }, + { "op": "declare_pub_input", "var": 26 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "less_than", "a": 4, "b": 11, "bits": 128 }, + { "op": "cond_select", "bit": 27, "a": 15, "b": 12 }, + { "op": "assert", "cond": 28 }, + { "op": "neg", "a": 11 }, + { "op": "add", "a": 4, "b": 29 }, + { "op": "load_imm", "imm": "6D69646E696768743A6B65726E656C3A6E6F6E63655F65766F6C7665" }, + { "op": "transient_hash", "inputs": [31, 1] }, + { "op": "div_mod_power_of_two", "var": 32, "bits": 248 }, + { "op": "cond_select", "bit": 6, "a": 7, "b": 9 }, + { "op": "cond_select", "bit": 6, "a": 8, "b": 10 }, + { "op": "load_imm", "imm": "6D646E3A6363" }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [15, 34, 2, 3, 11, 6, 35, 36, 37] }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "load_imm", "imm": "02" }, + { "op": "declare_pub_input", "var": 24 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 40 }, + { "op": "pi_skip", "guard": 12, "count": 4 }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 12 }, + { "op": "declare_pub_input", "var": 18 }, + { "op": "declare_pub_input", "var": 38 }, + { "op": "declare_pub_input", "var": 39 }, + { "op": "pi_skip", "guard": 12, "count": 6 }, + { "op": "declare_pub_input", "var": 25 }, + { "op": "declare_pub_input", "var": 15 }, + { "op": "pi_skip", "guard": 12, "count": 2 }, + { "op": "declare_pub_input", "var": 26 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "declare_pub_input", "var": 23 }, + { "op": "pi_skip", "guard": 12, "count": 1 }, + { "op": "test_eq", "a": 30, "b": 15 }, + { "op": "cond_select", "bit": 41, "a": 15, "b": 12 }, + { "op": "load_imm", "imm": "6D69646E696768743A6B65726E656C3A6E6F6E63655F65766F6C76652F32" }, + { "op": "transient_hash", "inputs": [43, 1] }, + { "op": "div_mod_power_of_two", "var": 44, "bits": 248 }, + { "op": "persistent_hash", "alignment": [{ "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 16, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 1, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 32, "tag": "bytes" } }, { "tag": "atom", "value": { "length": 6, "tag": "bytes" } }], "inputs": [15, 46, 2, 3, 30, 15, 16, 17, 37] }, + { "op": "cond_select", "bit": 42, "a": 23, "b": 15 }, + { "op": "declare_pub_input", "var": 49 }, + { "op": "pi_skip", "guard": 42, "count": 1 }, + { "op": "cond_select", "bit": 42, "a": 24, "b": 15 }, + { "op": "declare_pub_input", "var": 50 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "cond_select", "bit": 42, "a": 40, "b": 15 }, + { "op": "declare_pub_input", "var": 51 }, + { "op": "pi_skip", "guard": 42, "count": 4 }, + { "op": "cond_select", "bit": 42, "a": 25, "b": 15 }, + { "op": "declare_pub_input", "var": 52 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "cond_select", "bit": 42, "a": 18, "b": 15 }, + { "op": "declare_pub_input", "var": 53 }, + { "op": "cond_select", "bit": 42, "a": 47, "b": 15 }, + { "op": "declare_pub_input", "var": 54 }, + { "op": "cond_select", "bit": 42, "a": 48, "b": 15 }, + { "op": "declare_pub_input", "var": 55 }, + { "op": "pi_skip", "guard": 42, "count": 6 }, + { "op": "cond_select", "bit": 42, "a": 25, "b": 15 }, + { "op": "declare_pub_input", "var": 56 }, + { "op": "cond_select", "bit": 42, "a": 15, "b": 15 }, + { "op": "declare_pub_input", "var": 57 }, + { "op": "pi_skip", "guard": 42, "count": 2 }, + { "op": "cond_select", "bit": 42, "a": 26, "b": 15 }, + { "op": "declare_pub_input", "var": 58 }, + { "op": "pi_skip", "guard": 42, "count": 1 }, + { "op": "cond_select", "bit": 42, "a": 23, "b": 15 }, + { "op": "declare_pub_input", "var": 59 }, + { "op": "pi_skip", "guard": 42, "count": 1 }, + { "op": "cond_select", "bit": 42, "a": 23, "b": 15 }, + { "op": "declare_pub_input", "var": 60 }, + { "op": "pi_skip", "guard": 42, "count": 1 }, + { "op": "cond_select", "bit": 42, "a": 24, "b": 15 }, + { "op": "declare_pub_input", "var": 61 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "pi_skip", "guard": 42, "count": 4 }, + { "op": "cond_select", "bit": 42, "a": 25, "b": 15 }, + { "op": "declare_pub_input", "var": 62 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "declare_pub_input", "var": 42 }, + { "op": "cond_select", "bit": 42, "a": 18, "b": 15 }, + { "op": "declare_pub_input", "var": 63 }, + { "op": "cond_select", "bit": 42, "a": 47, "b": 15 }, + { "op": "declare_pub_input", "var": 64 }, + { "op": "cond_select", "bit": 42, "a": 48, "b": 15 }, + { "op": "declare_pub_input", "var": 65 }, + { "op": "pi_skip", "guard": 42, "count": 6 }, + { "op": "cond_select", "bit": 42, "a": 25, "b": 15 }, + { "op": "declare_pub_input", "var": 66 }, + { "op": "cond_select", "bit": 42, "a": 15, "b": 15 }, + { "op": "declare_pub_input", "var": 67 }, + { "op": "pi_skip", "guard": 42, "count": 2 }, + { "op": "cond_select", "bit": 42, "a": 26, "b": 15 }, + { "op": "declare_pub_input", "var": 68 }, + { "op": "pi_skip", "guard": 42, "count": 1 }, + { "op": "cond_select", "bit": 42, "a": 23, "b": 15 }, + { "op": "declare_pub_input", "var": 69 }, + { "op": "pi_skip", "guard": 42, "count": 1 } + ] +} diff --git a/packages/simulator/test/integration/UTXO.test.ts b/packages/simulator/test/integration/UTXO.test.ts new file mode 100644 index 0000000..79d7b11 --- /dev/null +++ b/packages/simulator/test/integration/UTXO.test.ts @@ -0,0 +1,282 @@ +import { + type DomainSeperator, + decodeCoinPublicKey, +} from '@midnight-ntwrk/compact-runtime'; +import { encodeContractAddress } from '@midnight-ntwrk/ledger'; +import { encodeTokenType, tokenType } from '@midnight-ntwrk/onchain-runtime'; +import { beforeEach, describe, expect, it } from 'vitest'; +import type { + ContractAddress, + Either, + ZswapCoinPublicKey, +} from '../fixtures/test-artifacts/UTXO/contract/index.cjs'; +import * as utils from '../fixtures/utils/address.js'; +import { UTXOSimulator } from './UTXOSimulator'; + +const DOMAIN_1 = new Uint8Array(32).fill(1); +const DOMAIN_2 = new Uint8Array(32).fill(2); +const DOMAIN_3 = new Uint8Array(32).fill(3); +const DOMAINS = [DOMAIN_1, DOMAIN_2, DOMAIN_3]; + +const NONCE_1 = new Uint8Array(32).fill(4); +const NONCE_2 = new Uint8Array(32).fill(5); +const NONCE_3 = new Uint8Array(32).fill(6); +const NONCES = [NONCE_1, NONCE_2, NONCE_3]; + +const AMOUNT_1 = 1700n; +const AMOUNT_2 = 1800000000n; +const AMOUNT_3 = 1900000000000000n; +const AMOUNTS = [AMOUNT_1, AMOUNT_2, AMOUNT_3]; + +const [ALICE, zALICE] = utils.generateEitherPubKeyPair('ALICE'); +const [BOB, zBOB] = utils.generateEitherPubKeyPair('BOB'); +const [CAROL, zCAROL] = utils.generateEitherPubKeyPair('CAROL'); +const RECIPIENTS = [zALICE, zBOB, zCAROL]; + +// +// Helpers +// + +const calculateColor = (domain: DomainSeperator, addr: string): Uint8Array => { + return encodeTokenType(tokenType(domain, addr)); +}; + +const encodeInstanceAddress = (addr: string) => { + return { + is_left: false, + left: { bytes: utils.zeroUint8Array() }, + right: { bytes: encodeContractAddress(addr) }, + }; +}; + +const createExpOutput = ( + nonce: Uint8Array, + color: Uint8Array, + value: bigint, + recipient: Either, +) => { + return { + coinInfo: { + nonce: nonce, + color: color, + value: value, + }, + recipient: recipient, + }; +}; + +let contract: UTXOSimulator; + +describe('UTXO test', () => { + beforeEach(() => { + contract = new UTXOSimulator(); + }); + + describe('coinPublicKey', () => { + // Helper to make the test callers output readable + const describeCoinPK = (pk: string): string => { + return `${pk.slice(0, 8)}...${pk.slice(-8)}`; + }; + + const testCallers = [ + { + caller: ALICE, + encodedAddy: zALICE, + readableAddy: describeCoinPK(decodeCoinPublicKey(zALICE.left.bytes)), + }, + { + caller: BOB, + encodedAddy: zBOB, + readableAddy: describeCoinPK(decodeCoinPublicKey(zBOB.left.bytes)), + }, + { + caller: CAROL, + encodedAddy: zCAROL, + readableAddy: describeCoinPK(decodeCoinPublicKey(zCAROL.left.bytes)), + }, + ]; + it.each(testCallers)( + 'should return $readableAddy when called from the corresponding coinPublicKey $caller', + ({ caller, encodedAddy }) => { + contract.as(caller).mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + expect(contract.getZswapState().coinPublicKey).toEqual( + encodedAddy.left, + ); + }, + ); + + it('should return zero when there is no caller', () => { + contract.mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + expect(contract.getZswapState().coinPublicKey).toEqual( + utils.ZERO_KEY.left, + ); + }); + }); + + describe('currentIndex', () => { + it('should start with a current index of zero', () => { + expect(contract.getZswapState().currentIndex).toEqual(0n); + }); + + it('should track the current index with created outputs', () => { + contract.mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + expect(contract.getZswapState().currentIndex).toEqual(1n); + + contract.mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + expect(contract.getZswapState().currentIndex).toEqual(2n); + + for (let i = 0; i < 8; i++) { + contract.mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + } + expect(contract.getZswapState().currentIndex).toEqual(10n); + }); + + // Receiving a coin resets the index + it.skip('should track the current index when creating inputs and outputs', () => { + // Bump index to 10 + for (let i = 0; i < NONCES.length; i++) { + contract.mint(DOMAIN_1, AMOUNT_1, NONCES[i], zALICE); + } + expect(contract.getZswapState().currentIndex).toEqual(3n); + + const thisColor = calculateColor(DOMAIN_1, contract.contractAddress); + const thisCoin = { + nonce: NONCE_1, + color: thisColor, + value: AMOUNT_1, + }; + contract.as(ALICE).receiveToken(thisCoin); + + expect(contract.getZswapState().currentIndex).toEqual(1n); + }); + }); + + describe('Outputs', () => { + it('should match zswap outputs with single output', () => { + contract.mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + const zswapRes = contract.getZswapState(); + + // Check inputs are empty + const inputs = zswapRes.inputs; + expect(inputs).toEqual([]); + + // Check outputs + const out = zswapRes.outputs; + const expected = { + coinInfo: { + nonce: NONCE_1, + color: calculateColor(DOMAIN_1, contract.contractAddress), + value: AMOUNT_1, + }, + recipient: zALICE, + }; + + // Check values + expect(out[0]).toEqual(expected); + + // Check output len + expect(out.length).toEqual(1); + }); + + it('should match zswap outputs with multiple outputs', () => { + for (let i = 0; i < RECIPIENTS.length; i++) { + contract.mint(DOMAINS[i], AMOUNTS[i], NONCES[i], RECIPIENTS[i]); + } + + const zswapRes = contract.getZswapState(); + + // Check inputs are empty + const inputs = zswapRes.inputs; + expect(inputs).toEqual([]); + + // Bind outputs + const out = zswapRes.outputs; + + // Check output len + expect(out.length).toEqual(3); + + // Check output values + for (let i = 0; i < RECIPIENTS.length; i++) { + const expected = { + coinInfo: { + nonce: NONCES[i], + color: calculateColor(DOMAINS[i], contract.contractAddress), + value: AMOUNTS[i], + }, + recipient: RECIPIENTS[i], + }; + expect(expected).toEqual(out[i]); + } + }); + }); + + describe('Inputs and outputs', () => { + it('should match input and outputs', () => { + const sendAmt = 1n; + const encodedContractAddy = encodeInstanceAddress( + contract.contractAddress, + ); + const thisColor = calculateColor(DOMAIN_1, contract.contractAddress); + + // Mint + receive = 2 outputs + contract.mint(DOMAIN_1, AMOUNT_1, NONCE_1, zALICE); + const thisCoin = { + nonce: NONCE_1, + color: thisColor, + value: AMOUNT_1, + }; + contract.as(ALICE).receiveToken(thisCoin); + + // Create input and output (1 input + 3 outputs) + const coinInput = contract.getPublicState()._coin; + contract.sendToken(coinInput, zBOB, sendAmt); + + const zswapRes = contract.getZswapState(); + + // Check input len + const inputs = zswapRes.inputs; + expect(inputs.length).toEqual(1); + + // Check input data + const expInput = { + color: thisColor, + mt_index: 0n, + nonce: NONCE_1, + value: AMOUNT_1, + }; + expect(inputs[0]).toEqual(expInput); + + // Check output len + const outputs = zswapRes.outputs; + expect(outputs.length).toEqual(3); + + // Check output data + const expOutput_1 = createExpOutput( + NONCE_1, + thisColor, + AMOUNT_1, + encodedContractAddy, + ); + expect(outputs[0]).toEqual(expOutput_1); + + // Check output 2 data + const expOutput_2 = createExpOutput(NONCE_1, thisColor, sendAmt, zBOB); + // We skip nonce here bc it's random + expect(outputs[1].coinInfo.color).toEqual(expOutput_2.coinInfo.color); + expect(outputs[1].coinInfo.value).toEqual(expOutput_2.coinInfo.value); + expect(outputs[1].recipient).toEqual(expOutput_2.recipient); + + // Check output 3 data + const expOutput_3 = createExpOutput( + NONCE_1, + thisColor, + AMOUNT_1 - sendAmt, + encodedContractAddy, + ); + // We skip nonce here bc it's random + expect(outputs[2].coinInfo.color).toEqual(expOutput_3.coinInfo.color); + expect(outputs[2].coinInfo.value).toEqual(expOutput_3.coinInfo.value); + expect(outputs[2].recipient).toEqual(expOutput_3.recipient); + }); + }); +}); diff --git a/packages/simulator/test/integration/UTXOSimulator.ts b/packages/simulator/test/integration/UTXOSimulator.ts new file mode 100644 index 0000000..5807137 --- /dev/null +++ b/packages/simulator/test/integration/UTXOSimulator.ts @@ -0,0 +1,64 @@ +import { type BaseSimulatorOptions, createSimulator } from '../../src/index'; +import { + UTXOPrivateState, + UTXOWitnesses, +} from '../fixtures/sample-contracts/witnesses/UTXOWitnesses'; +import { + type CoinInfo, + type ContractAddress, + type Either, + ledger, + type QualifiedCoinInfo, + Contract as UTXOContract, + type ZswapCoinPublicKey, +} from '../fixtures/test-artifacts/UTXO/contract/index.cjs'; + +/** + * Base simulator + */ +const UTXOSimulatorBase = createSimulator({ + contractFactory: (witnesses) => new UTXOContract(witnesses), + defaultPrivateState: () => UTXOPrivateState, + contractArgs: () => [], + ledgerExtractor: (state) => ledger(state), + witnessesFactory: () => UTXOWitnesses(), +}); + +/** + * UTXO Simulator + */ +export class UTXOSimulator extends UTXOSimulatorBase { + constructor( + options: BaseSimulatorOptions< + UTXOPrivateState, + ReturnType + > = {}, + ) { + super([], options); + } + + public mint( + domain: Uint8Array, + amount: bigint, + nonce: Uint8Array, + recipient: Either, + ) { + this.circuits.impure.mint(domain, amount, nonce, recipient); + } + + public sendToken( + input: QualifiedCoinInfo, + recipient: Either, + value: bigint, + ) { + return this.circuits.impure.sendToken(input, recipient, value); + } + + public receiveToken(coin: CoinInfo) { + return this.circuits.impure.receiveToken(coin); + } + + public receiveTokenSendChange(coin: CoinInfo, change: bigint) { + return this.circuits.impure.receiveTokenSendChange(coin, change); + } +} diff --git a/turbo.json b/turbo.json index 199d22c..1abe083 100644 --- a/turbo.json +++ b/turbo.json @@ -1,16 +1,10 @@ { - "extends": [ - "//" - ], + "extends": ["//"], "$schema": "https://turbo.build/schema.json", "tasks": { "test": { - "dependsOn": [ - "^build" - ], - "env": [ - "COMPACT_HOME" - ], + "dependsOn": ["^build"], + "env": ["COMPACT_HOME"], "inputs": [ "src/**/*.ts", "src/**/*.compact", @@ -21,12 +15,8 @@ "cache": false }, "build": { - "dependsOn": [ - "^build" - ], - "env": [ - "COMPACT_HOME" - ], + "dependsOn": ["^build"], + "env": ["COMPACT_HOME"], "inputs": [ "src/**/*.ts", "!src/**/*.test.ts", @@ -34,15 +24,11 @@ "tsconfig.build.json", ".env" ], - "outputs": [ - "dist/**" - ] + "outputs": ["dist/**"] }, "types": { "dependsOn": [], - "outputs": [ - "dist/**" - ] + "outputs": ["dist/**"] }, "fmt-and-lint": {}, "fmt-and-lint:ci": {}, @@ -54,4 +40,4 @@ "cache": false } } -} \ No newline at end of file +}