import { executeCommand } from './execute/execute' ; import { getCommandSignature } from '../setting/auth' ; import Transport from '../transport' ; import { commands } from './execute/command' ; import { APDUError } from '../error/errorHandle' ; import { CODE } from '../config/status/code' ; import { target } from '../config/param' ; import { getSEVersion } from './general' ; todo export const sendScript = async ( transport , script ) => { const { statusCode , msg } = await executeCommand ( transport , commands . SEND_SCRIPT , target . SE , script ) ; if ( statusCode === CODE . _9000 ) { return true ; } else { throw new APDUError ( commands . SEND_SCRIPT , statusCode , msg ) ; } } ; /**
 * Scriptable step 2 : sign tx by arguments and return encrypted signature
 */ export const executeScript = async ( transport , appId , appPrivKey , argument ) => { if ( argument . length > 20000 ) throw new Error ( 'argument too long' ) ; const args = argument . match ( /.{2,3800}/g ) ; if ( args === null ) throw new Error ( 'argument is empty' ) ; if ( args . length > 1 ) { const version = await getSEVersion ( transport ) ; if ( version < 314 ) throw new Error ( 'argument too long, try updating to support the longer data' ) ; } for ( const [ i , v ] of args . entries ( ) ) { const p1 = i . toString ( 16 ) . padStart ( 2 , '0' ) ; const p2 = args . length . toString ( 16 ) . padStart ( 2 , '0' ) ; const signature = await getCommandSignature ( transport , appId , appPrivKey , commands . EXECUTE_SCRIPT , v , p1 , p2 ) ; const { outputData , statusCode , msg } = await executeCommand ( transport , commands . EXECUTE_SCRIPT , target . SE , v + signature , p1 , p2 ) ; if ( i + 1 === args . length ) { if ( outputData ) { return outputData ; } else { throw new APDUError ( commands . EXECUTE_SCRIPT , statusCode , msg ) ; } } } } ; param transport param appId param appPrivKey param argument returns export const executeSegmentScript = async ( transport , appId , appPrivKey , argument ) => { if ( argument . length > 2147483648 * 2 ) throw new Error ( 'argument too long' ) ; const args = argument . match ( /.{2,3800}/g ) ; if ( args === null ) throw new Error ( 'argument is empty' ) ; if ( args . length > 1 ) { const version = await getSEVersion ( transport ) ; if ( version < 320 ) throw new Error ( 'argument too long, try updating to support the longer data' ) ; } const p2 = ( args . length - 1 ) . toString ( ) . padStart ( 2 , '0' ) ; for ( const [ i , v ] of args . entries ( ) ) { const p1 = i . toString ( ) . padStart ( 2 , '0' ) ; const signature = await getCommandSignature ( transport , appId , appPrivKey , commands . EXECUTE_SEGMENT_SCRIPT , v , p1 , p2 ) ; const { outputData , statusCode , msg } = await executeCommand ( transport , commands . EXECUTE_SEGMENT_SCRIPT , target . SE , v + signature , p1 , p2 ) ; if ( p1 === p2 ) { if ( outputData ) { return outputData ; } else { throw new APDUError ( commands . EXECUTE_SEGMENT_SCRIPT , statusCode , msg ) ; } } } } ; param { * } transport param { * } argument export const executeUtxoScript = async ( transport , appId , appPrivKey , utxoArgument , extraTransactionType ) => { const signature = await getCommandSignature ( transport , appId , appPrivKey , commands . EXECUTE_UTXO_SCRIPT , utxoArgument , extraTransactionType , undefined ) ; const { outputData : encryptedSignature , statusCode , msg , } = await executeCommand ( transport , commands . EXECUTE_UTXO_SCRIPT , target . SE , utxoArgument + signature , extraTransactionType , undefined ) ; if ( encryptedSignature ) { return encryptedSignature ; } else { throw new APDUError ( commands . EXECUTE_UTXO_SCRIPT , statusCode , msg ) ; } } ; todo param { Transport } transport return { Promse < { signedTx : string , statusCode : string } > } export const getSignedHex = async ( transport ) : Promise < { signedTx : string ; statusCode : string ; } > => { const { outputData : signedTx , statusCode , msg } = await executeCommand ( transport , commands . GET_SIGNED_HEX , target . SE ) ; if ( statusCode === CODE . _9000 || statusCode === CODE . _6D00 ) { return { signedTx , statusCode } ; } else { throw new APDUError ( commands . GET_SIGNED_HEX , statusCode , msg ) ; } } ; param { Transport } transport return { Promse < boolean > } export const finishPrepare = async ( transport ) : Promise < boolean > => { const { statusCode , msg } = await executeCommand ( transport , commands . FINISH_PREPARE , target . SE ) ; if ( statusCode === CODE . _9000 ) { return true ; } else { throw new APDUError ( commands . FINISH_PREPARE , statusCode , msg ) ; } } ; param { Transport } transport return { Promise < string > } export const getSignatureKey = async ( transport ) : Promise < string > => { const { outputData : signatureKey , statusCode , msg } = await executeCommand ( transport , commands . GET_TX_KEY , target . SE ) ; if ( signatureKey ) { return signatureKey ; } else { throw new APDUError ( commands . GET_TX_KEY , statusCode , msg ) ; } } ; param { Transport } transport return { Promise < boolean > } export const clearTransaction = async ( transport ) : Promise < boolean > => { const { statusCode , msg } = await executeCommand ( transport , commands . CLEAR_TX , target . SE ) ; if ( statusCode === CODE . _9000 ) { return true ; } else { throw new APDUError ( commands . CLEAR_TX , statusCode , msg ) ; } } ; param { Transport } transport return { Promise < boolean > } export const getTxDetail = async ( transport ) : Promise < boolean > => { const { statusCode , msg } = await executeCommand ( transport , commands . GET_TX_DETAIL , target . SE ) ; if ( statusCode === CODE . _9000 ) { return true ; } else { throw new APDUError ( commands . GET_TX_DETAIL , statusCode , msg ) ; } } ; param { Transport } transport param { string } payload param { number } sn return { Promise < boolean > } export const setToken = async ( transport , payload , sn = 1 ) : Promise < boolean > => { const command = sn === 1 ? commands . SET_ERC20_TOKEN : commands . SET_SECOND_ERC20_TOKEN ; const { statusCode , msg } = await executeCommand ( transport , command , target . SE , payload ) ; if ( statusCode === CODE . _9000 ) { return true ; } else { throw new APDUError ( command , statusCode , msg ) ; } } ; param { Transport } transport param { string } payload param { number } sn return { Promise < boolean > } export const setCustomToken = async ( transport , payload , sn = 1 ) : Promise < boolean > => { const command = sn === 1 ? commands . SET_ERC20_TOKEN : commands . SET_SECOND_ERC20_TOKEN ; const { statusCode , msg } = await executeCommand ( transport , command , target . SE , payload , '04' , '18' ) ; if ( statusCode === CODE . _9000 ) { return true ; } else { throw new APDUError ( command , statusCode , msg ) ; } } ;