From 84ef3c6c1330991c23c94197cfeaa69f6ed13185 Mon Sep 17 00:00:00 2001 From: LukassF Date: Tue, 17 Sep 2024 16:10:13 +0200 Subject: [PATCH 1/3] add support change network mobile aptos --- sdk/packages/aptos/package.json | 4 +- sdk/packages/aptos/src/app.ts | 14 +++++ sdk/packages/aptos/src/client.ts | 41 ++++++++++---- sdk/packages/aptos/src/utils.ts | 25 +++++---- sdk/packages/base/package.json | 2 +- sdk/packages/base/src/app.ts | 42 ++++++++++----- sdk/packages/base/src/client.ts | 62 +++++++++++++++++----- sdk/packages/base/src/content.ts | 16 +++++- sdk/packages/base/src/responseContent.ts | 8 +++ sdk/packages/selector-aptos/package.json | 2 +- sdk/packages/selector-aptos/src/adapter.ts | 3 +- sdk/packages/selector-base/package.json | 2 +- sdk/pnpm-lock.yaml | 12 ++--- 13 files changed, 175 insertions(+), 58 deletions(-) diff --git a/sdk/packages/aptos/package.json b/sdk/packages/aptos/package.json index d8dc8a8e..97528cc3 100644 --- a/sdk/packages/aptos/package.json +++ b/sdk/packages/aptos/package.json @@ -1,6 +1,6 @@ { "name": "@nightlylabs/nightly-connect-aptos", - "version": "0.0.2", + "version": "0.0.3", "type": "module", "exports": { ".": { @@ -45,7 +45,7 @@ "dependencies": { "@aptos-labs/ts-sdk": "^1.9.1", "@aptos-labs/wallet-standard": "^0.0.11", - "@nightlylabs/nightly-connect-base": "^0.0.28", + "@nightlylabs/nightly-connect-base": "^0.0.29", "eventemitter3": "^5.0.1" } } diff --git a/sdk/packages/aptos/src/app.ts b/sdk/packages/aptos/src/app.ts index 10e43fe2..3153f012 100644 --- a/sdk/packages/aptos/src/app.ts +++ b/sdk/packages/aptos/src/app.ts @@ -1,5 +1,6 @@ import { AccountInfo, + AptosChangeNetworkMethod, AptosSignAndSubmitTransactionMethod, AptosSignMessageMethod, AptosSignMessageOutput, @@ -151,4 +152,17 @@ export class AppAptos extends EventEmitter { args: deserializeObject(signedTx[0].message) as AptosSignMessageOutput } } + + changeNetwork: AptosChangeNetworkMethod = async (input) => { + const changedNetworkSuccess = await this.base.changeNetwork({ + ...input, + name: input.name as string + }) + return { + status: UserResponseStatus.APPROVED, + args: { + success: !!changedNetworkSuccess.newNetwork + } + } + } } diff --git a/sdk/packages/aptos/src/client.ts b/sdk/packages/aptos/src/client.ts index c7d12ab1..f04ec127 100644 --- a/sdk/packages/aptos/src/client.ts +++ b/sdk/packages/aptos/src/client.ts @@ -1,10 +1,19 @@ -import { AppDisconnectedEvent } from '../../../bindings/AppDisconnectedEvent' +import { AnyRawTransaction } from '@aptos-labs/ts-sdk' +import { + AccountInfo, + AptosSignAndSubmitTransactionOutput, + AptosSignMessageInput, + AptosSignMessageOutput, + AptosSignTransactionOutput, + NetworkInfo +} from '@aptos-labs/wallet-standard' import { BaseClient, ClientBaseInitialize, Connect as ConnectBase } from '@nightlylabs/nightly-connect-base' import { EventEmitter } from 'eventemitter3' +import { AppDisconnectedEvent } from '../../../bindings/AppDisconnectedEvent' import { GetInfoResponse } from '../../../bindings/GetInfoResponse' import { AptosRequest } from './requestTypes' import { @@ -16,15 +25,6 @@ import { serializeObject, serializePendingTransactionResponse } from './utils' -import { AnyRawTransaction } from '@aptos-labs/ts-sdk' -import { - AccountInfo, - AptosSignAndSubmitTransactionOutput, - AptosSignMessageInput, - AptosSignMessageOutput, - AptosSignTransactionOutput, - NetworkInfo -} from '@aptos-labs/wallet-standard' export interface SignAndSubmitTransactionEvent { sessionId: string requestId: string @@ -136,6 +136,22 @@ export class ClientAptos extends EventEmitter { return requests.map((request) => parseRequest(request, sessionIdToUse)) } + public resolveChangeNetwork = async ({ + requestId, + newNetwork, + sessionId + }: ResolveChangeNetwork) => { + const sessionIdToUse = sessionId || this.sessionId + if (sessionIdToUse === undefined) { + throw new Error('Session id is undefined') + } + await this.baseClient.resolveChangeNetwork({ + requestId, + newNetwork, + sessionId: sessionIdToUse + }) + } + public resolveSignTransaction = async ({ requestId, signedTransactions, @@ -236,3 +252,8 @@ export interface ResolveSignAptosMessage { signedMessages: Array sessionId?: string } +export interface ResolveChangeNetwork { + requestId: string + newNetwork: NetworkInfo + sessionId?: string +} diff --git a/sdk/packages/aptos/src/utils.ts b/sdk/packages/aptos/src/utils.ts index a1cb18ad..883c507d 100644 --- a/sdk/packages/aptos/src/utils.ts +++ b/sdk/packages/aptos/src/utils.ts @@ -1,22 +1,20 @@ -import { AppBaseInitialize, ContentType, RequestContent } from '@nightlylabs/nightly-connect-base' -import { - AptosRequest, - CustomAptosRequest, - SignMessagesAptosRequest, - SignTransactionsAptosRequest -} from './requestTypes' import { AccountAddress, AccountAuthenticator, AnyRawTransaction, Deserializer, - Ed25519PublicKey, PendingTransactionResponse, - PublicKey, RawTransaction, Serializer } from '@aptos-labs/ts-sdk' import { AccountInfo, NetworkInfo } from '@aptos-labs/wallet-standard' +import { AppBaseInitialize, ContentType, RequestContent } from '@nightlylabs/nightly-connect-base' +import { + AptosRequest, + CustomAptosRequest, + SignMessagesAptosRequest, + SignTransactionsAptosRequest +} from './requestTypes' export type AppAptosInitialize = Omit @@ -202,5 +200,14 @@ export const parseRequest = (request: RequestContent, sessionId: string): AptosR } return customRequest } + case ContentType.ChangeNetwork: { + const changeNetworkRequest: CustomAptosRequest = { + type: ContentType.Custom, + content: request.content.newNetwork.chainId.toString(), + requestId: request.requestId, + sessionId: sessionId + } + return changeNetworkRequest + } } } diff --git a/sdk/packages/base/package.json b/sdk/packages/base/package.json index df027426..91528079 100644 --- a/sdk/packages/base/package.json +++ b/sdk/packages/base/package.json @@ -1,6 +1,6 @@ { "name": "@nightlylabs/nightly-connect-base", - "version": "0.0.28", + "version": "0.0.29", "type": "module", "exports": { ".": { diff --git a/sdk/packages/base/src/app.ts b/sdk/packages/base/src/app.ts index 99d74ddf..7bdfd586 100644 --- a/sdk/packages/base/src/app.ts +++ b/sdk/packages/base/src/app.ts @@ -1,20 +1,24 @@ +import { EventEmitter } from 'eventemitter3' +import WebSocket from 'isomorphic-ws' import { AppToServer } from '../../../bindings/AppToServer' import { InitializeRequest } from '../../../bindings/InitializeRequest' import { InitializeResponse } from '../../../bindings/InitializeResponse' +import { ResponsePayload } from '../../../bindings/ResponsePayload' import { ServerToApp } from '../../../bindings/ServerToApp' import { UserConnectedEvent } from '../../../bindings/UserConnectedEvent' -import WebSocket from 'isomorphic-ws' -import { - getLocalStorage, - getRandomId, - getSessionIdLocalStorageKey, - getWalletsMetadata -} from './utils' import { UserDisconnectedEvent } from '../../../bindings/UserDisconnectedEvent' -import { ContentType, MessageToSign, RequestInternal, TransactionToSign } from './content' -import { ResponsePayload } from '../../../bindings/ResponsePayload' import { WalletMetadata } from '../../../bindings/WalletMetadata' import { + ChangeNetworkTo, + ContentType, + MessageToSign, + RequestInternal, + TransactionToSign +} from './content' +import { triggerDeeplink } from './deeplinks' +import { AppBaseInitialize } from './initializeTypes' +import { + ChangeNetworkResponseContent, CustomResponseContent, ResponseContent, ResponseContentType, @@ -23,9 +27,12 @@ import { SignedMessage, SignedTransaction } from './responseContent' -import { triggerDeeplink } from './deeplinks' -import { EventEmitter } from 'eventemitter3' -import { AppBaseInitialize } from './initializeTypes' +import { + getLocalStorage, + getRandomId, + getSessionIdLocalStorageKey, + getWalletsMetadata +} from './utils' interface BaseEvents { userConnected: (e: UserConnectedEvent) => void @@ -202,6 +209,9 @@ export class BaseApp extends EventEmitter { case 'SignMessages': { return payload as SignMessagesResponseContent } + case 'ChangeNetwork': { + return payload as ChangeNetworkResponseContent + } case 'Custom': { return payload as CustomResponseContent } @@ -222,6 +232,14 @@ export class BaseApp extends EventEmitter { })) as SignMessagesResponseContent return response.messages } + + changeNetwork = async (newNetwork: ChangeNetworkTo) => { + const response = (await this.sendRequest({ + type: ContentType.ChangeNetwork, + newNetwork: newNetwork + })) as ChangeNetworkResponseContent + return response + } customRequest = async (content: string): Promise => { const response = (await this.sendRequest({ type: ContentType.Custom, diff --git a/sdk/packages/base/src/client.ts b/sdk/packages/base/src/client.ts index 3338b848..764918e8 100644 --- a/sdk/packages/base/src/client.ts +++ b/sdk/packages/base/src/client.ts @@ -1,27 +1,33 @@ // import LocalStorage from 'isomorphic-localstorage' -import { ClientToServer } from '../../../bindings/ClientToServer' -import { ServerToClient } from '../../../bindings/ServerToClient' +import { EventEmitter } from 'eventemitter3' import WebSocket from 'isomorphic-ws' -import { getRandomId } from './utils' -import { GetInfoRequest } from '../../../bindings/GetInfoRequest' +import { AppDisconnectedEvent } from '../../../bindings/AppDisconnectedEvent' +import { ClientInitializeRequest } from '../../../bindings/ClientInitializeRequest' +import { ClientToServer } from '../../../bindings/ClientToServer' import { ConnectRequest } from '../../../bindings/ConnectRequest' +import { DropSessionsRequest } from '../../../bindings/DropSessionsRequest' +import { DropSessionsResponse } from '../../../bindings/DropSessionsResponse' +import { GetInfoRequest } from '../../../bindings/GetInfoRequest' import { GetInfoResponse } from '../../../bindings/GetInfoResponse' import { GetPendingRequestsResponse } from '../../../bindings/GetPendingRequestsResponse' -import { AppDisconnectedEvent } from '../../../bindings/AppDisconnectedEvent' -import { EventEmitter } from 'eventemitter3' -import { MessageToSign, RequestContent, RequestInternal, TransactionToSign } from './content' +import { GetSessionsRequest } from '../../../bindings/GetSessionsRequest' +import { GetSessionsResponse } from '../../../bindings/GetSessionsResponse' +import { ServerToClient } from '../../../bindings/ServerToClient' +import { + ChangeNetworkTo, + MessageToSign, + RequestContent, + RequestInternal, + TransactionToSign +} from './content' +import { ClientBaseInitialize } from './initializeTypes' import { ResponseContent, ResponseContentType, SignedMessage, SignedTransaction } from './responseContent' -import { ClientInitializeRequest } from '../../../bindings/ClientInitializeRequest' -import { GetSessionsRequest } from '../../../bindings/GetSessionsRequest' -import { GetSessionsResponse } from '../../../bindings/GetSessionsResponse' -import { DropSessionsRequest } from '../../../bindings/DropSessionsRequest' -import { DropSessionsResponse } from '../../../bindings/DropSessionsResponse' -import { ClientBaseInitialize } from './initializeTypes' +import { getRandomId } from './utils' export interface SignTransactionsEvent { responseId: string @@ -33,6 +39,11 @@ export interface SignMessagesEvent { sessionId: string messages: MessageToSign[] } +export interface ChangeNetworkEvent { + responseId: string + sessionId: string + newNetwork: ChangeNetworkTo +} export interface CustomEvent { responseId: string sessionId: string @@ -40,6 +51,7 @@ export interface CustomEvent { content?: any } interface BaseEvents { + changeNetwork: (e: ChangeNetworkEvent) => void signTransactions: (e: SignTransactionsEvent) => void signMessages: (e: SignMessagesEvent) => void customEvent: (e: CustomEvent) => void @@ -104,6 +116,14 @@ export class BaseClient extends EventEmitter { }) break } + case 'ChangeNetwork': { + baseClient.emit('changeNetwork', { + responseId: response.requestId, + sessionId: response.sessionId, + newNetwork: payload.newNetwork + }) + break + } case 'Custom': { baseClient.emit('customEvent', { responseId: response.requestId, @@ -224,6 +244,16 @@ export class BaseClient extends EventEmitter { type: 'NewPayloadEventReply' }) } + resolveChangeNetwork = async ({ requestId, sessionId, newNetwork }: ResolveChangeNetwork) => { + await this.resolveRequest({ + requestId, + content: { + type: ResponseContentType.ChangedNetwork, + newNetwork: newNetwork + }, + sessionId + }) + } resolveSignTransactions = async ({ requestId, sessionId, @@ -274,6 +304,12 @@ export interface ResolveSignTransactions { sessionId: string signedTransactions: SignedTransaction[] } +export interface ResolveChangeNetwork { + requestId: string + newNetwork: ChangeNetworkTo + sessionId: string +} + export interface ResolveSignMessages { requestId: string sessionId: string diff --git a/sdk/packages/base/src/content.ts b/sdk/packages/base/src/content.ts index b1cafa82..ceef9a0d 100644 --- a/sdk/packages/base/src/content.ts +++ b/sdk/packages/base/src/content.ts @@ -1,6 +1,7 @@ export enum ContentType { SignMessages = 'SignMessages', SignTransactions = 'SignTransactions', + ChangeNetwork = 'ChangeNetwork', Custom = 'Custom' } @@ -16,6 +17,15 @@ export interface TransactionToSign { transaction: string metadata?: string } +export interface ChangeNetworkTo { + name: string + chainId: number + url?: string +} +export interface ChangeNetworkContent { + type: ContentType.ChangeNetwork + newNetwork: ChangeNetworkTo +} export interface SignTransactionsContent { type: ContentType.SignTransactions transactions: TransactionToSign[] @@ -24,7 +34,11 @@ export interface CustomContent { type: ContentType.Custom content?: string } -export type RequestInternal = SignMessagesContent | SignTransactionsContent | CustomContent +export type RequestInternal = + | SignMessagesContent + | SignTransactionsContent + | ChangeNetworkContent + | CustomContent export interface RequestContent { requestId: string content: RequestInternal diff --git a/sdk/packages/base/src/responseContent.ts b/sdk/packages/base/src/responseContent.ts index cc883bd2..d45c8e9f 100644 --- a/sdk/packages/base/src/responseContent.ts +++ b/sdk/packages/base/src/responseContent.ts @@ -1,6 +1,9 @@ +import { ChangeNetworkTo } from './content' + export enum ResponseContentType { SignMessages = 'SignMessagesResponse', SignTransactions = 'SignTransactionsResponse', + ChangedNetwork = 'ChangedNetwork', Custom = 'CustomResponse', Reject = 'RejectResponse' } @@ -21,6 +24,10 @@ export interface SignTransactionsResponseContent { type: ResponseContentType.SignTransactions transactions: SignedTransaction[] } +export interface ChangeNetworkResponseContent { + type: ResponseContentType.ChangedNetwork + newNetwork: ChangeNetworkTo +} export interface RejectResponseContent { type: ResponseContentType.Reject reason?: string @@ -32,5 +39,6 @@ export interface CustomResponseContent { export type ResponseContent = | SignMessagesResponseContent | SignTransactionsResponseContent + | ChangeNetworkResponseContent | RejectResponseContent | CustomResponseContent diff --git a/sdk/packages/selector-aptos/package.json b/sdk/packages/selector-aptos/package.json index d4e14737..77e9c496 100644 --- a/sdk/packages/selector-aptos/package.json +++ b/sdk/packages/selector-aptos/package.json @@ -26,7 +26,7 @@ "dependencies": { "@aptos-labs/ts-sdk": "^1.9.1", "@aptos-labs/wallet-standard": "^0.0.11", - "@nightlylabs/nightly-connect-aptos": "0.0.2", + "@nightlylabs/nightly-connect-aptos": "0.0.3", "@nightlylabs/wallet-selector-base": "0.4.1", "@wallet-standard/core": "^1.0.3", "eventemitter3": "^5.0.1" diff --git a/sdk/packages/selector-aptos/src/adapter.ts b/sdk/packages/selector-aptos/src/adapter.ts index 678b1964..c5910d39 100644 --- a/sdk/packages/selector-aptos/src/adapter.ts +++ b/sdk/packages/selector-aptos/src/adapter.ts @@ -328,9 +328,8 @@ export class NightlyConnectAptosAdapter extends EventEmitter if (!this) { throw new Error('Not connected') } - // TODO: add support for Nightly Connect if (this._connectionType === ConnectionType.Nightly) { - throw new Error('Not supported for Nightly Connect') + return await this._app!.changeNetwork(networkInfo) } if (this._connectionType === ConnectionType.WalletStandard) { return await this._innerStandardAdapter!.features['aptos:changeNetwork']!.changeNetwork( diff --git a/sdk/packages/selector-base/package.json b/sdk/packages/selector-base/package.json index 9a18f593..f9865287 100644 --- a/sdk/packages/selector-base/package.json +++ b/sdk/packages/selector-base/package.json @@ -24,7 +24,7 @@ "author": "", "license": "ISC", "dependencies": { - "@nightlylabs/nightly-connect-base": "0.0.28", + "@nightlylabs/nightly-connect-base": "0.0.29", "@nightlylabs/wallet-selector-modal": "0.2.1", "@wallet-standard/core": "^1.0.3", "isomorphic-localstorage": "^1.0.2" diff --git a/sdk/pnpm-lock.yaml b/sdk/pnpm-lock.yaml index 30ce0f6a..3944ed11 100644 --- a/sdk/pnpm-lock.yaml +++ b/sdk/pnpm-lock.yaml @@ -173,7 +173,7 @@ importers: specifiers: '@aptos-labs/ts-sdk': ^1.9.1 '@aptos-labs/wallet-standard': ^0.0.11 - '@nightlylabs/nightly-connect-base': ^0.0.28 + '@nightlylabs/nightly-connect-base': ^0.0.29 '@rollup/plugin-commonjs': ^25.0.0 '@rollup/plugin-node-resolve': ^15.2.1 '@rollup/plugin-terser': ^0.4.3 @@ -317,7 +317,7 @@ importers: tweetnacl: 1.0.3 typescript: 5.5.3 specifiers: - '@nightlylabs/nightly-connect-base': 0.0.28 + '@nightlylabs/nightly-connect-base': 0.0.29 '@polkadot/api': ^10.10.1 '@polkadot/extension-inject': ^0.46.5 '@polkadot/keyring': ^12.5.1 @@ -381,7 +381,7 @@ importers: specifiers: '@aptos-labs/ts-sdk': ^1.9.1 '@aptos-labs/wallet-standard': ^0.0.11 - '@nightlylabs/nightly-connect-aptos': 0.0.2 + '@nightlylabs/nightly-connect-aptos': 0.0.3 '@nightlylabs/wallet-selector-base': 0.4.1 '@rollup/plugin-commonjs': ^25.0.0 '@rollup/plugin-node-resolve': ^15.1.0 @@ -409,7 +409,7 @@ importers: tslib: 2.6.3 typescript: 5.5.3 specifiers: - '@nightlylabs/nightly-connect-base': 0.0.28 + '@nightlylabs/nightly-connect-base': 0.0.29 '@nightlylabs/wallet-selector-modal': 0.2.1 '@rollup/plugin-commonjs': ^25.0.0 '@rollup/plugin-node-resolve': ^15.1.0 @@ -546,7 +546,7 @@ importers: tweetnacl: 1.0.3 typescript: 5.5.3 specifiers: - '@nightlylabs/nightly-connect-base': 0.0.28 + '@nightlylabs/nightly-connect-base': 0.0.29 '@rollup/plugin-commonjs': ^25.0.0 '@rollup/plugin-node-resolve': ^15.1.0 '@rollup/plugin-terser': ^0.4.3 @@ -589,7 +589,7 @@ importers: specifiers: '@mysten/sui': ^1.2.1 '@mysten/wallet-standard': ^0.12.12 - '@nightlylabs/nightly-connect-base': ^0.0.28 + '@nightlylabs/nightly-connect-base': ^0.0.29 '@noble/hashes': ^1.3.0 '@rollup/plugin-commonjs': ^25.0.0 '@rollup/plugin-node-resolve': ^15.2.1 From fb0d43048a80fb7da22ff8a89faee43cc989fcbf Mon Sep 17 00:00:00 2001 From: LukassF Date: Tue, 17 Sep 2024 17:47:44 +0200 Subject: [PATCH 2/3] fix --- sdk/apps/modal-example/package.json | 2 +- sdk/apps/modal-example/src/routes/aptos.tsx | 39 +++++++++++++++++ sdk/packages/aptos/src/app.ts | 5 +-- sdk/packages/aptos/src/client.ts | 17 +++++++- sdk/packages/aptos/src/e2e.test.ts | 33 +++++++++------ sdk/packages/aptos/src/http-client.test.ts | 39 +++++++++++++---- sdk/packages/aptos/src/http-client.ts | 17 ++++++++ sdk/packages/aptos/src/requestTypes.ts | 9 +++- sdk/packages/aptos/src/utils.ts | 2 +- sdk/packages/base/package.json | 2 + sdk/packages/base/src/app.ts | 11 ++--- sdk/packages/base/src/client.test.ts | 25 ++++++++++- sdk/packages/base/src/client.ts | 13 ++---- sdk/packages/base/src/content.ts | 10 ++--- sdk/packages/base/src/http-client.test.ts | 30 ++++++++++++-- sdk/packages/base/src/http-client.ts | 46 ++++++++++++++++----- sdk/packages/base/src/responseContent.ts | 4 +- sdk/packages/selector-aptos/package.json | 2 +- sdk/pnpm-lock.yaml | 29 +++++++++---- 19 files changed, 259 insertions(+), 76 deletions(-) diff --git a/sdk/apps/modal-example/package.json b/sdk/apps/modal-example/package.json index f4b1e875..2f7293bf 100644 --- a/sdk/apps/modal-example/package.json +++ b/sdk/apps/modal-example/package.json @@ -22,7 +22,7 @@ "@nightlylabs/nightly-connect-polkadot": "0.0.16", "@nightlylabs/nightly-connect-solana": "0.0.29", "@nightlylabs/nightly-connect-sui": "0.1.0", - "@nightlylabs/wallet-selector-aptos": "0.1.7", + "@nightlylabs/wallet-selector-aptos": "0.1.8", "@nightlylabs/wallet-selector-base": "^0.4.1", "@nightlylabs/wallet-selector-polkadot": "0.2.7", "@nightlylabs/wallet-selector-solana": "0.3.6", diff --git a/sdk/apps/modal-example/src/routes/aptos.tsx b/sdk/apps/modal-example/src/routes/aptos.tsx index dcb618cc..31f66719 100644 --- a/sdk/apps/modal-example/src/routes/aptos.tsx +++ b/sdk/apps/modal-example/src/routes/aptos.tsx @@ -27,6 +27,8 @@ export default function AptosPage() { const [adapter, setAdapter] = createSignal() const [eager, setEager] = createSignal(false) const [accountInfo, setAccountInfo] = createSignal() + const [currentNetwork, setCurrentNetwork] = createSignal() + onMount(async () => { NightlyConnectAptosAdapter.build( { @@ -203,6 +205,43 @@ export default function AptosPage() { }}> Sign message +