feat: deploy contract using evm signature (#257)
* feat: deploy contract using evm signature * fix: review fixes
This commit is contained in:
155
src/__tests__/unit/signature.test.ts
Normal file
155
src/__tests__/unit/signature.test.ts
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import { Signature } from '../../contract/Signature';
|
||||||
|
import { defaultCacheOptions, WarpFactory } from '../../core/WarpFactory';
|
||||||
|
|
||||||
|
describe('Wallet', () => {
|
||||||
|
const sampleFunction = async () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
//test
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const signingFunction = `async (tx) => {await this.warp.arweave.transactions.sign(tx, walletOrSignature);}`.replace(
|
||||||
|
/\s+/g,
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('in local environment', () => {
|
||||||
|
const warp = WarpFactory.forLocal();
|
||||||
|
|
||||||
|
it(`should set correct signature for 'use_wallet'`, () => {
|
||||||
|
const sut = new Signature(warp, 'use_wallet');
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for jwk`, () => {
|
||||||
|
const sut = new Signature(warp, {
|
||||||
|
kty: '',
|
||||||
|
e: '',
|
||||||
|
n: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for custom signing function and arweave signature type`, () => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'arweave' });
|
||||||
|
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(sampleFunction.toString().replace(/\s+/g, ''));
|
||||||
|
expect(sut.type).toEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should throw for custom signing function and ethereum signature type`, () => {
|
||||||
|
expect(() => {
|
||||||
|
new Signature(warp, { signer: sampleFunction, type: 'ethereum' });
|
||||||
|
}).toThrow(
|
||||||
|
`Unable to use signing function of type: ethereum when not in mainnet environment or bundling is disabled.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('in testnet environment', () => {
|
||||||
|
const warp = WarpFactory.forTestnet();
|
||||||
|
|
||||||
|
it(`should set correct signature for 'use_wallet'`, () => {
|
||||||
|
const sut = new Signature(warp, 'use_wallet');
|
||||||
|
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for jwk`, () => {
|
||||||
|
const sut = new Signature(warp, {
|
||||||
|
kty: '',
|
||||||
|
e: '',
|
||||||
|
n: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for custom signing function and arweave signature type`, () => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'arweave' });
|
||||||
|
|
||||||
|
expect(sut.signer).toEqual(sampleFunction);
|
||||||
|
expect(sut.type).toEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should throw for custom signing function and arweave signature type`, () => {
|
||||||
|
expect(() => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'ethereum' });
|
||||||
|
}).toThrow(
|
||||||
|
`Unable to use signing function of type: ethereum when not in mainnet environment or bundling is disabled.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('in mainnet environment when bundling is disabled', () => {
|
||||||
|
const warp = WarpFactory.forMainnet(defaultCacheOptions, true);
|
||||||
|
|
||||||
|
it(`should set correct signature for 'use_wallet'`, () => {
|
||||||
|
const sut = new Signature(warp, 'use_wallet');
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for jwk`, () => {
|
||||||
|
const sut = new Signature(warp, {
|
||||||
|
kty: '',
|
||||||
|
e: '',
|
||||||
|
n: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for custom signing function and arweave signature type`, () => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'arweave' });
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(sampleFunction.toString().replace(/\s+/g, ''));
|
||||||
|
expect(sut.type).toEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should throw for custom signing function and arweave signature type`, () => {
|
||||||
|
expect(() => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'ethereum' });
|
||||||
|
}).toThrow(
|
||||||
|
`Unable to use signing function of type: ethereum when not in mainnet environment or bundling is disabled.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('in mainnet environment when bundling is enabled', () => {
|
||||||
|
const warp = WarpFactory.forMainnet();
|
||||||
|
|
||||||
|
it(`should set correct signature for 'use_wallet'`, () => {
|
||||||
|
const sut = new Signature(warp, 'use_wallet');
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for jwk`, () => {
|
||||||
|
const sut = new Signature(warp, {
|
||||||
|
kty: '',
|
||||||
|
e: '',
|
||||||
|
n: ''
|
||||||
|
});
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(signingFunction);
|
||||||
|
expect(sut.type).toStrictEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for custom signing function and arweave signature type`, () => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'arweave' });
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(sampleFunction.toString().replace(/\s+/g, ''));
|
||||||
|
expect(sut.type).toEqual('arweave');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set correct signature for custom signing function and ethereum signature type`, () => {
|
||||||
|
const sut = new Signature(warp, { signer: sampleFunction, type: 'ethereum' });
|
||||||
|
expect(sut.signer.toString().replace(/\s+/g, '')).toEqual(sampleFunction.toString().replace(/\s+/g, ''));
|
||||||
|
expect(sut.signer).toEqual(sampleFunction);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import Transaction from 'arweave/node/lib/transaction';
|
|
||||||
import { SortKeyCacheResult } from '../cache/SortKeyCache';
|
import { SortKeyCacheResult } from '../cache/SortKeyCache';
|
||||||
import { ContractCallRecord } from '../core/ContractCallRecord';
|
import { ContractCallRecord } from '../core/ContractCallRecord';
|
||||||
import { InteractionResult } from '../core/modules/impl/HandlerExecutorFactory';
|
import { InteractionResult } from '../core/modules/impl/HandlerExecutorFactory';
|
||||||
@@ -6,12 +5,11 @@ import { EvaluationOptions, EvalStateResult } from '../core/modules/StateEvaluat
|
|||||||
import { GQLNodeInterface } from '../legacy/gqlResult';
|
import { GQLNodeInterface } from '../legacy/gqlResult';
|
||||||
import { ArTransfer, Tags, ArWallet } from './deploy/CreateContract';
|
import { ArTransfer, Tags, ArWallet } from './deploy/CreateContract';
|
||||||
import { Source } from './deploy/Source';
|
import { Source } from './deploy/Source';
|
||||||
|
import { SignatureType } from './Signature';
|
||||||
|
|
||||||
export type CurrentTx = { interactionTxId: string; contractTxId: string };
|
export type CurrentTx = { interactionTxId: string; contractTxId: string };
|
||||||
export type BenchmarkStats = { gatewayCommunication: number; stateEvaluation: number; total: number };
|
export type BenchmarkStats = { gatewayCommunication: number; stateEvaluation: number; total: number };
|
||||||
|
|
||||||
export type SigningFunction = (tx: Transaction) => Promise<void>;
|
|
||||||
export type Signature = { signer: SigningFunction; signatureType: 'arweave' | 'ethereum' };
|
|
||||||
export class ContractError extends Error {
|
export class ContractError extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
super(message);
|
super(message);
|
||||||
@@ -85,7 +83,7 @@ export interface Contract<State = unknown> extends Source {
|
|||||||
*
|
*
|
||||||
* @param signer - either {@link ArWallet} that will be connected to this contract or custom {@link SigningFunction}
|
* @param signer - either {@link ArWallet} that will be connected to this contract or custom {@link SigningFunction}
|
||||||
*/
|
*/
|
||||||
connect(signature: ArWallet | Signature): Contract<State>;
|
connect(signature: ArWallet | SignatureType): Contract<State>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to set ({@link EvaluationOptions})
|
* Allows to set ({@link EvaluationOptions})
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { TransactionStatusResponse } from 'arweave/node/transactions';
|
import { TransactionStatusResponse } from 'arweave/node/transactions';
|
||||||
import stringify from 'safe-stable-stringify';
|
import stringify from 'safe-stable-stringify';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
import Transaction from 'arweave/node/lib/transaction';
|
|
||||||
import { SortKeyCacheResult } from '../cache/SortKeyCache';
|
import { SortKeyCacheResult } from '../cache/SortKeyCache';
|
||||||
import { ContractCallRecord, InteractionCall } from '../core/ContractCallRecord';
|
import { ContractCallRecord, InteractionCall } from '../core/ContractCallRecord';
|
||||||
import { ExecutionContext } from '../core/ExecutionContext';
|
import { ExecutionContext } from '../core/ExecutionContext';
|
||||||
@@ -29,13 +28,13 @@ import {
|
|||||||
CurrentTx,
|
CurrentTx,
|
||||||
WriteInteractionOptions,
|
WriteInteractionOptions,
|
||||||
WriteInteractionResponse,
|
WriteInteractionResponse,
|
||||||
InnerCallData,
|
InnerCallData
|
||||||
Signature
|
|
||||||
} from './Contract';
|
} from './Contract';
|
||||||
import { Tags, ArTransfer, emptyTransfer, ArWallet } from './deploy/CreateContract';
|
import { Tags, ArTransfer, emptyTransfer, ArWallet } from './deploy/CreateContract';
|
||||||
import { SourceData, SourceImpl } from './deploy/impl/SourceImpl';
|
import { SourceData, SourceImpl } from './deploy/impl/SourceImpl';
|
||||||
import { InnerWritesEvaluator } from './InnerWritesEvaluator';
|
import { InnerWritesEvaluator } from './InnerWritesEvaluator';
|
||||||
import { generateMockVrf } from '../utils/vrf';
|
import { generateMockVrf } from '../utils/vrf';
|
||||||
|
import { Signature, SignatureType } from './Signature';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link Contract} that is backwards compatible with current style
|
* An implementation of {@link Contract} that is backwards compatible with current style
|
||||||
@@ -54,11 +53,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
private readonly _arweaveWrapper: ArweaveWrapper;
|
private readonly _arweaveWrapper: ArweaveWrapper;
|
||||||
private _sorter: InteractionsSorter;
|
private _sorter: InteractionsSorter;
|
||||||
private _rootSortKey: string;
|
private _rootSortKey: string;
|
||||||
|
private signature: Signature;
|
||||||
/**
|
|
||||||
* wallet connected to this contract
|
|
||||||
*/
|
|
||||||
protected signature?: Signature;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _contractTxId: string,
|
private readonly _contractTxId: string,
|
||||||
@@ -229,11 +224,7 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
|
|
||||||
const bundleInteraction = interactionsLoader.type() == 'warp' && !effectiveDisableBundling;
|
const bundleInteraction = interactionsLoader.type() == 'warp' && !effectiveDisableBundling;
|
||||||
|
|
||||||
if (this.signature.signatureType !== 'arweave' && !bundleInteraction) {
|
this.signature.checkNonArweaveSigningAvailability(bundleInteraction);
|
||||||
throw new Error(
|
|
||||||
`Unable to use signing function of type: ${this.signature.signatureType} when not in mainnet environment or bundling is disabled.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
bundleInteraction &&
|
bundleInteraction &&
|
||||||
@@ -404,29 +395,8 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
return this._callStack;
|
return this._callStack;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(signature: ArWallet | Signature): Contract<State> {
|
connect(signature: ArWallet | SignatureType): Contract<State> {
|
||||||
if (this.isSignatureType(signature)) {
|
this.signature = new Signature(this.warp, 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.signature = {
|
|
||||||
signer: async (tx: Transaction) => {
|
|
||||||
await this.warp.arweave.transactions.sign(tx, signature);
|
|
||||||
},
|
|
||||||
signatureType: 'arweave'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,10 +758,9 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
if (!this.signature) {
|
if (!this.signature) {
|
||||||
throw new Error("Wallet not connected. Use 'connect' method first.");
|
throw new Error("Wallet not connected. Use 'connect' method first.");
|
||||||
}
|
}
|
||||||
const { arweave } = this.warp;
|
const source = new SourceImpl(this.warp);
|
||||||
const source = new SourceImpl(arweave);
|
|
||||||
|
|
||||||
const srcTx = await source.save(sourceData, this.warp.environment, this.signature.signer);
|
const srcTx = await source.save(sourceData, this.warp.environment, this.signature);
|
||||||
|
|
||||||
return srcTx.id;
|
return srcTx.id;
|
||||||
}
|
}
|
||||||
@@ -799,8 +768,4 @@ export class HandlerBasedContract<State> implements Contract<State> {
|
|||||||
get rootSortKey(): string {
|
get rootSortKey(): string {
|
||||||
return this._rootSortKey;
|
return this._rootSortKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isSignatureType(signature: ArWallet | Signature): signature is Signature {
|
|
||||||
return (signature as Signature).signer !== undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
45
src/contract/Signature.ts
Normal file
45
src/contract/Signature.ts
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import Transaction from 'arweave/node/lib/transaction';
|
||||||
|
import { Warp } from 'core/Warp';
|
||||||
|
import { ArWallet } from './deploy/CreateContract';
|
||||||
|
|
||||||
|
export type SigningFunction = (tx: Transaction) => Promise<void>;
|
||||||
|
export type SignatureType = { signer: SigningFunction; type: 'arweave' | 'ethereum' };
|
||||||
|
|
||||||
|
export class Signature {
|
||||||
|
readonly signer: SigningFunction;
|
||||||
|
readonly type: 'arweave' | 'ethereum';
|
||||||
|
readonly warp: Warp;
|
||||||
|
|
||||||
|
constructor(warp: Warp, walletOrSignature: ArWallet | SignatureType) {
|
||||||
|
this.warp = warp;
|
||||||
|
|
||||||
|
if (this.isSignatureType(walletOrSignature)) {
|
||||||
|
if (
|
||||||
|
walletOrSignature.type !== 'arweave' &&
|
||||||
|
(!(this.warp.environment == 'mainnet') || !(this.warp.interactionsLoader.type() == 'warp'))
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Unable to use signing function of type: ${walletOrSignature.type} when not in mainnet environment or bundling is disabled.`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.signer = walletOrSignature.signer;
|
||||||
|
this.type = walletOrSignature.type;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.signer = async (tx: Transaction) => {
|
||||||
|
await this.warp.arweave.transactions.sign(tx, walletOrSignature);
|
||||||
|
};
|
||||||
|
this.type = 'arweave';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkNonArweaveSigningAvailability(bundling: boolean): void {
|
||||||
|
if (this.type !== 'arweave' && !bundling) {
|
||||||
|
throw new Error(`Unable to use signing function of type: ${this.type} when bundling is disabled.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private isSignatureType(signature: ArWallet | SignatureType): signature is SignatureType {
|
||||||
|
return (signature as SignatureType).signer !== undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { JWKInterface } from 'arweave/node/lib/wallet';
|
import { JWKInterface } from 'arweave/node/lib/wallet';
|
||||||
|
import { SignatureType } from '../../contract/Signature';
|
||||||
|
|
||||||
export type Tags = { name: string; value: string }[];
|
export type Tags = { name: string; value: string }[];
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ export const emptyTransfer: ArTransfer = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export interface CommonContractData {
|
export interface CommonContractData {
|
||||||
wallet: ArWallet;
|
wallet: ArWallet | SignatureType;
|
||||||
initState: string;
|
initState: string;
|
||||||
tags?: Tags;
|
tags?: Tags;
|
||||||
transfer?: ArTransfer;
|
transfer?: ArTransfer;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SigningFunction } from '../../contract/Contract';
|
|
||||||
import { ArWallet } from './CreateContract';
|
import { ArWallet } from './CreateContract';
|
||||||
import { SourceData } from './impl/SourceImpl';
|
import { SourceData } from './impl/SourceImpl';
|
||||||
import { WarpEnvironment } from '../../core/Warp';
|
import { WarpEnvironment } from '../../core/Warp';
|
||||||
|
import { SignatureType } from '../../contract/Signature';
|
||||||
|
|
||||||
export interface Source {
|
export interface Source {
|
||||||
/**
|
/**
|
||||||
@@ -11,7 +11,7 @@ export interface Source {
|
|||||||
save(
|
save(
|
||||||
contractSource: SourceData,
|
contractSource: SourceData,
|
||||||
env: WarpEnvironment,
|
env: WarpEnvironment,
|
||||||
signer?: ArWallet | SigningFunction,
|
signer?: ArWallet | SignatureType,
|
||||||
useBundler?: boolean
|
useBundler?: boolean
|
||||||
): Promise<string | null>;
|
): Promise<string | null>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import Arweave from 'arweave';
|
import Arweave from 'arweave';
|
||||||
import Transaction from 'arweave/node/lib/transaction';
|
import Transaction from 'arweave/node/lib/transaction';
|
||||||
|
import { Signature } from '../../../contract/Signature';
|
||||||
import { SmartWeaveTags } from '../../../core/SmartWeaveTags';
|
import { SmartWeaveTags } from '../../../core/SmartWeaveTags';
|
||||||
import { Warp } from '../../../core/Warp';
|
import { Warp } from '../../../core/Warp';
|
||||||
import { WARP_GW_URL } from '../../../core/WarpFactory';
|
import { WARP_GW_URL } from '../../../core/WarpFactory';
|
||||||
@@ -11,6 +12,7 @@ import { Buffer } from 'redstone-isomorphic';
|
|||||||
|
|
||||||
export class DefaultCreateContract implements CreateContract {
|
export class DefaultCreateContract implements CreateContract {
|
||||||
private readonly logger = LoggerFactory.INST.create('DefaultCreateContract');
|
private readonly logger = LoggerFactory.INST.create('DefaultCreateContract');
|
||||||
|
private signature: Signature;
|
||||||
|
|
||||||
constructor(private readonly arweave: Arweave, private warp: Warp) {
|
constructor(private readonly arweave: Arweave, private warp: Warp) {
|
||||||
this.deployFromSourceTx = this.deployFromSourceTx.bind(this);
|
this.deployFromSourceTx = this.deployFromSourceTx.bind(this);
|
||||||
@@ -22,7 +24,7 @@ export class DefaultCreateContract implements CreateContract {
|
|||||||
const effectiveUseBundler =
|
const effectiveUseBundler =
|
||||||
disableBundling == undefined ? this.warp.definitionLoader.type() == 'warp' : !disableBundling;
|
disableBundling == undefined ? this.warp.definitionLoader.type() == 'warp' : !disableBundling;
|
||||||
|
|
||||||
const source = new SourceImpl(this.arweave);
|
const source = new SourceImpl(this.warp);
|
||||||
|
|
||||||
const srcTx = await source.save(contractData, this.warp.environment, wallet, effectiveUseBundler);
|
const srcTx = await source.save(contractData, this.warp.environment, wallet, effectiveUseBundler);
|
||||||
this.logger.debug('Creating new contract');
|
this.logger.debug('Creating new contract');
|
||||||
@@ -48,22 +50,23 @@ export class DefaultCreateContract implements CreateContract {
|
|||||||
): Promise<ContractDeploy> {
|
): Promise<ContractDeploy> {
|
||||||
this.logger.debug('Creating new contract from src tx');
|
this.logger.debug('Creating new contract from src tx');
|
||||||
const { wallet, srcTxId, initState, tags, transfer, data } = contractData;
|
const { wallet, srcTxId, initState, tags, transfer, data } = contractData;
|
||||||
|
this.signature = new Signature(this.warp, wallet);
|
||||||
|
const signer = this.signature.signer;
|
||||||
|
|
||||||
const effectiveUseBundler =
|
const effectiveUseBundler =
|
||||||
disableBundling == undefined ? this.warp.definitionLoader.type() == 'warp' : !disableBundling;
|
disableBundling == undefined ? this.warp.definitionLoader.type() == 'warp' : !disableBundling;
|
||||||
|
|
||||||
let contractTX = await this.arweave.createTransaction({ data: data?.body || initState }, wallet);
|
this.signature.checkNonArweaveSigningAvailability(effectiveUseBundler);
|
||||||
|
|
||||||
|
let contractTX = await this.arweave.createTransaction({ data: data?.body || initState });
|
||||||
|
|
||||||
if (+transfer?.winstonQty > 0 && transfer.target.length) {
|
if (+transfer?.winstonQty > 0 && transfer.target.length) {
|
||||||
this.logger.debug('Creating additional transaction with AR transfer', transfer);
|
this.logger.debug('Creating additional transaction with AR transfer', transfer);
|
||||||
contractTX = await this.arweave.createTransaction(
|
contractTX = await this.arweave.createTransaction({
|
||||||
{
|
data: data?.body || initState,
|
||||||
data: data?.body || initState,
|
target: transfer.target,
|
||||||
target: transfer.target,
|
quantity: transfer.winstonQty
|
||||||
quantity: transfer.winstonQty
|
});
|
||||||
},
|
|
||||||
wallet
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tags?.length) {
|
if (tags?.length) {
|
||||||
@@ -86,7 +89,7 @@ export class DefaultCreateContract implements CreateContract {
|
|||||||
contractTX.addTag(SmartWeaveTags.WARP_TESTNET, '1.0.0');
|
contractTX.addTag(SmartWeaveTags.WARP_TESTNET, '1.0.0');
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.arweave.transactions.sign(contractTX, wallet);
|
await signer(contractTX);
|
||||||
|
|
||||||
let responseOk: boolean;
|
let responseOk: boolean;
|
||||||
let response: { status: number; statusText: string; data: any };
|
let response: { status: number; statusText: string; data: any };
|
||||||
|
|||||||
@@ -1,16 +1,15 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import metering from 'redstone-wasm-metering';
|
import metering from 'redstone-wasm-metering';
|
||||||
import Arweave from 'arweave';
|
|
||||||
import { Go } from '../../../core/modules/impl/wasm/go-wasm-imports';
|
import { Go } from '../../../core/modules/impl/wasm/go-wasm-imports';
|
||||||
import fs, { PathOrFileDescriptor } from 'fs';
|
import fs, { PathOrFileDescriptor } from 'fs';
|
||||||
import { matchMutClosureDtor } from '../../../core/modules/impl/wasm/wasm-bindgen-tools';
|
import { matchMutClosureDtor } from '../../../core/modules/impl/wasm/wasm-bindgen-tools';
|
||||||
import { ArWallet, ContractType } from '../CreateContract';
|
import { ArWallet, ContractType } from '../CreateContract';
|
||||||
import { SigningFunction } from '../../../contract/Contract';
|
|
||||||
import { SmartWeaveTags } from '../../../core/SmartWeaveTags';
|
import { SmartWeaveTags } from '../../../core/SmartWeaveTags';
|
||||||
import { LoggerFactory } from '../../../logging/LoggerFactory';
|
import { LoggerFactory } from '../../../logging/LoggerFactory';
|
||||||
import { Source } from '../Source';
|
import { Source } from '../Source';
|
||||||
import { Buffer } from 'redstone-isomorphic';
|
import { Buffer } from 'redstone-isomorphic';
|
||||||
import { WarpEnvironment } from '../../../core/Warp';
|
import { Warp, WarpEnvironment } from '../../../core/Warp';
|
||||||
|
import { Signature, SignatureType } from '../../../contract/Signature';
|
||||||
|
|
||||||
const wasmTypeMapping: Map<number, string> = new Map([
|
const wasmTypeMapping: Map<number, string> = new Map([
|
||||||
[1, 'assemblyscript'],
|
[1, 'assemblyscript'],
|
||||||
@@ -28,18 +27,25 @@ export interface SourceData {
|
|||||||
|
|
||||||
export class SourceImpl implements Source {
|
export class SourceImpl implements Source {
|
||||||
private readonly logger = LoggerFactory.INST.create('Source');
|
private readonly logger = LoggerFactory.INST.create('Source');
|
||||||
constructor(private readonly arweave: Arweave) {}
|
private signature: Signature;
|
||||||
|
|
||||||
|
constructor(private readonly warp: Warp) {}
|
||||||
|
|
||||||
async save(
|
async save(
|
||||||
contractData: SourceData,
|
contractData: SourceData,
|
||||||
env: WarpEnvironment,
|
env: WarpEnvironment,
|
||||||
signer: ArWallet | SigningFunction,
|
signature: ArWallet | SignatureType,
|
||||||
useBundler = false
|
useBundler = false
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
this.logger.debug('Creating new contract source');
|
this.logger.debug('Creating new contract source');
|
||||||
|
|
||||||
const { src, wasmSrcCodeDir, wasmGlueCode } = contractData;
|
const { src, wasmSrcCodeDir, wasmGlueCode } = contractData;
|
||||||
|
|
||||||
|
this.signature = new Signature(this.warp, signature);
|
||||||
|
const signer = this.signature.signer;
|
||||||
|
|
||||||
|
this.signature.checkNonArweaveSigningAvailability(useBundler);
|
||||||
|
|
||||||
const contractType: ContractType = src instanceof Buffer ? 'wasm' : 'js';
|
const contractType: ContractType = src instanceof Buffer ? 'wasm' : 'js';
|
||||||
let srcTx;
|
let srcTx;
|
||||||
let wasmLang = null;
|
let wasmLang = null;
|
||||||
@@ -102,11 +108,7 @@ export class SourceImpl implements Source {
|
|||||||
|
|
||||||
const allData = contractType == 'wasm' ? this.joinBuffers(data) : src;
|
const allData = contractType == 'wasm' ? this.joinBuffers(data) : src;
|
||||||
|
|
||||||
if (typeof signer == 'function') {
|
srcTx = await this.warp.arweave.createTransaction({ data: allData });
|
||||||
srcTx = await this.arweave.createTransaction({ data: allData });
|
|
||||||
} else {
|
|
||||||
srcTx = await this.arweave.createTransaction({ data: allData }, signer);
|
|
||||||
}
|
|
||||||
|
|
||||||
srcTx.addTag(SmartWeaveTags.APP_NAME, 'SmartWeaveContractSource');
|
srcTx.addTag(SmartWeaveTags.APP_NAME, 'SmartWeaveContractSource');
|
||||||
// TODO: version should be taken from the current package.json version.
|
// TODO: version should be taken from the current package.json version.
|
||||||
@@ -124,11 +126,8 @@ export class SourceImpl implements Source {
|
|||||||
srcTx.addTag(SmartWeaveTags.WARP_TESTNET, '1.0.0');
|
srcTx.addTag(SmartWeaveTags.WARP_TESTNET, '1.0.0');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof signer == 'function') {
|
await signer(srcTx);
|
||||||
await signer(srcTx);
|
|
||||||
} else {
|
|
||||||
await this.arweave.transactions.sign(srcTx, signer);
|
|
||||||
}
|
|
||||||
this.logger.debug('Posting transaction with source');
|
this.logger.debug('Posting transaction with source');
|
||||||
|
|
||||||
// note: in case of useBundler = true, we're posting both
|
// note: in case of useBundler = true, we're posting both
|
||||||
@@ -136,7 +135,7 @@ export class SourceImpl implements Source {
|
|||||||
let responseOk = true;
|
let responseOk = true;
|
||||||
let response: { status: number; statusText: string; data: any };
|
let response: { status: number; statusText: string; data: any };
|
||||||
if (!useBundler) {
|
if (!useBundler) {
|
||||||
response = await this.arweave.transactions.post(srcTx);
|
response = await this.warp.arweave.transactions.post(srcTx);
|
||||||
responseOk = response.status === 200 || response.status === 208;
|
responseOk = response.status === 200 || response.status === 208;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { CreateTransactionInterface } from 'arweave/node/common';
|
|||||||
import { BlockData } from 'arweave/node/blocks';
|
import { BlockData } from 'arweave/node/blocks';
|
||||||
import { SmartWeaveTags } from '../core/SmartWeaveTags';
|
import { SmartWeaveTags } from '../core/SmartWeaveTags';
|
||||||
import { GQLNodeInterface } from './gqlResult';
|
import { GQLNodeInterface } from './gqlResult';
|
||||||
import { SigningFunction } from '../contract/Contract';
|
|
||||||
import { TagsParser } from '../core/modules/impl/TagsParser';
|
import { TagsParser } from '../core/modules/impl/TagsParser';
|
||||||
|
import { SigningFunction } from '../contract/Signature';
|
||||||
|
|
||||||
export async function createInteractionTx(
|
export async function createInteractionTx(
|
||||||
arweave: Arweave,
|
arweave: Arweave,
|
||||||
|
|||||||
Reference in New Issue
Block a user