Skip to content

Commit

Permalink
add deploySC
Browse files Browse the repository at this point in the history
  • Loading branch information
peterjah committed Dec 3, 2024
1 parent c45f5a4 commit 76792fd
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 6 deletions.
2 changes: 1 addition & 1 deletion packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/massalabs/metamask-massa.git"
},
"source": {
"shasum": "KqCZqbU7xRPsvxPn66moq8eFjwZsgofIwrqDPK7DHAs=",
"shasum": "PcT+u0rwzqYHXfkiy34U1v/1YjSDtvnBBJntrE1PXRc=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
4 changes: 1 addition & 3 deletions packages/snap/src/components/CallSc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,7 @@ export const CallSc: SnapComponent<CallScProps> = (params: CallScProps) => {
<Bold>Arguments: </Bold>
{params.args.toString()}
</Text>
) : (
<> </>
)}
) : null}
</Section>
</Box>
</Container>
Expand Down
54 changes: 54 additions & 0 deletions packages/snap/src/components/DeploySc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Mas } from '@massalabs/massa-web3';
import {
SnapComponent,
Container,
Box,
Heading,
Text,
Section,
Bold,
} from '@metamask/snaps-sdk/jsx';

type DeployScProps = {
fee: string;
args: number[];
coins: string;
maxCoins: string;
};

export const DeploySc: SnapComponent<DeployScProps> = ({
fee,
args,
coins,
maxCoins,
}) => {
return (
<Container>
<Box>
<Heading>Deploying Smart contract</Heading>
<Section>
<Text>
<Bold>Coins: </Bold>
{Mas.toString(BigInt(coins))} MAS
</Text>
<Text>
<Bold>Max coins: </Bold>
{maxCoins !== 'none'
? `${Mas.toString(BigInt(maxCoins))} MAS`
: 'none'}
</Text>
<Text>
<Bold>Fee: </Bold>
{Mas.toString(BigInt(fee))} MAS
</Text>
{args.length ? (
<Text>
<Bold>Constructor arguments: </Bold>
{args.toString()}
</Text>
) : null}
</Section>
</Box>
</Container>
);
};
3 changes: 1 addition & 2 deletions packages/snap/src/handlers/call-smart-contract.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,9 @@ const validate = (params: CallSCParameters) => {
};
/**
* @description Calls a smart contract with the given parameters
* @param params - The call smart contract parameters (see `CallSCParameters` type and massa standard)
* @param params - CallSCParameters
* @returns The operation id
* @throws If the user denies the transaction
* @throws If the client or account is not found
*/
export const callSmartContract: Handler<
CallSCParameters,
Expand Down
96 changes: 96 additions & 0 deletions packages/snap/src/handlers/deploy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { getProvider } from '../accounts/provider';
import { addAccountOperation } from '../operations';
import type { Handler } from './handler';
import { DeploySc } from '../components/DeploySc';
import { DeploySCParams } from '@massalabs/massa-web3';
import { getActiveNetwork } from '../active-chain';

export type DeploySCParameters = {
bytecode: number[];
fee?: string;
args?: number[];
coins?: string;
maxCoins?: string;
maxGas?: string;
};

export type DeploySCResponse = {
operationId: string;
};

const validate = (params: DeploySCParameters) => {
// mandatory parameters
if (!params.bytecode || !Array.isArray(params.bytecode)) {
throw new Error('Invalid params: bytecode must be an array');
}

// optionnal parameters
if (params.args && !Array.isArray(params.args)) {
throw new Error('Invalid params: args must be an array');
}
if (params.fee && typeof params.fee !== 'string') {
throw new Error('Invalid params: fee must be a string');
}
if (params?.coins && typeof params.coins !== 'string') {
throw new Error('Invalid params: coins must be a string');
}
if (params?.maxGas && typeof params.maxGas !== 'string') {
throw new Error('Invalid params: maxGas must be a string');
}
if (params?.maxCoins && typeof params.maxCoins !== 'string') {
throw new Error('Invalid params: maxCoins must be a string');
}
};
/**
* @description Deploy a smart contract
* @param params - DeploySCParameters
* @returns The operation id
* @throws If the user denies the transaction
*/
export const deployContract: Handler<
DeploySCParameters,
DeploySCResponse
> = async (params) => {
validate(params);
const provider = await getProvider();

const networkInfos = await getActiveNetwork();
const fee = params.fee ? params.fee : networkInfos.minimalFees;

const confirm = await snap.request({
method: 'snap_dialog',
params: {
type: 'confirmation',
content: (
<DeploySc
fee={fee}
args={params.args ?? []}
coins={params.coins ?? '0'}
maxCoins={params.maxCoins ?? 'none'}
/>
),
},
});

if (!confirm) {
throw new Error('User denied calling smart contract');
}
const deploySCParams: DeploySCParams = {
parameter: Uint8Array.from(params.args ?? []),
byteCode: Uint8Array.from(params.bytecode),
fee: BigInt(fee),
};

if (params.coins) {
deploySCParams.coins = BigInt(params.coins);
}
if (params.maxGas) {
deploySCParams.maxGas = BigInt(params.maxGas);
}
// bypass protected attribute of deploy function
const operationId: string = await (provider as any).deploy(deploySCParams);
await addAccountOperation(provider.address, operationId);
return {
operationId,
};
};
1 change: 1 addition & 0 deletions packages/snap/src/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './call-smart-contract';
export * from './deploy';
export * from './sign-message';
export * from './transfer';
export * from './get-balance';
Expand Down
4 changes: 4 additions & 0 deletions packages/snap/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import type {
GetOperationsParams,
ClearOperationsParams,
GetBalanceParams,
DeploySCParameters,
} from './handlers';
import {
getBalance,
Expand All @@ -36,6 +37,7 @@ import {
getTokens,
getOperations,
clearOperations,
deployContract,
} from './handlers';
import { getActiveAccount } from './handlers/get-active-account';

Expand All @@ -61,6 +63,8 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => {
return signMessage(request.params as SignMessageParams);
case 'account.callSC':
return callSmartContract(request.params as CallSCParameters);
case 'account.deploySC':
return deployContract(request.params as DeploySCParameters);
case 'account.sendTransaction':
return transfer(request.params as TransferParams);
case 'account.sellRolls':
Expand Down
2 changes: 2 additions & 0 deletions packages/snap/test/call-sc.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ describe('call-sc', () => {
params: baseParams,
});

await response.getInterface();

const ui = (await response.getInterface()) as SnapConfirmationInterface;

expect(ui.type).toBe('confirmation');
Expand Down
35 changes: 35 additions & 0 deletions packages/snap/test/deploy-sc.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { expect } from '@jest/globals';
import type { SnapConfirmationInterface } from '@metamask/snaps-jest';
import { installSnap } from '@metamask/snaps-jest';
import { DeploySc } from '../src/components/DeploySc';

const baseParams = {
bytecode: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
fee: '1000000000000000',
};

describe('deploy-sc', () => {
const origin = 'Jest';

it('should render ui', async () => {
const { request } = await installSnap();

const response = request({
method: 'account.deploySC',
origin,
params: baseParams,
});

const ui = (await response.getInterface()) as SnapConfirmationInterface;

expect(ui.type).toBe('confirmation');
expect(ui).toRender(
<DeploySc
fee={'1000000000000000'}
maxCoins={'none'}
args={[]}
coins={'0'}
/>,
);
});
});

0 comments on commit 76792fd

Please sign in to comment.