@@ -965,9 +965,9 @@ describe("stackflow agent", () => {
965965 const outgoing = agent . buildOutgoingTransfer ( {
966966 pipeId,
967967 amount : "25" ,
968- actor : "ST1LOCAL" ,
969968 } ) ;
970969
970+ expect ( outgoing . actor ) . toBe ( "ST1LOCAL" ) ;
971971 expect ( outgoing . myBalance ) . toBe ( "75" ) ;
972972 expect ( outgoing . theirBalance ) . toBe ( "25" ) ;
973973 expect ( outgoing . nonce ) . toBe ( "1" ) ;
@@ -992,6 +992,71 @@ describe("stackflow agent", () => {
992992 store . close ( ) ;
993993 } ) ;
994994
995+ it ( "rejects outgoing transfer requests with actor mismatch" , ( ) => {
996+ const dbFile = tempDbFile ( "agent-send-actor-mismatch" ) ;
997+ const store = new AgentStateStore ( { dbFile } ) ;
998+
999+ const contractId = "ST1TESTABC.contract" ;
1000+ const pipeKey = {
1001+ "principal-1" : "ST1LOCAL" ,
1002+ "principal-2" : "ST1OTHER" ,
1003+ token : null ,
1004+ } ;
1005+ const pipeId = buildPipeId ( { contractId, pipeKey } ) ;
1006+
1007+ store . upsertTrackedPipe ( {
1008+ pipeId,
1009+ contractId,
1010+ pipeKey,
1011+ localPrincipal : "ST1LOCAL" ,
1012+ counterpartyPrincipal : "ST1OTHER" ,
1013+ token : null ,
1014+ } ) ;
1015+
1016+ store . upsertSignatureState ( {
1017+ contractId,
1018+ pipeKey,
1019+ forPrincipal : "ST1LOCAL" ,
1020+ withPrincipal : "ST1OTHER" ,
1021+ token : null ,
1022+ myBalance : "100" ,
1023+ theirBalance : "0" ,
1024+ nonce : "0" ,
1025+ action : "1" ,
1026+ actor : "ST1LOCAL" ,
1027+ mySignature : "0x" + "11" . repeat ( 65 ) ,
1028+ theirSignature : "0x" + "22" . repeat ( 65 ) ,
1029+ secret : null ,
1030+ validAfter : null ,
1031+ beneficialOnly : false ,
1032+ } ) ;
1033+
1034+ const agent = new StackflowAgentService ( {
1035+ stateStore : store ,
1036+ signer : {
1037+ async sip018Sign ( ) {
1038+ return "0x" + "44" . repeat ( 65 ) ;
1039+ } ,
1040+ async submitDispute ( ) {
1041+ return { txid : "0x1" } ;
1042+ } ,
1043+ async callContract ( ) {
1044+ return { ok : true } ;
1045+ } ,
1046+ } ,
1047+ } ) ;
1048+
1049+ expect ( ( ) =>
1050+ agent . buildOutgoingTransfer ( {
1051+ pipeId,
1052+ amount : "25" ,
1053+ actor : "ST1THIRD" ,
1054+ } ) ,
1055+ ) . toThrow ( "actor must match tracked local principal" ) ;
1056+
1057+ store . close ( ) ;
1058+ } ) ;
1059+
9951060 it ( "defaults watcher interval to one hour" , ( ) => {
9961061 const dbFile = tempDbFile ( "agent-interval" ) ;
9971062 const store = new AgentStateStore ( { dbFile } ) ;
0 commit comments