Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions contracts/contracts/ccip/test/receiver/contract.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,7 @@ fun onInternalMessage(in: InMessage) {
match (msg) {
Receiver_CCIPReceive => {
var st = lazy Storage.load();
msg.validateAndConfirm({
router: st.authorizedCaller,
minValue: ton("0.01"),
inMsg: {
senderAddress: in.senderAddress,
valueCoins: in.valueCoins,
},
confirmationMsg: {
sendMode: SEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE,
}
});


match (st.behavior) {
TestReceiverBehavior.Accept => {
processAccept(msg, in.senderAddress)
Expand All @@ -49,6 +38,20 @@ fun onInternalMessage(in: InMessage) {
processConsumeAllGas()
}
}

Copy link
Collaborator Author

@vicentevieytes vicentevieytes Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to move this validateAndConfirm code block under the process functions. Turns out that if you do the reserve and send trick before the emit then it does not work, it has to be the last message sent. @patricios-space

reserveToncoinsOnBalance(0, RESERVE_MODE_INCREASE_BY_ORIGINAL_BALANCE);
msg.validateAndConfirm({
router: st.authorizedCaller,
minValue: ton("0.01"),
inMsg: {
senderAddress: in.senderAddress,
valueCoins: in.valueCoins,
},
confirmationMsg: {
sendMode: SEND_MODE_CARRY_ALL_BALANCE,
}
});

}
TestReceiver_UpdateAuthorizedCaller => {
onUpdateAuthorizedCaller(msg, in.senderAddress)
Expand Down
36 changes: 36 additions & 0 deletions contracts/tests/ccip/Receiver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,40 @@ describe('Receiver', () => {
exitCode: -14,
})
})

it('should keep original balance after succesfully receiving', async () => {
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in test name: "succesfully" should be "successfully".

Suggested change
it('should keep original balance after succesfully receiving', async () => {
it('should keep original balance after successfully receiving', async () => {

Copilot uses AI. Check for mistakes.
const contract = await blockchain.getContract(receiver.address)
const initialBalance = contract.balance

const result = await receiver.sendCCIPReceive(
deployer.getSender(),
toNano('1'),
ccipReceiveSampleMessage,
)
expect(result.transactions).toHaveTransaction({
from: deployer.address,
to: receiver.address,
success: true,
deploy: false,
body: tr.builder.message.in.ccipReceive.encode(ccipReceiveSampleMessage).asCell(),
})

const tx = result.transactions.find(
(tx) =>
tx.inMessage &&
tx.inMessage.info.src &&
tx.inMessage.info.src instanceof Address &&
tx.inMessage.info.src.equals(deployer.address) &&
tx.inMessage.info.dest &&
tx.inMessage.info.dest instanceof Address &&
tx.inMessage.info.dest.equals(receiver.address),
)
if (!tx || tx.description.type != 'generic') {
throw new Error('Expected an internal message')
}
const storageFees = tx.description.storagePhase?.storageFeesCollected || toNano('0')

const finalBalance = (await blockchain.getContract(receiver.address)).balance
expect(finalBalance).toEqual(initialBalance - storageFees)
})
})
Loading