Skip to content

Commit

Permalink
- Added a test website for testing the snap
Browse files Browse the repository at this point in the history
- Made adjustments to the core mm snap functions to allow for a dynamically passed in snap id
- Improved the UI of the snap popups
  • Loading branch information
codebycarson committed Jan 4, 2024
1 parent d4e4bfa commit 5b327c1
Show file tree
Hide file tree
Showing 71 changed files with 8,518 additions and 275 deletions.
16 changes: 2 additions & 14 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
# Changelog

## 0.0.0-internal-20231226184402

### Minor Changes

- Simplified exports

## 0.0.0-internal-20231226181823

### Patch Changes

- Updated @noble versions

## 0.0.0-internal-20231226173424
## 0.0.0-internal-20240104081628

### Patch Changes

- Moved helper libraries to /core
- pre-release test

## 3.1.2

Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sei-js/core",
"version": "0.0.0-internal-20231226184402",
"version": "3.1.2",
"private": false,
"description": "TypeScript library for front end integrations with Sei",
"keywords": [
Expand Down
72 changes: 0 additions & 72 deletions packages/core/src/lib/mmSnap/__tests__/snapWallet.spec.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/core/src/lib/mmSnap/config.ts

This file was deleted.

71 changes: 49 additions & 22 deletions packages/core/src/lib/mmSnap/cosmjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ export const requestSignature = async (
authInfoBytes?: Uint8Array | null;
chainId?: string | null;
accountNumber?: Long | null;
}
) => {
const signature = await sendReqToSnap('signDirect', {
chainId,
signerAddress,
signDoc
});
},
snapId: string
): Promise<DirectSignResponse> => {
const signature = await sendReqToSnap(
'signDirect',
{
chainId,
signerAddress,
signDoc
},
snapId
);

const { accountNumber } = signDoc;

Expand All @@ -40,13 +45,15 @@ export const requestSignature = async (

export class CosmJSOfflineSigner implements OfflineDirectSigner {
readonly chainId: string;
readonly snapId: string;

constructor(chainId: string) {
constructor(chainId: string, snapId: string) {
this.chainId = chainId;
this.snapId = snapId;
}

async getAccounts(): Promise<AccountData[]> {
const wallet = await getWallet(0);
const wallet = await getWallet(0, this.snapId);
return wallet.getAccounts();
}

Expand All @@ -60,10 +67,9 @@ export class CosmJSOfflineSigner implements OfflineDirectSigner {
throw new Error('Signer address does not match wallet address');
}

return requestSignature(this.chainId, signerAddress, signDoc) as Promise<DirectSignResponse>;
return requestSignature(this.chainId, signerAddress, signDoc, this.snapId);
}

// This has been added as a placeholder.
async signAmino(signerAddress: string, signDoc: StdSignDoc, options?: SignAminoOptions): Promise<AminoSignResponse> {
if (this.chainId !== signDoc.chain_id) {
throw new Error('Chain ID does not match signer chain ID');
Expand All @@ -74,31 +80,52 @@ export class CosmJSOfflineSigner implements OfflineDirectSigner {
throw new Error('Signer address does not match wallet address');
}

return requestSignAmino(this.chainId, signerAddress, signDoc, options) as unknown as Promise<AminoSignResponse>;
return requestSignAmino(this.chainId, signerAddress, signDoc, this.snapId, options);
}

async signArbitrary(signer: string, data: string, signOptions?: { enableExtraEntropy?: boolean }) {
const signDoc = makeADR36AminoSignDoc(signer, data);
const result = await requestSignAmino(this.chainId, signer, signDoc, {
const result = await requestSignAmino(this.chainId, signer, signDoc, this.snapId, {
isADR36: true,
preferNoSetFee: true,
enableExtraEntropy: signOptions?.enableExtraEntropy
});
return result.signature;
}
}

export const requestSignAmino = async (chainId: string, signerAddress: string, signDoc: StdSignDoc, options?: SignAminoOptions) => {
const { isADR36 = false, enableExtraEntropy = false } = options || {};
export const requestSignAmino = async (
chainId: string,
signerAddress: string,
signDoc: StdSignDoc,
snapId: string,
options?: SignAminoOptions
): Promise<AminoSignResponse> => {
const { isADR36 = false, enableExtraEntropy = false, preferNoSetFee = true } = options || {};

if (!preferNoSetFee) {
// @ts-ignore
signDoc.fee.amount = [
{
amount: '0.1',
denom: 'usei'
}
];
}

if (!isADR36 && chainId !== signDoc.chain_id) {
throw new Error('Chain ID does not match signer chain ID');
}

return (await sendReqToSnap('signAmino', {
chainId,
signerAddress,
signDoc,
isADR36,
enableExtraEntropy
})) as AminoSignResponse;
return (await sendReqToSnap(
'signAmino',
{
chainId,
signerAddress,
signDoc,
isADR36,
enableExtraEntropy
},
snapId
)) as AminoSignResponse;
};
1 change: 0 additions & 1 deletion packages/core/src/lib/mmSnap/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './config';
export * from './cosmjs';
export * from './snapWallet';
export * from './types';
Expand Down
16 changes: 8 additions & 8 deletions packages/core/src/lib/mmSnap/snapWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ import { BIP44Node } from '@metamask/key-tree';
import { AccountData, encodeSecp256k1Signature, StdSignDoc } from '@cosmjs/amino';
import { Buffer } from 'buffer';
import { CosmJSOfflineSigner } from './cosmjs';
import { MM_SNAP_ORIGIN } from './config';
import { getSnapEthereumProvider, sendReqToSnap } from './utils';
import { compressedPubKeyToAddress, serializeAminoSignDoc, serializeDirectSignDoc } from '../utils';
import { SeiWallet } from '../wallet';

const MM_SNAP_ORIGIN = 'npm:@sei-js/metamask-snap';

export class SnapWallet {
constructor(private privateKey: Uint8Array, private compressedPubKey: Uint8Array, private address: string) {}

static create(privateKey: string) {
const sanitizedPvtKey = privateKey.replace('0x', '');
const pvtKeyBytes = Buffer.from(sanitizedPvtKey, 'hex');

const compressedPubKey = getSecp256k1PublicKey(pvtKeyBytes, true);
const seiAddress = compressedPubKeyToAddress(compressedPubKey);
return new SnapWallet(pvtKeyBytes, compressedPubKey, seiAddress);
Expand Down Expand Up @@ -79,8 +79,8 @@ export class SnapWallet {
}
}

export async function getWallet(account_index = 0): Promise<SnapWallet> {
const account: BIP44Node = await sendReqToSnap('getPrivateKey', { account_index });
export async function getWallet(account_index = 0, origin: string): Promise<SnapWallet> {
const account: BIP44Node = await sendReqToSnap('getPrivateKey', { account_index }, origin);

if (account.privateKey) {
return SnapWallet.create(account.privateKey);
Expand All @@ -91,7 +91,7 @@ export async function getWallet(account_index = 0): Promise<SnapWallet> {
// Awaiting audit
export const experimental_SEI_METAMASK_SNAP: SeiWallet = {
getAccounts: async (chainId) => {
const offlineSigner = new CosmJSOfflineSigner(chainId);
const offlineSigner = new CosmJSOfflineSigner(chainId, MM_SNAP_ORIGIN);
return offlineSigner.getAccounts();
},
connect: async (_: string) => {
Expand All @@ -110,13 +110,13 @@ export const experimental_SEI_METAMASK_SNAP: SeiWallet = {
throw new Error('Not implemented');
},
getOfflineSigner: async (chainId) => {
return new CosmJSOfflineSigner(chainId);
return new CosmJSOfflineSigner(chainId, MM_SNAP_ORIGIN);
},
getOfflineSignerAmino: async (chainId) => {
return new CosmJSOfflineSigner(chainId);
return new CosmJSOfflineSigner(chainId, MM_SNAP_ORIGIN);
},
signArbitrary: async (chainId, signer, message) => {
const offlineSigner = new CosmJSOfflineSigner(chainId);
const offlineSigner = new CosmJSOfflineSigner(chainId, MM_SNAP_ORIGIN);
return offlineSigner.signArbitrary(signer, message);
},
verifyArbitrary: async (_: string, signingAddress, data, signature) => {
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/mmSnap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ declare global {

export type SignAminoOptions = {
isADR36?: boolean;
preferNoSetFee?: boolean;
enableExtraEntropy?: boolean;
};
5 changes: 2 additions & 3 deletions packages/core/src/lib/mmSnap/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { EthereumProvider } from './types';
import { MM_SNAP_ORIGIN } from './config';

/**
* The fool proof version of getting the ethereum provider suggested by
Expand Down Expand Up @@ -51,12 +50,12 @@ export const getSnapEthereumProvider = async (): Promise<EthereumProvider> => {
return window.ethereum;
};

export const sendReqToSnap = async (method: string, params: any): Promise<any> => {
export const sendReqToSnap = async (method: string, params: any, snapId: string): Promise<any> => {
const provider = await getSnapEthereumProvider();
return provider.request({
method: 'wallet_invokeSnap',
params: {
snapId: MM_SNAP_ORIGIN,
snapId,
request: {
method,
params
Expand Down
44 changes: 44 additions & 0 deletions packages/metamask-snap/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module.exports = {
root: true,
parserOptions: {
sourceType: 'module',
},

extends: ['@metamask/eslint-config'],

overrides: [
{
files: ['**/*.js'],
extends: ['@metamask/eslint-config-nodejs'],
},

{
files: ['**/*.{ts,tsx}'],
extends: ['@metamask/eslint-config-typescript'],
rules: {
'@typescript-eslint/consistent-type-definitions': ['error', 'type'],
},
},

{
files: ['**/*.test.ts', '**/*.test.js'],
extends: ['@metamask/eslint-config-jest'],
rules: {
'@typescript-eslint/no-shadow': [
'error',
{ allow: ['describe', 'expect', 'it'] },
],
},
},
],

ignorePatterns: [
'!.prettierrc.js',
'**/!.eslintrc.js',
'**/dist*/',
'**/*__GENERATED__*',
'**/build',
'**/public',
'**/.cache',
],
};
9 changes: 0 additions & 9 deletions packages/metamask-snap/.eslintrc.json

This file was deleted.

Loading

0 comments on commit 5b327c1

Please sign in to comment.