diff --git a/.gitignore b/.gitignore index 8494ef3de..71974a331 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,35 @@ +# Build and project files /docs/build Cargo.lock /target **/*.rs.bk *.ll -/tests/.tmp* -/tests/create_me/ -/test_snapshots/ +package-lock.json +# Test directories and snapshots +tests/.tmp* +tests/create_me/ +/test_snapshots +test_snapshots/ +test_snapshots/ + +# Editors and IDEs .helix/ .vscode/ -/test_snapshots +# OS generated files +*.DS_Store + +# Compiled binaries and outputs +*.wasm +*.abi +*.ll + +# Dependencies and modules +node_modules/ + +# Integration specific paths +integration/soroban/addition.sol +integration/soroban/rust/target/ +integration/anchor/target/ +integration/anchor/target/.rustc_info.json \ No newline at end of file diff --git a/integration/soroban/counter.sol b/integration/soroban/counter.sol index 3d289ba33..31af2a007 100644 --- a/integration/soroban/counter.sol +++ b/integration/soroban/counter.sol @@ -10,4 +10,12 @@ contract counter { count -= 1; return count; } -} + + function addingu64(uint64 a, uint64 b) public returns (uint64) { + return a + b; + } + + function addingu32(uint32 a, uint32 b) public returns (uint32) { + return a + b; + } +} \ No newline at end of file diff --git a/integration/soroban/counter.spec.js b/integration/soroban/counter.spec.js index 21f14e48a..74afaf4fc 100644 --- a/integration/soroban/counter.spec.js +++ b/integration/soroban/counter.spec.js @@ -47,6 +47,46 @@ describe('Counter', () => { let count = await call_contract_function("count", server, keypair, contract); expect(count.returnValue().value().toString()).eq("11"); }); + + it('adding two u64 values', async () => { + // add two numbers + + let args = [ + StellarSdk.xdr.ScVal.scvU64(100n), + StellarSdk.xdr.ScVal.scvU64(200n) + ]; + + console.log(`addingu64 inputs are: ${args[0].u64()} and ${args[1].u64()} `); + + + let result = await call_contract_function("addingu64", server, keypair, contract, ...args); // let returnValue = result.returnValue().value().toString(); + + let output = result.returnValue().value().toString(); + console.log(`additionu64 output is: ${output}`); + expect(result.returnValue().value().toString()).eq("300"); + }); + + + + + + it('adding two u32 values', async () => { + // add two numbers + + let args = [ + StellarSdk.xdr.ScVal.scvU32(50), + StellarSdk.xdr.ScVal.scvU32(60) + ]; + + console.log(`additionu32 input is: ${args[0].u32()} and ${args[1].u32()} `); + + + let result = await call_contract_function("addingu32", server, keypair, contract, ...args); // let returnValue = result.returnValue().value().toString(); + + let output = result.returnValue().value().toString(); + console.log(`additionu32 output is: ${output}`); + expect(result.returnValue().value().toString()).eq("110"); + }); }); diff --git a/src/codegen/encoding/soroban_encoding.rs b/src/codegen/encoding/soroban_encoding.rs index baa5711c0..7ba1482f0 100644 --- a/src/codegen/encoding/soroban_encoding.rs +++ b/src/codegen/encoding/soroban_encoding.rs @@ -131,9 +131,38 @@ pub fn soroban_decode_arg( }), signed: false, }, + Type::Uint(32) | Type::Int(32) => { + let shifted = Expression::ShiftRight { + loc: Loc::Codegen, + ty: Type::Uint(64), // The shift result is Uint(64) + left: arg.into(), + right: Box::new(Expression::NumberLiteral { + loc: Loc::Codegen, + ty: Type::Uint(64), + value: BigInt::from(8_u64), + }), + signed: false, + }; - Type::Address(_) => arg.clone(), + let truncated = Expression::Trunc { + // Truncate to the original size + loc: Loc::Codegen, + ty: ty.clone(), // Use the original type (Uint(32) or Int(32)) + expr: Box::new(shifted), + }; + if ty == Type::Int(32) { + Expression::Cast { + // Cast to Int(32) if needed + loc: Loc::Codegen, + ty: Type::Int(32), + expr: Box::new(truncated), + } + } else { + truncated + } + } + Type::Address(_) => arg.clone(), Type::Int(128) | Type::Uint(128) => decode_i128(wrapper_cfg, vartab, arg), _ => unimplemented!(), } @@ -285,6 +314,48 @@ pub fn soroban_encode_arg( expr: added, } } + + Type::Uint(32) | Type::Int(32) => { + let extended = Expression::ZeroExt { + loc: item.loc(), + ty: Type::Uint(64), + expr: Box::new(item.clone()), + }; + let shift_left = Expression::ShiftLeft { + loc: item.loc(), + ty: Type::Uint(64), + left: Box::new(extended), + right: Box::new(Expression::NumberLiteral { + loc: item.loc(), + ty: Type::Uint(64), + value: BigInt::from(8), + }), + }; + + let tag = match item.ty() { + Type::Uint(32) => 4, + Type::Int(32) => 5, + _ => unreachable!(), + }; + + let added = Expression::Add { + loc: item.loc(), + ty: Type::Uint(64), + left: Box::new(shift_left), + right: Box::new(Expression::NumberLiteral { + loc: item.loc(), + ty: Type::Uint(64), + value: BigInt::from(tag), + }), + overflowing: false, + }; + + Instr::Set { + loc: item.loc(), + res: obj, + expr: added, + } + } Type::Address(_) => { let instr = if let Expression::Cast { loc, ty: _, expr } = item { let address_literal = expr;