@@ -7,11 +7,13 @@ import type { BrowserContext, Page } from '@playwright/test';
77
88import 'dotenv/config' ;
99
10- import { execFileSync } from 'child_process' ;
10+ import { execFileSync , execSync } from 'child_process' ;
1111import { IotaNamesTransaction , isSubname , NameRecord } from '@iota/iota-names-sdk' ;
1212import type { Signer } from '@iota/iota-sdk/cryptography' ;
1313import { Transaction } from '@iota/iota-sdk/transactions' ;
1414import { NANOS_PER_IOTA } from '@iota/iota-sdk/utils' ;
15+ import { blake2b } from '@noble/hashes/blake2' ;
16+ import { bytesToHex } from '@noble/hashes/utils' ;
1517
1618import { buildCreateAuctionTransaction , buildPlaceBidTransaction } from '@/auctions' ;
1719import { CONFIG } from '@/config' ;
@@ -320,6 +322,7 @@ export async function setAvatar(nameRecord: NameRecord, signer: Signer) {
320322 console . log ( `Avatar set to address: ${ address } ` ) ;
321323 return responseSetAvatar ;
322324}
325+
323326export function deriveAddressFromMnemonic ( mnemonic : string , path ?: string ) {
324327 const keypair = Ed25519Keypair . deriveKeypair ( mnemonic , path ) ;
325328 const address = keypair . getPublicKey ( ) . toIotaAddress ( ) ;
@@ -416,3 +419,44 @@ export function generateRandomSubname(subname: string, parentName: string) {
416419 const random = Math . floor ( Math . random ( ) * 10_000 ) ;
417420 return `${ subname } ${ random } .${ parentName } ` ;
418421}
422+
423+ interface CreateCouponOptions {
424+ code : string ;
425+ type : 'fixed' | 'percentage' ;
426+ value : bigint ;
427+ }
428+
429+ export async function createCoupon ( { code, type, value } : CreateCouponOptions ) {
430+ const couponCodeHash = bytesToHex ( blake2b ( code , { dkLen : 32 } ) ) ;
431+
432+ const couponsPackageId = iotaNamesClient . getPackage ( 'couponsPackageId' ) ;
433+ const iotaNamesObjectId = iotaNamesClient . getPackage ( 'iotaNamesObjectId' ) ;
434+ const adminCapId = iotaNamesClient . getPackage ( 'adminCap' ) ;
435+ const adminAddress = iotaNamesClient . getPackage ( 'adminAddress' ) ;
436+
437+ const functionName =
438+ type === 'fixed' ? 'admin_add_fixed_coupon' : 'admin_add_percentage_coupon' ;
439+
440+ const command = `iota client ptb \
441+ --move-call ${ couponsPackageId } ::rules::new_empty_rules \
442+ --assign empty_rules \
443+ --move-call ${ couponsPackageId } ::coupon_house::${ functionName } \
444+ @${ adminCapId } \
445+ @${ iotaNamesObjectId } \
446+ '"${ couponCodeHash } "' \
447+ ${ value . toString ( ) } \
448+ empty_rules \
449+ --gas-budget 50000000 \
450+ --sender @${ adminAddress } ` ;
451+
452+ console . log ( `Creating ${ type } coupon "${ code } " with hash ${ couponCodeHash } ...` ) ;
453+
454+ try {
455+ const output = execSync ( command , { encoding : 'utf-8' } ) ;
456+ console . log ( `Created ${ type } coupon "${ code } " successfully` ) ;
457+ return output ;
458+ } catch ( error ) {
459+ console . error ( `Failed to create coupon "${ code } ":` , error ) ;
460+ throw error ;
461+ }
462+ }
0 commit comments