Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aptos init support #74

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sdk/apps/aptos/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/.nightly-connect-session
55 changes: 55 additions & 0 deletions sdk/apps/aptos/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "@nightlylabs/nightly-connect-aptos",
"version": "0.0.1",
"type": "module",
"exports": {
".": {
"import": "./dist/index.mjs.js",
"require": "./dist/index.cjs.js",
"types": "./dist/index.d.ts"
}
},
"browser": {
"./dist/index.cjs.js": "./dist/index.browser.cjs.js",
"./dist/index.mjs.js": "./dist/index.browser.mjs.js"
},
"react-native": "dist/index.browser.cjs.js",
"main": "dist/index.cjs.js",
"module": "dist/index.mjs.js",
"types": "dist/index.d.ts",
"typings": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:run": "vitest run",
"test:production": "PRODUCTION=true vitest run",
"test:ci": "IS_CI=true vitest run",
"build": "rm -rf ./dist && rollup -c"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^25.0.0",
"@rollup/plugin-node-resolve": "^15.1.0",
"@rollup/plugin-terser": "^0.4.3",
"@rollup/plugin-typescript": "^11.1.1",
"@types/node": "^20.3.0",
"@vitest/ui": "^0.31.1",
"bs58": "^5.0.0",
"js-sha256": "^0.9.0",
"rollup": "^3.23.1",
"rollup-plugin-dts": "^5.3.0",
"tslib": "^2.5.3",
"tweetnacl": "^1.0.3",
"typescript": "^5.1.3"
},
"dependencies": {
"@nightlylabs/nightly-connect-base": "0.0.27",
"@aptos-labs/wallet-adapter-core": "^3.0.0",
"aptos": "^1.20.0",
"@noble/hashes": "^1.3.0",
"eventemitter3": "^5.0.1",
"uuid": "^9.0.0"
}
}
70 changes: 70 additions & 0 deletions sdk/apps/aptos/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import typescript from '@rollup/plugin-typescript'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import terser from '@rollup/plugin-terser'
import dts from 'rollup-plugin-dts'

export default [
{
input: 'src/index.ts',
output: [
{
file: 'dist/index.cjs.js',
format: 'cjs',
sourcemap: true,
interop: 'compat'
},
{
file: 'dist/index.mjs.js',
format: 'esm',
sourcemap: true
}
],
plugins: [typescript(), nodeResolve(), commonjs(), terser()],
external: [
'aptos',
'@aptos-labs/wallet-adapter-core',
'@nightlylabs/nightly-connect-base',
'uuid',
'eventemitter3',
'isomorphic-ws',
'ws'
]
},
{
input: 'src/index.ts',
output: [
{
file: 'dist/index.browser.cjs.js',
format: 'cjs',
sourcemap: true,
interop: 'compat'
},
{
file: 'dist/index.browser.mjs.js',
format: 'esm',
sourcemap: true
}
],
plugins: [
typescript(),
nodeResolve({ browser: true, preferBuiltins: false }),
commonjs(),
terser()
],
external: [
'aptos',
'@aptos-labs/wallet-adapter-core',
'@nightlylabs/nightly-connect-base',
'uuid',
'eventemitter3',
'isomorphic-ws',
'ws'
]
},
{
input: 'dist/types/apps/aptos/src/index.d.ts',
output: [{ file: 'dist/index.d.ts', format: 'esm' }],
plugins: [dts()]
}
]
144 changes: 144 additions & 0 deletions sdk/apps/aptos/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import type {
AccountInfo,
NetworkInfo,
SignMessagePayload,
SignMessageResponse,
Types
} from '@aptos-labs/wallet-adapter-core'
import {
BaseApp,
DeeplinkConnect,
MessageToSign,
TransactionToSign,
getWalletsMetadata
} from '@nightlylabs/nightly-connect-base'
import EventEmitter from 'eventemitter3'
import { UserDisconnectedEvent } from '../../../bindings/UserDisconnectedEvent'
import { WalletMetadata } from '../../../bindings/WalletMetadata'
import { APTOS_NETWORK, AppAptosInitialize, deserializeSignMessageResponse } from './utils'
export interface AptosUserConnectedEvent {
accounts: Array<AccountInfo>
networkInfo: NetworkInfo
metadata?: string
}

interface SuiAppEvents {
userConnected: (e: AptosUserConnectedEvent) => void
userDisconnected: (e: UserDisconnectedEvent) => void
serverDisconnected: () => void
}
export class AppAptos extends EventEmitter<SuiAppEvents> {
// Nightly Connect
sessionId: string
base: BaseApp
initData: AppAptosInitialize

constructor(base: BaseApp, initData: AppAptosInitialize) {
super()
this.initData = initData
this.base = base
this.sessionId = base.sessionId
this.base.on('userConnected', (e) => {
const keys = e.publicKeys.map((pk) => {
const accountInfo: AccountInfo = JSON.parse(pk)
return accountInfo
})
// metadata here should include networkInfo
const networkInfo: NetworkInfo = JSON.parse(e.metadata!).networkInfo
this.emit('userConnected', { accounts: keys, metadata: e.metadata, networkInfo })
})
this.base.on('userDisconnected', (e) => {
this.emit('userDisconnected', e)
})
this.base.on('serverDisconnected', async () => {
// We need this because of power saving mode on mobile
await this.tryReconnect()
})
}
private tryReconnect = async () => {
try {
const base = await BaseApp.build({ ...this.initData, network: APTOS_NETWORK })
// On reconnect, if the base has not been restored, emit serverDisconnected
if (!base.hasBeenRestored) {
this.emit('serverDisconnected')
return
}
base.on('userConnected', (e) => {
const keys = e.publicKeys.map((pk) => {
const accountInfo: AccountInfo = JSON.parse(pk)
return accountInfo
})
// metadata here should include networkInfo
const networkInfo: NetworkInfo = JSON.parse(e.metadata!).networkInfo
this.emit('userConnected', { accounts: keys, metadata: e.metadata, networkInfo })
})
base.on('userDisconnected', (e) => {
this.emit('userDisconnected', e)
})
base.on('serverDisconnected', async () => {
await this.tryReconnect()
})
// If there is a deeplink, reconnect to it
if (this.base.deeplink) {
base.connectDeeplink(this.base.deeplink)
}
this.base = base
return
} catch (_) {
console.warn('Could not reconnect to nightly server')
}
}

public hasBeenRestored = () => {
return this.base.hasBeenRestored
}
public get account() {
const accountInfo: AccountInfo = JSON.parse(this.base.connectedPublicKeys[0])
return accountInfo
}
public get network() {
const networkInfo: NetworkInfo = JSON.parse(this.base.connectedMetadata!).networkInfo
return networkInfo
}
public get connectedPublicKeys() {
return this.base.connectedPublicKeys
}
public get connectedMetadata() {
return this.base.connectedMetadata
}
public static getWalletsMetadata = async (url?: string): Promise<WalletMetadata[]> => {
return getWalletsMetadata(url, 'aptos')
}
public static build = async (initData: AppAptosInitialize): Promise<AppAptos> => {
const base = await BaseApp.build({ ...initData, network: APTOS_NETWORK })
return new AppAptos(base, initData)
}
connectDeeplink = async (data: DeeplinkConnect) => {
this.base.connectDeeplink(data)
}

async signAndSubmitTransaction(
transaction: Types.TransactionPayload,
options?: any
): Promise<{ hash: Types.HexEncodedBytes }> {
const transactionToSign: TransactionToSign = {
transaction: JSON.stringify(transaction),
metadata: JSON.stringify({ ...options, submit: true })
}
const signedTx = await this.base.signTransactions([transactionToSign])

return JSON.parse(signedTx[0].transaction)
}

async signMessage(message: SignMessagePayload): Promise<SignMessageResponse> {
if (typeof message !== 'object' || !message.nonce) {
throw `Nightly Invalid signMessage Payload`
}
const request: MessageToSign = {
message: JSON.stringify(message),
metadata: undefined
}
const signedTx = await this.base.signMessages([request])
return deserializeSignMessageResponse(signedTx[0].message)
}
}
Loading
Loading