1- import { Keypair , LAMPORTS_PER_SOL , PublicKey } from "@solana/web3.js" ;
1+ import {
2+ Keypair ,
3+ LAMPORTS_PER_SOL ,
4+ PublicKey ,
5+ SystemProgram ,
6+ } from "@solana/web3.js" ;
27import chai from "chai" ;
38import chaiAsPromised from "chai-as-promised" ;
4- import { makeTransfer } from "../util/cryptid" ;
9+ import { makeTransfer , toAccountMeta } from "../util/cryptid" ;
510import { initializeDIDAccount } from "../util/did" ;
611import { balanceOf , createTestContext , fund } from "../util/anchorUtils" ;
7- import { DID_SOL_PREFIX } from "@identity.com/sol-did-client" ;
8- import { Cryptid } from "@identity.com/cryptid" ;
12+ import { DID_SOL_PREFIX , DID_SOL_PROGRAM } from "@identity.com/sol-did-client" ;
13+ import { Cryptid , TransactionState } from "@identity.com/cryptid" ;
914import {
1015 SuperuserCheckSignerMiddleware ,
1116 deriveMiddlewareAccountAddress ,
@@ -17,13 +22,16 @@ const { expect } = chai;
1722
1823describe ( "Middleware: superuserCheckSigner" , ( ) => {
1924 const {
25+ program,
2026 keypair,
2127 provider,
2228 authority,
2329 middleware : { superuserCheckSigner : superuserCheckSignerMiddlewareProgram } ,
2430 } = createTestContext ( ) ;
2531
2632 let cryptid : CryptidClient ;
33+ let authorizedCryptid : CryptidClient ;
34+
2735 const cryptidIndex = 1 ;
2836
2937 let middlewareAccount : PublicKey ;
@@ -33,6 +41,31 @@ describe("Middleware: superuserCheckSigner", () => {
3341 const makeTransaction = ( to = signer . publicKey ) =>
3442 makeTransfer ( cryptid . address ( ) , to ) ;
3543
44+ const execute = ( transactionAccount : PublicKey ) =>
45+ // execute the Cryptid transaction
46+ program . methods
47+ . executeTransaction (
48+ [ ] , // no controller chain
49+ cryptid . details . bump ,
50+ cryptid . details . index ,
51+ cryptid . details . didAccountBump ,
52+ 0
53+ )
54+ . accounts ( {
55+ cryptidAccount : cryptid . address ( ) ,
56+ didProgram : DID_SOL_PROGRAM ,
57+ did : cryptid . details . didAccount ,
58+ authority : signer . publicKey ,
59+ destination : signer . publicKey ,
60+ transactionAccount,
61+ } )
62+ . remainingAccounts ( [
63+ toAccountMeta ( signer . publicKey , true , false ) ,
64+ toAccountMeta ( SystemProgram . programId ) ,
65+ ] )
66+ . signers ( [ signer ] )
67+ . rpc ( ) ;
68+
3669 before ( "Fund the authority and signer" , async ( ) => {
3770 await Promise . all ( [
3871 fund ( authority . publicKey , LAMPORTS_PER_SOL ) ,
@@ -99,6 +132,22 @@ describe("Middleware: superuserCheckSigner", () => {
99132 }
100133 )
101134 ) . unauthorized ( ) ;
135+
136+ authorizedCryptid = await Cryptid . buildFromDID (
137+ DID_SOL_PREFIX + ":" + authority . publicKey ,
138+ authority ,
139+ {
140+ connection : provider . connection ,
141+ accountIndex : cryptidIndex ,
142+ middlewares : [
143+ {
144+ programId : superuserCheckSignerMiddlewareProgram . programId ,
145+ address : middlewareAccount ,
146+ isSuperuser : true ,
147+ } ,
148+ ] ,
149+ }
150+ ) ;
102151 } ;
103152
104153 before (
@@ -159,6 +208,37 @@ describe("Middleware: superuserCheckSigner", () => {
159208 ) ;
160209 } ) ;
161210
211+ it ( "cannot execute with an unauthorized signer if the transaction was proposed by none (middleware error)" , async ( ) => {
212+ // propose the Cryptid transaction
213+ const { proposeTransaction, transactionAccount, proposeSigners } =
214+ await authorizedCryptid . propose ( makeTransaction ( ) ) ;
215+ // this will be signed by a DID authority
216+ await authorizedCryptid . send ( proposeTransaction , proposeSigners ) ;
217+
218+ // This should fail!
219+ const { transactions, signers } = await cryptid . execute ( transactionAccount ) ;
220+
221+ const shouldFail = cryptid . send ( transactions [ 0 ] , signers ) ;
222+
223+ return expect ( shouldFail ) . to . be . rejectedWith (
224+ "Error Code: AlreadyAuthorizedTransactionAccount"
225+ ) ;
226+ } ) ;
227+
228+ it ( "cannot execute with an unauthorized signer if the transaction was proposed by none (execute error)" , async ( ) => {
229+ // propose the Cryptid transaction
230+ const { proposeTransaction, transactionAccount, proposeSigners } =
231+ await authorizedCryptid . propose ( makeTransaction ( ) ) ;
232+ // this will be signed by a DID authority
233+ await authorizedCryptid . send ( proposeTransaction , proposeSigners ) ;
234+
235+ // This should fail!
236+ // Manual execute skips the middleware execution. (which would fail)
237+ const shouldFail = execute ( transactionAccount ) ;
238+
239+ return expect ( shouldFail ) . to . be . rejectedWith ( "Error Code: KeyMustBeSigner" ) ;
240+ } ) ;
241+
162242 it ( "blocks a transfer not signed by the signer" , async ( ) => {
163243 // change the signer
164244 signer = Keypair . generate ( ) ;
@@ -177,4 +257,26 @@ describe("Middleware: superuserCheckSigner", () => {
177257
178258 return expect ( shouldFail ) . to . be . rejectedWith ( "Error Code: InvalidSigner." ) ;
179259 } ) ;
260+
261+ it ( "cannot extend with an unauthorized signer of the transaction was proposed by none" , async ( ) => {
262+ // propose the Cryptid transaction
263+ const { proposeTransaction, transactionAccount, proposeSigners } =
264+ await authorizedCryptid . propose (
265+ makeTransaction ( ) ,
266+ TransactionState . NotReady
267+ ) ;
268+ // this will be signed by the non-did signer
269+ await authorizedCryptid . send ( proposeTransaction , proposeSigners ) ;
270+
271+ // This should fail!
272+ const extendTx = await cryptid . extend (
273+ transactionAccount ,
274+ makeTransaction ( )
275+ ) ;
276+ const shouldFail = cryptid . send ( extendTx , [ ] ) ;
277+
278+ return expect ( shouldFail ) . to . be . rejectedWith (
279+ "Error Code: KeyMustBeSigner."
280+ ) ;
281+ } ) ;
180282} ) ;
0 commit comments