wormhole/algorand/audit_test/src/wormhole/WormholeTmplSig.ts

76 lines
2.7 KiB
TypeScript

import { decodeAddress, getApplicationAddress, LogicSigAccount, OnApplicationComplete } from 'algosdk'
import { Address, AppId } from '../sdk/AlgorandTypes'
import { concatArrays, decodeBase16, AlgorandType } from "../sdk/Encoding"
import { Deployer, SignCallback } from "../sdk/Deployer"
import path from 'path'
import varint from 'varint'
import { Wormhole } from './Wormhole'
export const EMITTER_GUARDIAN = new TextEncoder().encode("guardian")
export class WormholeTmplSig {
private _logicSig: LogicSigAccount
public constructor(
sequence: number,
emitterId: Uint8Array,
coreId: AppId,
) {
// Generate the template sig bytecode directly
const program = concatArrays([
decodeBase16('0620010181'),
varint.encode(sequence),
decodeBase16('4880'),
varint.encode(emitterId.length),
emitterId,
decodeBase16('483110810612443119221244311881'),
varint.encode(coreId),
decodeBase16('124431208020'),
decodeAddress(getApplicationAddress(coreId)).publicKey,
decodeBase16('124431018100124431093203124431153203124422'),
])
this._logicSig = new LogicSigAccount(program)
}
public get logicSig(): LogicSigAccount {
return this._logicSig
}
public get address(): Address {
return this.logicSig.address()
}
public async optin(deployer: Deployer, owner: Address, coreId: AppId, signCallback: SignCallback, dryrunDebug = false): Promise<void> {
// Test if contract is opted in
const optedIn = await deployer.readOptedInApps(this.address)
if (optedIn.find((entry) => entry.id === coreId) === undefined) {
console.log(`Performing optin for TmplSig ${this.address}`)
const tmplSigPayment = BigInt(1_002_000)
const optinTxns = await Promise.all([
deployer.makePayTransaction(owner, this.address, tmplSigPayment, 2 * deployer.minFee),
deployer.makeCallTransaction(this.address, coreId, OnApplicationComplete.OptInOC, [], [], [], [], '', 0, getApplicationAddress(coreId))
])
const initTxId = await deployer.callGroupTransaction(optinTxns, new Map([[this.address, this.logicSig]]), signCallback, dryrunDebug)
await deployer.waitForTransactionResponse(initTxId)
}
}
public static async compileTmplSig(deployer: Deployer, sequence: number | bigint, emitterId: Uint8Array, coreId: AppId): Promise<LogicSigAccount> {
const tmplSigPath = path.join(Wormhole.BASE_PATH, 'TmplSig.py')
const tmplSigArgs = new Map<string, AlgorandType>([
['TMPL_ADDR_IDX', sequence],
['TMPL_EMITTER_ID', emitterId],
['TMPL_APP_ID', coreId],
// FIXME: The application address should be generated contract side for security
['TMPL_APP_ADDRESS', decodeAddress(getApplicationAddress(coreId)).publicKey],
])
const tmplSigApp = await deployer.compileStateless(tmplSigPath, tmplSigArgs)
return tmplSigApp
}
}