Rc/evm signature (#249)
* feat: allow signing function only for bundled txs * fix: after ppe review * feat: add transaction verification * feat: warp plugins system * chore: removing lodash dep * feat: isEvmSigned verification * chore: useFastCopy fix in tests * feat: evm signature - minor fixes * fix: try-catch for evm sig verification * v1.2.14-beta.5 * fix: await for sig verification * v1.2.14-beta.6 * chore: restore original package version Co-authored-by: asiaziola <ziola.jm@gmail.com>
This commit is contained in:
@@ -26,11 +26,11 @@ import { sleep } from '../utils/utils';
|
||||
import {
|
||||
Contract,
|
||||
BenchmarkStats,
|
||||
SigningFunction,
|
||||
CurrentTx,
|
||||
WriteInteractionOptions,
|
||||
WriteInteractionResponse,
|
||||
InnerCallData
|
||||
InnerCallData,
|
||||
Signature
|
||||
} from './Contract';
|
||||
import { Tags, ArTransfer, emptyTransfer, ArWallet } from './deploy/CreateContract';
|
||||
import { SourceData, SourceImpl } from './deploy/impl/SourceImpl';
|
||||
@@ -58,7 +58,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
/**
|
||||
* wallet connected to this contract
|
||||
*/
|
||||
protected signer?: SigningFunction;
|
||||
protected signature?: Signature;
|
||||
|
||||
constructor(
|
||||
private readonly _contractTxId: string,
|
||||
@@ -207,7 +207,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
options?: WriteInteractionOptions
|
||||
): Promise<WriteInteractionResponse | null> {
|
||||
this.logger.info('Write interaction', { input, options });
|
||||
if (!this.signer) {
|
||||
if (!this.signature) {
|
||||
throw new Error("Wallet not connected. Use 'connect' method first.");
|
||||
}
|
||||
const { arweave, interactionsLoader, environment } = this.warp;
|
||||
@@ -221,6 +221,12 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
|
||||
const bundleInteraction = interactionsLoader.type() == 'warp' && !effectiveDisableBundling;
|
||||
|
||||
if (this.signature.signatureType !== 'arweave' && !bundleInteraction) {
|
||||
throw new Error(
|
||||
`Unable to use signing function of type: ${this.signature.signatureType} when not in mainnet environment or bundling is disabled.`
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
bundleInteraction &&
|
||||
effectiveTransfer.target != emptyTransfer.target &&
|
||||
@@ -369,7 +375,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
|
||||
const interactionTx = await createInteractionTx(
|
||||
this.warp.arweave,
|
||||
this.signer,
|
||||
this.signature.signer,
|
||||
this._contractTxId,
|
||||
input,
|
||||
tags,
|
||||
@@ -389,12 +395,27 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
return this._callStack;
|
||||
}
|
||||
|
||||
connect(signer: ArWallet | SigningFunction): Contract<State> {
|
||||
if (typeof signer == 'function') {
|
||||
this.signer = signer;
|
||||
connect(signature: ArWallet | Signature): Contract<State> {
|
||||
if (this.isSignatureType(signature)) {
|
||||
if (
|
||||
signature.signatureType !== 'arweave' &&
|
||||
(!(this.warp.environment == 'mainnet') || !(this.warp.interactionsLoader.type() == 'warp'))
|
||||
) {
|
||||
throw new Error(
|
||||
`Unable to use signing function of type: ${signature.signatureType} when not in mainnet environment or bundling is disabled.`
|
||||
);
|
||||
} else {
|
||||
this.signature = {
|
||||
signer: signature.signer,
|
||||
signatureType: signature.signatureType
|
||||
};
|
||||
}
|
||||
} else {
|
||||
this.signer = async (tx: Transaction) => {
|
||||
await this.warp.arweave.transactions.sign(tx, signer);
|
||||
this.signature = {
|
||||
signer: async (tx: Transaction) => {
|
||||
await this.warp.arweave.transactions.sign(tx, signature);
|
||||
},
|
||||
signatureType: 'arweave'
|
||||
};
|
||||
}
|
||||
return this;
|
||||
@@ -539,7 +560,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
): Promise<InteractionResult<State, View>> {
|
||||
this.logger.info('Call contract input', input);
|
||||
this.maybeResetRootContract();
|
||||
if (!this.signer) {
|
||||
if (!this.signature) {
|
||||
this.logger.warn('Wallet not set.');
|
||||
}
|
||||
const { arweave, stateEvaluator } = this.warp;
|
||||
@@ -553,7 +574,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
let effectiveCaller;
|
||||
if (caller) {
|
||||
effectiveCaller = caller;
|
||||
} else if (this.signer) {
|
||||
} else if (this.signature) {
|
||||
// we're creating this transaction just to call the signing function on it
|
||||
// - and retrieve the caller/owner
|
||||
const dummyTx = await arweave.createTransaction({
|
||||
@@ -561,7 +582,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
reward: '72600854',
|
||||
last_tx: 'p7vc1iSP6bvH_fCeUFa9LqoV5qiyW-jdEKouAT0XMoSwrNraB9mgpi29Q10waEpO'
|
||||
});
|
||||
await this.signer(dummyTx);
|
||||
await this.signature.signer(dummyTx);
|
||||
effectiveCaller = await arweave.wallets.ownerToAddress(dummyTx.owner);
|
||||
} else {
|
||||
effectiveCaller = '';
|
||||
@@ -586,7 +607,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
this.logger.debug('interaction', interaction);
|
||||
const tx = await createInteractionTx(
|
||||
arweave,
|
||||
this.signer,
|
||||
this.signature?.signer,
|
||||
this._contractTxId,
|
||||
input,
|
||||
tags,
|
||||
@@ -746,13 +767,13 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
}
|
||||
|
||||
async save(sourceData: SourceData): Promise<any> {
|
||||
if (!this.signer) {
|
||||
if (!this.signature) {
|
||||
throw new Error("Wallet not connected. Use 'connect' method first.");
|
||||
}
|
||||
const { arweave } = this.warp;
|
||||
const source = new SourceImpl(arweave);
|
||||
|
||||
const srcTx = await source.save(sourceData, this.signer);
|
||||
const srcTx = await source.save(sourceData, this.signature.signer);
|
||||
|
||||
return srcTx.id;
|
||||
}
|
||||
@@ -760,4 +781,8 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
||||
get rootSortKey(): string {
|
||||
return this._rootSortKey;
|
||||
}
|
||||
|
||||
private isSignatureType(signature: ArWallet | Signature): signature is Signature {
|
||||
return (signature as Signature).signer !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user