Skip to content

Commit

Permalink
Feat: Base chain support for Superfluid (#182)
Browse files Browse the repository at this point in the history
* feat: create base package

* [CORE] feat: add Base Blockchain

* [CORE] v1.0.4

* [EVM] feat: Add Base + ETH Sepolia chains data

* [EVM] v1.0.4

* feat: generalize SuperfluidAccount to handle EVM Accounts

* [SUPERFLUID] v1.1.0

* [EVM] feat: add chain when not listed on connect

* Fix: message.chain=ETH for all EVM chains messages (else rejected)

* Fix: message.chain=ETH for all EVM chains messages (else rejected)

---------

Co-authored-by: philogicae <[email protected]>
  • Loading branch information
gmolki and philogicae authored Sep 5, 2024
1 parent 9703fe7 commit ed1ef77
Show file tree
Hide file tree
Showing 20 changed files with 579 additions and 232 deletions.
120 changes: 114 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
"messages",
"ethereum",
"solana",
"avalanche",
"avax",
"base",
"defi",
"dao",
"nft"
Expand All @@ -32,7 +35,8 @@
"Roman Gascoin <[email protected]>",
"Mike Hukiewitz <[email protected]>",
"Kelian Christophe <[email protected]>",
"Angel Manzano <[email protected]>"
"Angel Manzano <[email protected]>",
"Gerard Molina <[email protected]>"
],
"license": "MIT",
"engines": {
Expand Down Expand Up @@ -73,6 +77,7 @@
"packages/ethereum",
"packages/ethereum-ledger",
"packages/avalanche",
"packages/base",
"packages/nuls2",
"packages/cosmos",
"packages/solana",
Expand All @@ -83,4 +88,4 @@
"packages/client",
"packages/dns"
]
}
}
16 changes: 9 additions & 7 deletions packages/avalanche/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import { KeyPair, KeyChain } from 'avalanche/dist/apis/avm'
import { KeyPair as EVMKeyPair } from 'avalanche/dist/apis/evm'
import { ethers, providers } from 'ethers'
import { privateToAddress } from 'ethereumjs-util'

import { Blockchain } from '@aleph-sdk/core'
import { SignableMessage, BaseProviderWallet } from '@aleph-sdk/account'
import { ChangeRpcParam, RpcId, EVMAccount, JsonRPCWallet } from '@aleph-sdk/evm'
import { ChangeRpcParam, RpcId, EVMAccount, JsonRPCWallet, ChainData } from '@aleph-sdk/evm'
import { digestMessage, verifyAvalanche } from './verify'

/**
Expand Down Expand Up @@ -152,18 +151,21 @@ export async function importAccountFromMnemonic(
/**
* Get an account from a Web3 provider (ex: Metamask)
*
* @param {providers.ExternalProvider} provider from metamask
* @param {providers.ExternalProvider | ethers.providers.Web3Provider} provider
* @param requestedRpc Use this params to change the RPC endpoint;
*/
export async function getAccountFromProvider(
provider: providers.ExternalProvider,
provider: ethers.providers.ExternalProvider | ethers.providers.Web3Provider,
requestedRpc: ChangeRpcParam = RpcId.AVAX,
): Promise<AvalancheAccount> {
const avaxProvider = new providers.Web3Provider(provider)
const jrw = new JsonRPCWallet(avaxProvider)
await jrw.changeNetwork(requestedRpc)
const ETHprovider =
provider instanceof ethers.providers.Web3Provider ? provider : new providers.Web3Provider(provider)
const jrw = new JsonRPCWallet(ETHprovider)

const chainId = Number((typeof requestedRpc === 'number' ? ChainData[requestedRpc] : requestedRpc).chainId)
if (chainId !== (await jrw.provider.getNetwork()).chainId) await jrw.changeNetwork(requestedRpc)
await jrw.connect()

if (jrw.address) {
return new AvalancheAccount(jrw, jrw.address)
}
Expand Down
9 changes: 9 additions & 0 deletions packages/base/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# @aleph-sdk/base

This package provides an implementation for Base blockchain accounts within the Aleph.im ecosystem, enabling Base account management and message signing functionalities.

See [@aleph-sdk/client](https://npmjs.com/package/@aleph-sdk/client) or the [offical docs](https://docs.aleph.im) as the entrypoint for developing with aleph.im.

## Features

As Base Account extends from Ethereum account, see [@aleph-sdk/ethereum](https://www.npmjs.com/package/@aleph-sdk/ethereum)
87 changes: 87 additions & 0 deletions packages/base/__tests__/account.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import * as bip39 from 'bip39'
import { ethers } from 'ethers'

import * as base from '../src'
import { PostMessageBuilder, prepareAlephMessage, ItemType } from '../../message/src'
import { EthereumMockProvider } from '@aleph-sdk/evm'
import { EphAccount } from '@aleph-sdk/account'

async function createEphemeralEth(): Promise<EphAccount> {
const mnemonic = bip39.generateMnemonic()
const { address, publicKey, privateKey } = ethers.Wallet.fromMnemonic(mnemonic)

return {
address,
publicKey,
privateKey: privateKey.substring(2),
mnemonic,
}
}

describe('Ethereum accounts', () => {
let ephemeralAccount: EphAccount

beforeAll(async () => {
ephemeralAccount = await createEphemeralEth()
})

it('should import a base account using a mnemonic', () => {
const { account, mnemonic } = base.newAccount()
const accountFromMnemonic = base.importAccountFromMnemonic(mnemonic)

expect(account.address).toStrictEqual(accountFromMnemonic.address)
})

it('should import a base account using a private key', () => {
const mnemonic = bip39.generateMnemonic()
const wallet = ethers.Wallet.fromMnemonic(mnemonic)
const accountFromPrivate = base.importAccountFromPrivateKey(wallet.privateKey)

expect(wallet.address).toStrictEqual(accountFromPrivate.address)
})

it('should import a base account using a provider', async () => {
const { address, privateKey } = ephemeralAccount
if (!privateKey) throw Error('Can not retrieve privateKey inside ephemeralAccount.json')

const provider = new EthereumMockProvider({
address,
privateKey,
networkVersion: 31,
})

const accountFromProvider = await base.getAccountFromProvider(provider)
const accountFromPrivate = base.importAccountFromPrivateKey(privateKey)

expect(accountFromProvider.address).toStrictEqual(accountFromPrivate.address)
})

it('should get the same signed message for each account', async () => {
const { address, privateKey } = ephemeralAccount
if (!privateKey) throw Error('Can not retrieve privateKey inside ephemeralAccount.json')

const provider = new EthereumMockProvider({
address,
privateKey,
networkVersion: 31,
})
const { account, mnemonic } = base.newAccount()
const accountFromProvider = await base.getAccountFromProvider(provider)
const accountFromPrivate = await base.importAccountFromMnemonic(mnemonic)

const builtMessage = PostMessageBuilder({
account,
channel: 'TEST',
storageEngine: ItemType.inline,
timestamp: Date.now() / 1000,
content: { address: account.address, time: 15, type: '' },
})

const hashedMessage = await prepareAlephMessage({
message: builtMessage,
})

expect(account.sign(hashedMessage)).toStrictEqual(accountFromPrivate.sign(hashedMessage))
expect(account.sign(hashedMessage)).toStrictEqual(accountFromProvider.sign(hashedMessage))
})
})
38 changes: 38 additions & 0 deletions packages/base/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@aleph-sdk/base",
"version": "1.0.0",
"description": "Base accounts for signing messages on aleph.im",
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"devDependencies": {
"@types/sha.js": "^2.4.0"
},
"dependencies": {
"eciesjs": "^0.4.6",
"sha.js": "^2.4.11"
},
"peerDependencies": {
"@aleph-sdk/account": "^1.x.x",
"@aleph-sdk/core": "^1.0.4",
"@aleph-sdk/evm": "^1.0.4",
"@aleph-sdk/ethereum": "^1.x.x",
"avalanche": "^3.15.3",
"ethers": "^5.x.x"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"rollup": "rollup -c ../../rollup.config.js",
"build": "npm run rollup"
},
"author": "",
"homepage": "https://aleph.im",
"bugs": "https://github.com/aleph-im/aleph-sdk-ts/issues",
"license": "MIT"
}
Loading

0 comments on commit ed1ef77

Please sign in to comment.