From 6ea84239701125981be22010343b337932ad5fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?NB=F0=9F=98=88?= Date: Thu, 30 Nov 2023 15:22:06 +0100 Subject: [PATCH 1/4] aptos init support --- sdk/apps/aptos/.gitignore | 1 + sdk/apps/aptos/package.json | 55 ++ sdk/apps/aptos/rollup.config.js | 70 ++ sdk/apps/aptos/src/app.ts | 146 +++++ sdk/apps/aptos/src/client.ts | 186 ++++++ sdk/apps/aptos/src/e2e.test.ts | 150 +++++ sdk/apps/aptos/src/http-client.ts | 89 +++ sdk/apps/aptos/src/http-e2e.test.ts | 110 ++++ sdk/apps/aptos/src/index.ts | 10 + sdk/apps/aptos/src/requestTypes.ts | 28 + sdk/apps/aptos/src/testUtils.ts | 23 + sdk/apps/aptos/src/utils.ts | 107 +++ sdk/apps/aptos/tsconfig.json | 30 + sdk/apps/aptos/vitest.config.ts | 9 + sdk/apps/base/src/app.ts | 2 + sdk/build-only-packages.sh | 2 + sdk/packages/selector-aptos/package.json | 47 ++ sdk/packages/selector-aptos/rollup.config.js | 42 ++ sdk/packages/selector-aptos/src/adapter.ts | 645 +++++++++++++++++++ sdk/packages/selector-aptos/src/detection.ts | 13 + sdk/packages/selector-aptos/src/icon.ts | 2 + sdk/packages/selector-aptos/src/index.ts | 2 + sdk/packages/selector-aptos/tsconfig.json | 17 + sdk/pnpm-lock.yaml | 481 +++++++++++--- 24 files changed, 2181 insertions(+), 86 deletions(-) create mode 100644 sdk/apps/aptos/.gitignore create mode 100644 sdk/apps/aptos/package.json create mode 100644 sdk/apps/aptos/rollup.config.js create mode 100644 sdk/apps/aptos/src/app.ts create mode 100644 sdk/apps/aptos/src/client.ts create mode 100644 sdk/apps/aptos/src/e2e.test.ts create mode 100644 sdk/apps/aptos/src/http-client.ts create mode 100644 sdk/apps/aptos/src/http-e2e.test.ts create mode 100644 sdk/apps/aptos/src/index.ts create mode 100644 sdk/apps/aptos/src/requestTypes.ts create mode 100644 sdk/apps/aptos/src/testUtils.ts create mode 100644 sdk/apps/aptos/src/utils.ts create mode 100644 sdk/apps/aptos/tsconfig.json create mode 100644 sdk/apps/aptos/vitest.config.ts create mode 100644 sdk/packages/selector-aptos/package.json create mode 100644 sdk/packages/selector-aptos/rollup.config.js create mode 100644 sdk/packages/selector-aptos/src/adapter.ts create mode 100644 sdk/packages/selector-aptos/src/detection.ts create mode 100644 sdk/packages/selector-aptos/src/icon.ts create mode 100644 sdk/packages/selector-aptos/src/index.ts create mode 100644 sdk/packages/selector-aptos/tsconfig.json diff --git a/sdk/apps/aptos/.gitignore b/sdk/apps/aptos/.gitignore new file mode 100644 index 00000000..37b1898b --- /dev/null +++ b/sdk/apps/aptos/.gitignore @@ -0,0 +1 @@ +/.nightly-connect-session \ No newline at end of file diff --git a/sdk/apps/aptos/package.json b/sdk/apps/aptos/package.json new file mode 100644 index 00000000..61c1d68b --- /dev/null +++ b/sdk/apps/aptos/package.json @@ -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" + } +} \ No newline at end of file diff --git a/sdk/apps/aptos/rollup.config.js b/sdk/apps/aptos/rollup.config.js new file mode 100644 index 00000000..99ae5d43 --- /dev/null +++ b/sdk/apps/aptos/rollup.config.js @@ -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()] + } +] diff --git a/sdk/apps/aptos/src/app.ts b/sdk/apps/aptos/src/app.ts new file mode 100644 index 00000000..44d57be4 --- /dev/null +++ b/sdk/apps/aptos/src/app.ts @@ -0,0 +1,146 @@ +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 + networkInfo: NetworkInfo + metadata?: string +} + +interface SuiAppEvents { + userConnected: (e: AptosUserConnectedEvent) => void + userDisconnected: (e: UserDisconnectedEvent) => void + serverDisconnected: () => void +} +export class AppAptos extends EventEmitter { + // Nightly Connect + sessionId: string + base: BaseApp + initData: AppAptosInitialize + url = 'https://nightly.app' + providerName?: string + provider: any + 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 accountInfo() { + const accountInfo: AccountInfo = JSON.parse(this.base.connectedPublicKeys[0]) + return accountInfo + } + public get networkInfo() { + 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 => { + return getWalletsMetadata(url, 'aptos') + } + public static build = async (initData: AppAptosInitialize): Promise => { + 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 { + 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) + } +} diff --git a/sdk/apps/aptos/src/client.ts b/sdk/apps/aptos/src/client.ts new file mode 100644 index 00000000..c32b8eb3 --- /dev/null +++ b/sdk/apps/aptos/src/client.ts @@ -0,0 +1,186 @@ +import { + AccountInfo, + NetworkInfo, + SignMessagePayload, + SignMessageResponse, + Types +} from '@aptos-labs/wallet-adapter-core' +import { BaseClient, ClientBaseInitialize, Connect } from '@nightlylabs/nightly-connect-base' +import { EventEmitter } from 'eventemitter3' +import { AppDisconnectedEvent } from '../../../bindings/AppDisconnectedEvent' +import { GetInfoResponse } from '../../../bindings/GetInfoResponse' +import { AptosRequest } from './requestTypes' +import { APTOS_NETWORK, parseRequest, serializeSignMessageResponse } from './utils' + +export interface SignAptosTransactionEvent { + requestId: string + transactions: Array<{ + transaction: Types.TransactionPayload + options: unknown & { submit: boolean } + }> + sessionId: string +} +export interface SignAptosMessageEvent { + requestId: string + sessionId: string + messages: Array<{ + message: SignMessagePayload + metadata?: string + }> +} +export interface ClientAptosEvents { + signTransactions: (e: SignAptosTransactionEvent) => void + signMessages: (e: SignAptosMessageEvent) => void + appDisconnected: (e: AppDisconnectedEvent) => void +} +export class ClientAptos extends EventEmitter { + baseClient: BaseClient + sessionId: string | undefined = undefined + private constructor(baseClient: BaseClient) { + super() + baseClient.on('signTransactions', (e) => { + const event: SignAptosTransactionEvent = { + sessionId: e.sessionId, + requestId: e.responseId, + transactions: e.transactions.map((tx) => { + const transaction = JSON.parse(tx.transaction) + const metadata = tx.metadata ? JSON.parse(tx.metadata) : { submit: true } + return { options: metadata, transaction } + }) + } + this.emit('signTransactions', event) + }) + baseClient.on('signMessages', (e) => { + const event: SignAptosMessageEvent = { + sessionId: e.sessionId, + requestId: e.responseId, + messages: e.messages.map((tx) => { + const message = JSON.parse(tx.message) + return { metadata: tx.metadata, message: message } + }) + } + this.emit('signMessages', event) + }) + baseClient.on('appDisconnected', (e) => { + this.emit('appDisconnected', e) + }) + this.baseClient = baseClient + } + public static build = async ( + sessionId: string, + initData: ClientBaseInitialize + ): Promise<{ + client: ClientAptos + data: GetInfoResponse + }> => { + // Add prefix to client id + const baseClient = await BaseClient.build({ + ...initData, + clientId: APTOS_NETWORK + '-' + initData.clientId + }) + const data = await baseClient.getInfo(sessionId) + const client = new ClientAptos(baseClient) + return { client, data } + } + public static create = async (initData: ClientBaseInitialize) => { + // Add prefix to client id + const baseClient = await BaseClient.build({ + ...initData, + clientId: APTOS_NETWORK + '-' + initData.clientId + }) + const client = new ClientAptos(baseClient) + return client + } + public getInfo = async (sessionId: string): Promise => { + const response = await this.baseClient.getInfo(sessionId) + return response + } + public connect = async (connect: AptosConnect) => { + await this.baseClient.connect({ + ...connect, + publicKeys: connect.publicKeys.map((pk) => JSON.stringify(pk)), + metadata: JSON.stringify({ networkInfo: connect.networkInfo }) + }) + this.sessionId = connect.sessionId + } + public getPendingRequests = async (sessionId?: string): Promise => { + const sessionIdToUse = sessionId || this.sessionId + //Assert session id is defined + if (sessionIdToUse === undefined) { + throw new Error('Session id is undefined') + } + const requests = await this.baseClient.getPendingRequests(sessionIdToUse) + return requests.map((request) => parseRequest(request, sessionIdToUse)) + } + + public resolveSignTransaction = async ({ + requestId, + transactionHashes, + sessionId + }: ResolveSignAptosTransactions) => { + const serializedTxs = transactionHashes.map((tx) => { + return { network: APTOS_NETWORK, transaction: JSON.stringify({ hash: tx.hash }) } + }) + const sessionIdToUse = sessionId || this.sessionId + //Assert session id is defined + if (sessionIdToUse === undefined) { + throw new Error('Session id is undefined') + } + await this.baseClient.resolveSignTransactions({ + requestId: requestId, + signedTransactions: serializedTxs, + sessionId: sessionIdToUse + }) + } + public resolveSignMessage = async ({ + requestId, + response, + sessionId + }: ResolveSignAptosMessage) => { + const sessionIdToUse = sessionId || this.sessionId + //Assert session id is defined + if (sessionIdToUse === undefined) { + throw new Error('Session id is undefined') + } + await this.baseClient.resolveSignMessages({ + requestId: requestId, + sessionId: sessionIdToUse, + signedMessages: [{ message: serializeSignMessageResponse(response) }] + }) + } + public rejectRequest = async ({ requestId, reason, sessionId }: RejectRequest) => { + const sessionIdToUse = sessionId || this.sessionId + //Assert session id is defined + if (sessionIdToUse === undefined) { + throw new Error('Session id is undefined') + } + await this.baseClient.reject({ requestId: requestId, reason, sessionId: sessionIdToUse }) + } + public getSessions = async (): Promise => { + return await this.baseClient.getSessions() + } + public dropSessions = async (sessionsToDrop: string[]): Promise => { + return await this.baseClient.dropSessions(sessionsToDrop) + } +} + +export interface RejectRequest { + requestId: string + reason?: string + sessionId?: string +} +export interface ResolveSignAptosTransactions { + requestId: string + transactionHashes: Array<{ hash: Types.HexEncodedBytes }> + sessionId?: string +} +export interface ResolveSignAptosMessage { + requestId: string + response: SignMessageResponse + sessionId?: string +} + +export type AptosConnect = Omit & { + publicKeys: AccountInfo[] + networkInfo: NetworkInfo +} diff --git a/sdk/apps/aptos/src/e2e.test.ts b/sdk/apps/aptos/src/e2e.test.ts new file mode 100644 index 00000000..b855675a --- /dev/null +++ b/sdk/apps/aptos/src/e2e.test.ts @@ -0,0 +1,150 @@ +import { + AccountInfo, + SignMessagePayload, + SignMessageResponse +} from '@aptos-labs/wallet-adapter-core' +import { + AptosAccount, + CoinClient, + FaucetClient, + Network, + TransactionBuilderEd25519, + TxnBuilderTypes, + Types +} from 'aptos' +import { assert, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest' +import { TEST_RELAY_ENDPOINT, smartDelay } from '../../../commonTestUtils' +import { AppAptos } from './app' +import { AptosConnect, ClientAptos } from './client' +import { FAUCET_URL, NODE_URL, TEST_APP_INITIALIZE } from './testUtils' +import { APTOS_NETWORK } from './utils' + +const aptosClient = new FaucetClient(NODE_URL, FAUCET_URL) // <:!:section_1 +const alice = new AptosAccount() +const aliceAccountInfo: AccountInfo = { + address: alice.address().toString(), + publicKey: alice.pubKey().toString() +} +const olive = new AptosAccount() +const oliveAccountInfo: AccountInfo = { + address: olive.address().toString(), + publicKey: olive.pubKey().toString() +} +const coinClient = new CoinClient(aptosClient) +describe('Base Client tests', () => { + let app: AppAptos + let client: ClientAptos + beforeAll(async () => { + await aptosClient.fundAccount(alice.address(), 10 ** 9) + app = await AppAptos.build(TEST_APP_INITIALIZE) + expect(app).toBeDefined() + assert(app.sessionId !== '') + client = await ClientAptos.create({ url: TEST_RELAY_ENDPOINT }) + }) + beforeEach(async () => { + await smartDelay() + }) + test('#getInfo()', async () => { + const info = await client.getInfo(app.sessionId) + expect(info).toBeDefined() + assert(info.appMetadata.additionalInfo === TEST_APP_INITIALIZE.appMetadata.additionalInfo) + assert(info.appMetadata.description === TEST_APP_INITIALIZE.appMetadata.description) + assert(info.appMetadata.icon === TEST_APP_INITIALIZE.appMetadata.icon) + assert(info.appMetadata.name === TEST_APP_INITIALIZE.appMetadata.name) + assert(info.network === APTOS_NETWORK) + // assert(info.version === testAppBaseInitialize.version) + }) + test('#connect()', async () => { + const fn = vi.fn() + const fnNetworkInfo = vi.fn() + app.on('userConnected', (e) => { + fn(e.accounts[0]) + fnNetworkInfo(e.networkInfo) + }) + const msg: AptosConnect = { + publicKeys: [aliceAccountInfo], + sessionId: app.sessionId, + networkInfo: { name: Network.MAINNET } + } + await client.connect(msg) + await smartDelay() + expect(fn).toHaveBeenCalledWith(aliceAccountInfo) + expect(fnNetworkInfo).toHaveBeenCalledWith({ name: Network.MAINNET }) + }) + test('#on("signTransactions")', async () => { + client.on('signTransactions', async (e) => { + const tx = await aptosClient.generateTransaction( + alice.address(), + e.transactions[0].transaction as Types.EntryFunctionPayload + ) + const txnBuilder = new TransactionBuilderEd25519( + (signingMessage: TxnBuilderTypes.SigningMessage) => { + const sigHexStr = alice.signBuffer(signingMessage) + return new TxnBuilderTypes.Ed25519Signature(sigHexStr.toUint8Array()) + }, + alice.pubKey().toUint8Array() + ) + const signedTxn = txnBuilder.sign(tx) + const hash = await aptosClient.submitTransaction(signedTxn) + + await client.resolveSignTransaction({ + requestId: e.requestId, + transactionHashes: [{ hash: hash.hash }] + }) + }) + smartDelay() + const tx = { + type: 'entry_function_payload', + arguments: [olive.address().toString(), 1000], + function: '0x1::coin::transfer', + type_arguments: ['0x1::aptos_coin::AptosCoin'] + } + const signedtx = await app.signAndSubmitTransaction(tx) + assert(signedtx.hash.length === 66) + }) + test('#on("signMessages")', async () => { + const msgToSign: SignMessagePayload = { + message: 'I love Nightly', + nonce: '1234', + address: true + } + const signMsgResponse: SignMessageResponse = { + fullMessage: 'I love Nightly', + message: 'I love Nightly', + nonce: '1234', + prefix: 'APTOS', + signature: 'signature', + bitmap: undefined + } + client.on('signMessages', async (e) => { + await client.resolveSignMessage({ + requestId: e.requestId, + response: signMsgResponse + }) + }) + await smartDelay() + const signedMsg = await app.signMessage(msgToSign) + assert(JSON.stringify(signedMsg) === JSON.stringify(signMsgResponse)) + }) + // test('#getPendingRequests()', async () => { + // client.removeListener('signTransactions') + // const RECEIVER = Keypair.generate() + // const ix = SystemProgram.transfer({ + // fromPubkey: alice_keypair.publicKey, + // lamports: LAMPORTS_PER_SOL, + // toPubkey: RECEIVER.publicKey + // }) + // const tx = new Transaction().add(ix) + // tx.feePayer = alice_keypair.publicKey + // tx.recentBlockhash = 'E6wypnGQkndknX5Urd5yXV8yxAkbHwD5MJ1aaNKWZBd5' + // app.signTransaction(tx) + // app.signTransaction(tx) + // await smartDelay(500) + // const requests = await client.getPendingRequests() + // expect(requests.length).toBe(2) + // expect(requests[0].type).toBe(ContentType.SignTransactions) + // expect(requests[1].type).toBe(ContentType.SignTransactions) + // const payload1 = requests[0] as SignTransactionsSolanaRequest + // expect(payload1.transactions.length).toBe(1) + // }) +}) diff --git a/sdk/apps/aptos/src/http-client.ts b/sdk/apps/aptos/src/http-client.ts new file mode 100644 index 00000000..c3a5009b --- /dev/null +++ b/sdk/apps/aptos/src/http-client.ts @@ -0,0 +1,89 @@ +import { + AccountInfo, + NetworkInfo, + SignMessageResponse, + Types +} from '@aptos-labs/wallet-adapter-core' +import { HttpBaseClient, HttpBaseClientInitialize } from '@nightlylabs/nightly-connect-base' +import { HttpConnectSessionRequest } from '../../../bindings/HttpConnectSessionRequest' +import { HttpGetPendingRequestRequest } from '../../../bindings/HttpGetPendingRequestRequest' +import { HttpGetPendingRequestsRequest } from '../../../bindings/HttpGetPendingRequestsRequest' +import { HttpGetSessionInfoResponse } from '../../../bindings/HttpGetSessionInfoResponse' +import { APTOS_NETWORK, parseRequest, serializeSignMessageResponse } from './utils' + +export class HttpClientAptos { + baseClient: HttpBaseClient + clientId: string | undefined = undefined + public constructor({ clientId, timeout, url }: HttpBaseClientInitialize) { + this.clientId = clientId + this.baseClient = new HttpBaseClient({ clientId, timeout, url }) + } + public getInfo = async (sessionId: string): Promise => { + const response = await this.baseClient.getInfo(sessionId) + return response + } + public connect = async (connect: AptosConnect) => { + await this.baseClient.connect({ + ...connect, + publicKeys: connect.publicKeys.map((pk) => JSON.stringify(pk)), + metadata: JSON.stringify({ networkInfo: connect.networkInfo }) + }) + } + public getPendingRequests = async (request: Omit) => { + const requests = await this.baseClient.getPendingRequests(request) + return requests.map((rq) => parseRequest(rq, request.sessionId)) + } + public getPendingRequest = async (request: Omit) => { + const rq = await this.baseClient.getPendingRequest(request) + return parseRequest(rq, request.sessionId) + } + public resolveSignTransaction = async ({ + requestId, + transactionHashes, + sessionId + }: ResolveSignAptosTransactions) => { + const serializedTxs = transactionHashes.map((tx) => { + return { network: APTOS_NETWORK, transaction: JSON.stringify({ hash: tx.hash }) } + }) + + await this.baseClient.resolveSignTransactions({ + requestId: requestId, + signedTransactions: serializedTxs, + sessionId: sessionId + }) + } + public resolveSignMessage = async ({ + requestId, + response, + sessionId + }: ResolveSignAptosMessage) => { + await this.baseClient.resolveSignMessages({ + requestId: requestId, + sessionId: sessionId, + signedMessages: [{ message: serializeSignMessageResponse(response) }] + }) + } + public rejectRequest = async ({ requestId, reason, sessionId }: RejectRequest) => { + await this.baseClient.reject({ requestId: requestId, reason, sessionId: sessionId }) + } +} +export type AptosConnect = Omit & { + publicKeys: AccountInfo[] + networkInfo: NetworkInfo +} + +export interface RejectRequest { + requestId: string + sessionId: string + reason?: string +} +export interface ResolveSignAptosTransactions { + requestId: string + transactionHashes: Array<{ hash: Types.HexEncodedBytes }> + sessionId: string +} +export interface ResolveSignAptosMessage { + requestId: string + response: SignMessageResponse + sessionId: string +} diff --git a/sdk/apps/aptos/src/http-e2e.test.ts b/sdk/apps/aptos/src/http-e2e.test.ts new file mode 100644 index 00000000..e4a22ac0 --- /dev/null +++ b/sdk/apps/aptos/src/http-e2e.test.ts @@ -0,0 +1,110 @@ +import { AccountInfo } from '@aptos-labs/wallet-adapter-core' +import { ContentType, getRandomId } from '@nightlylabs/nightly-connect-base' +import { + AptosAccount, + FaucetClient, + Network, + TransactionBuilderEd25519, + TxnBuilderTypes, + Types +} from 'aptos' +import { assert, beforeAll, beforeEach, describe, expect, test, vi } from 'vitest' +import { TEST_RELAY_ENDPOINT, smartDelay } from '../../../commonTestUtils' +import { AppAptos } from './app' +import { AptosConnect } from './client' +import { HttpClientAptos } from './http-client' +import { FAUCET_URL, NODE_URL, TEST_APP_INITIALIZE } from './testUtils' +import { APTOS_NETWORK } from './utils' + +const aptosClient = new FaucetClient(NODE_URL, FAUCET_URL) +const alice = new AptosAccount() +const olive = new AptosAccount() +const aliceAccountInfo: AccountInfo = { + address: alice.address().toString(), + publicKey: alice.pubKey().toString() +} +describe('Base Client tests', () => { + let app: AppAptos + let client: HttpClientAptos + const clientId = getRandomId() + beforeAll(async () => { + await aptosClient.fundAccount(alice.address(), 10 ** 9) + app = await AppAptos.build(TEST_APP_INITIALIZE) + expect(app).toBeDefined() + assert(app.sessionId !== '') + client = new HttpClientAptos({ url: TEST_RELAY_ENDPOINT, clientId }) + }) + beforeEach(async () => { + await smartDelay() + }) + test('#getInfo()', async () => { + const info = await client.getInfo(app.sessionId) + expect(info).toBeDefined() + assert(info.appMetadata.additionalInfo === TEST_APP_INITIALIZE.appMetadata.additionalInfo) + assert(info.appMetadata.description === TEST_APP_INITIALIZE.appMetadata.description) + assert(info.appMetadata.icon === TEST_APP_INITIALIZE.appMetadata.icon) + assert(info.appMetadata.name === TEST_APP_INITIALIZE.appMetadata.name) + assert(info.network === APTOS_NETWORK) + // assert(info.version === testAppBaseInitialize.version) + }) + test('#connect()', async () => { + const fn = vi.fn() + const fnNetworkInfo = vi.fn() + app.on('userConnected', (e) => { + fn(e.accounts[0]) + fnNetworkInfo(e.networkInfo) + }) + const msg: AptosConnect = { + publicKeys: [aliceAccountInfo], + sessionId: app.sessionId, + networkInfo: { + name: Network.MAINNET + } + } + await client.connect(msg) + await smartDelay() + expect(fn).toHaveBeenCalledWith(aliceAccountInfo) + expect(fnNetworkInfo).toHaveBeenCalledWith({ + name: Network.MAINNET + }) + }) + test('#resolveSignTransaction()', async () => { + const txnBuilder = new TransactionBuilderEd25519( + (signingMessage: TxnBuilderTypes.SigningMessage) => { + const sigHexStr = alice.signBuffer(signingMessage) + return new TxnBuilderTypes.Ed25519Signature(sigHexStr.toUint8Array()) + }, + alice.pubKey().toUint8Array() + ) + const txToSign = { + type: 'entry_function_payload', + arguments: [olive.address().toString(), 1000], + function: '0x1::coin::transfer', + type_arguments: ['0x1::aptos_coin::AptosCoin'] + } + const promiseSignTransaction = app.signAndSubmitTransaction(txToSign) + await smartDelay() + // Query for request + const pendingRequest = (await client.getPendingRequests({ sessionId: app.sessionId }))[0] + if (pendingRequest.type !== ContentType.SignTransactions) { + throw new Error('Wrong content type') + } + const tx = await aptosClient.generateTransaction( + alice.address(), + pendingRequest.transactions[0].transaction as Types.EntryFunctionPayload + ) + const signedTxn = txnBuilder.sign(tx) + const hash = await aptosClient.submitTransaction(signedTxn) + + await client.resolveSignTransaction({ + requestId: pendingRequest.requestId, + sessionId: app.sessionId, + transactionHashes: [{ hash: hash.hash }] + }) + + await smartDelay() + const signed = await promiseSignTransaction + assert(signed.hash.length === 66) + assert(signed.hash === hash.hash) + }) +}) diff --git a/sdk/apps/aptos/src/index.ts b/sdk/apps/aptos/src/index.ts new file mode 100644 index 00000000..aec1ae76 --- /dev/null +++ b/sdk/apps/aptos/src/index.ts @@ -0,0 +1,10 @@ +export * from './app' +export * from './client' +export { + HttpClientAptos, + type RejectRequest as RejectHttpRequest, + type ResolveSignAptosMessage as ResolveSignHttpAptosMessage, + type ResolveSignAptosTransactions as ResolveSignHttpAptosTransactions +} from './http-client' +export * from './utils' +export * from './requestTypes' diff --git a/sdk/apps/aptos/src/requestTypes.ts b/sdk/apps/aptos/src/requestTypes.ts new file mode 100644 index 00000000..d7c58cd4 --- /dev/null +++ b/sdk/apps/aptos/src/requestTypes.ts @@ -0,0 +1,28 @@ +import type { SignMessagePayload, Types } from '@aptos-labs/wallet-adapter-core' +import type { ContentType } from '@nightlylabs/nightly-connect-base' + +export interface SignTransactionsAptosRequest { + type: ContentType.SignTransactions + requestId: string + transactions: Array<{ + transaction: Types.TransactionPayload + options: unknown & { submit: true } + }> + sessionId: string +} +export interface SignMessagesAptosRequest { + type: ContentType.SignMessages + requestId: string + messages: Array + sessionId: string +} +export interface CustomAptosRequest { + type: ContentType.Custom + requestId: string + content?: string + sessionId: string +} +export type AptosRequest = + | SignTransactionsAptosRequest + | SignMessagesAptosRequest + | CustomAptosRequest diff --git a/sdk/apps/aptos/src/testUtils.ts b/sdk/apps/aptos/src/testUtils.ts new file mode 100644 index 00000000..f8d4fa5e --- /dev/null +++ b/sdk/apps/aptos/src/testUtils.ts @@ -0,0 +1,23 @@ +import { AppAptosInitialize } from './utils' +import { TEST_RELAY_ENDPOINT } from '../../../commonTestUtils' + +export const TEST_APP_INITIALIZE: AppAptosInitialize = { + appMetadata: { + additionalInfo: 'test-aptos-additional-info', + description: 'test-aptos-app-description', + icon: 'test-aptos-app-icon', + name: 'test-aptos-app-name' + }, + persistent: false, + persistentSessionId: undefined, + timeout: undefined, + url: TEST_RELAY_ENDPOINT +} +export function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +export const NODE_URL = process.env.APTOS_NODE_URL || 'https://fullnode.devnet.aptoslabs.com' +export const FAUCET_URL = process.env.APTOS_FAUCET_URL || 'https://faucet.devnet.aptoslabs.com' + +export const aptosCoinStore = '0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>' diff --git a/sdk/apps/aptos/src/utils.ts b/sdk/apps/aptos/src/utils.ts new file mode 100644 index 00000000..d090b493 --- /dev/null +++ b/sdk/apps/aptos/src/utils.ts @@ -0,0 +1,107 @@ +import { AppBaseInitialize, ContentType, RequestContent } from '@nightlylabs/nightly-connect-base' +import { + CustomAptosRequest, + SignMessagesAptosRequest, + SignTransactionsAptosRequest, + AptosRequest +} from './requestTypes' +import { SignMessageResponse } from '@aptos-labs/wallet-adapter-core' + +export type AppAptosInitialize = Omit + +export const APTOS_NETWORK = 'Aptos' + +export const parseRequest = (request: RequestContent, sessionId: string): AptosRequest => { + switch (request.content.type) { + case ContentType.SignTransactions: { + const signTransactionsRequest: SignTransactionsAptosRequest = { + type: ContentType.SignTransactions, + requestId: request.requestId, + sessionId: sessionId, + transactions: request.content.transactions.map((tx) => { + return { + options: tx.metadata ? JSON.parse(tx.metadata) : { submit: true }, + transaction: JSON.parse(tx.transaction) + } + }) + } + return signTransactionsRequest + } + case ContentType.SignMessages: { + const signMessagesRequest: SignMessagesAptosRequest = { + type: ContentType.SignMessages, + requestId: request.requestId, + sessionId: sessionId, + messages: request.content.messages.map((msg) => JSON.parse(msg.message)) + } + return signMessagesRequest + } + case ContentType.Custom: { + const customRequest: CustomAptosRequest = { + type: ContentType.Custom, + content: request.content.content, + requestId: request.requestId, + sessionId: sessionId + } + return customRequest + } + } +} + +export const serializeSignMessageResponse = (response: SignMessageResponse) => { + const data = { + ...response, + bitmap: response.bitmap ? Buffer.from(response.bitmap).toString('hex') : undefined + } + return JSON.stringify(data) +} +export const deserializeSignMessageResponse = (data: string): SignMessageResponse => { + const response = JSON.parse(data) + const bitmap = response.bitmap ? Buffer.from(response.bitmap, 'hex') : undefined + return { + ...response, + bitmap + } +} + +import { sha256 } from 'js-sha256' +import base58 from 'bs58' + +export class AptosPublicKey { + private readonly hexString: string + + static default() { + return new AptosPublicKey('0'.repeat(64)) + } + + address() { + const hash = sha256.create() + hash.update(Buffer.from(this.asPureHex(), 'hex')) + hash.update('\x00') + return '0x' + hash.hex() + } + + asUint8Array() { + return new Uint8Array(Buffer.from(this.asPureHex(), 'hex')) + } + static fromBase58(base58string: string) { + const bytes = Buffer.from(base58.decode(base58string)) + const hexString = bytes.toString('hex') + return new AptosPublicKey(hexString) + } + asString() { + return this.hexString + } + + asPureHex() { + return this.hexString.substr(2) + } + + constructor(hexString: string) { + if (hexString.startsWith('0x')) { + this.hexString = hexString + } else { + this.hexString = `0x${hexString}` + } + } +} diff --git a/sdk/apps/aptos/tsconfig.json b/sdk/apps/aptos/tsconfig.json new file mode 100644 index 00000000..75a9ae75 --- /dev/null +++ b/sdk/apps/aptos/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "lib": ["es2015", "DOM"], + "types": ["node"], + "target": "esnext", + "moduleDetection": "force", + "resolveJsonModule": true, + "allowJs": true, + "baseUrl": ".", + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "noImplicitAny": false, + "forceConsistentCasingInFileNames": true, + "module": "esnext", + "moduleResolution": "node", + "isolatedModules": true, + "noFallthroughCasesInSwitch": true, + "declaration": true, + "declarationDir": "types", + "emitDeclarationOnly": true, + "outDir": "dist", + "rootDir": "../.." + }, + "ts-node": { + "require": ["tsconfig-paths/register"] + }, + "include": ["../../bindings/*", "src/*"] +} diff --git a/sdk/apps/aptos/vitest.config.ts b/sdk/apps/aptos/vitest.config.ts new file mode 100644 index 00000000..b7b4aacd --- /dev/null +++ b/sdk/apps/aptos/vitest.config.ts @@ -0,0 +1,9 @@ +import tsconfigPath from 'vite-tsconfig-paths' +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + plugins: [tsconfigPath()], + test: { + // singleThread: true + } +}) diff --git a/sdk/apps/base/src/app.ts b/sdk/apps/base/src/app.ts index 99d74ddf..7e5b3f66 100644 --- a/sdk/apps/base/src/app.ts +++ b/sdk/apps/base/src/app.ts @@ -45,6 +45,7 @@ export class BaseApp extends EventEmitter { timeout: number deeplink: DeeplinkConnect | undefined connectedPublicKeys: string[] = [] + connectedMetadata: string | undefined = undefined hasBeenRestored = false clientMetadata: string | undefined initializeData: AppBaseInitialize @@ -98,6 +99,7 @@ export class BaseApp extends EventEmitter { } case 'UserConnectedEvent': { baseApp.connectedPublicKeys = response.publicKeys + baseApp.connectedMetadata = response.metadata baseApp.emit('userConnected', response) break } diff --git a/sdk/build-only-packages.sh b/sdk/build-only-packages.sh index abc50631..a0156192 100644 --- a/sdk/build-only-packages.sh +++ b/sdk/build-only-packages.sh @@ -9,6 +9,8 @@ cd ../sui pnpm build cd ../polkadot pnpm build +cd ../aptos +pnpm build # ui packages cd ../../packages/qr-codes pnpm build diff --git a/sdk/packages/selector-aptos/package.json b/sdk/packages/selector-aptos/package.json new file mode 100644 index 00000000..2ebbfbd0 --- /dev/null +++ b/sdk/packages/selector-aptos/package.json @@ -0,0 +1,47 @@ +{ + "name": "@nightlylabs/wallet-selector-aptos", + "version": "0.2.6", + "description": "", + "type": "module", + "exports": { + ".": { + "import": "./dist/index.mjs.js", + "require": "./dist/index.cjs.js", + "types": "./dist/index.d.ts" + } + }, + "main": "dist/index.cjs.js", + "module": "dist/index.mjs.js", + "types": "dist/index.d.ts", + "typings": "dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "rm -rf ./dist && rollup -c" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@nightlylabs/nightly-connect-aptos": "0.0.1", + "@nightlylabs/wallet-selector-base": "0.2.4", + "@wallet-standard/core": "^1.0.3", + "bs58": "^4.0.1", + "events": "^3.3.0", + "@aptos-labs/wallet-adapter-core": "^3.0.0", + "aptos": "^1.20.0", + "@nightlylabs/nightly-connect-base": "^0.0.27" + }, + "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/bs58": "^4.0.1", + "rollup": "^3.23.1", + "rollup-plugin-dts": "^5.3.0", + "tslib": "^2.5.3", + "typescript": "^5.1.3" + } +} \ No newline at end of file diff --git a/sdk/packages/selector-aptos/rollup.config.js b/sdk/packages/selector-aptos/rollup.config.js new file mode 100644 index 00000000..409325ff --- /dev/null +++ b/sdk/packages/selector-aptos/rollup.config.js @@ -0,0 +1,42 @@ +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 + }, + { + file: 'dist/index.mjs.js', + format: 'esm', + sourcemap: true + } + ], + plugins: [ + typescript(), + nodeResolve({ browser: true, preferBuiltins: false }), + commonjs(), + terser() + ], + external: [ + '@aptos-labs/wallet-adapter-core', + 'aptos', + '@nightlylabs/wallet-selector-base', + '@wallet-standard/core', + 'bs58', + 'events' + ] + }, + { + input: 'dist/types/index.d.ts', + output: [{ file: 'dist/index.d.ts', format: 'esm' }], + plugins: [dts()] + } +] diff --git a/sdk/packages/selector-aptos/src/adapter.ts b/sdk/packages/selector-aptos/src/adapter.ts new file mode 100644 index 00000000..bb813b83 --- /dev/null +++ b/sdk/packages/selector-aptos/src/adapter.ts @@ -0,0 +1,645 @@ +/* eslint-disable @typescript-eslint/no-empty-function */ +import { + AppInitData, + ConnectionType, + IWalletListItem, + MetadataWallet, + NightlyConnectSelectorModal, + XMLOptions, + clearRecentStandardWalletForNetwork, + clearSessionIdForNetwork, + getRecentStandardWalletForNetwork, + isMobileBrowser, + isStandardConnectedForNetwork, + persistRecentStandardWalletForNetwork, + sleep, + triggerConnect +} from '@nightlylabs/wallet-selector-base' +// import { suiWalletsFilter } from './detection' +import { + AccountInfo, + AdapterPlugin, + NetworkInfo, + SignMessagePayload, + SignMessageResponse, + Types, + WalletName +} from '@aptos-labs/wallet-adapter-core' +import { AppAptos } from '@nightlylabs/nightly-connect-aptos' +import { logoBase64 } from './icon' + +export const AptosWalletName = 'Nightly Connect' as WalletName<'Nightly Connect'> +export const APTOS_NETWORK = 'aptos' + +export class NightlyConnectAptosAdapter implements AdapterPlugin { + // TODO: add later "implements WalletAdapter" + name = AptosWalletName + icon: `data:image/${'svg+xml' | 'webp' | 'png' | 'gif'};base64,${string}` = logoBase64 + readonly url = + 'https://chromewebstore.google.com/detail/nightly/fiikommddbeccaoicoejoniammnalkfa?hl=en' + provider = undefined + connected = false + connecting = false + // Nightly connect fields + private _app: AppAptos | undefined + // private _innerStandardAdapter: StandardWalletAdapter | undefined + private _loading = false + private _modal: NightlyConnectSelectorModal | undefined + private _appInitData: AppInitData + private _eagerConnectForStandardWallets = true + private _walletsList: IWalletListItem[] = [] + private _chosenMobileWalletName: string | undefined + private _account: AccountInfo | undefined = undefined + private _connectionType: ConnectionType | undefined + private _metadataWallets: MetadataWallet[] = [] + private _initOnConnect: boolean + + get walletsList() { + return this._walletsList + } + + set walletsList(list: IWalletListItem[]) { + this._walletsList = list + if (this._modal) { + this._modal.walletsList = list + } + } + + // We need internal _connecting since sui messes with connecting state + private _connecting = false + constructor( + appInitData: AppInitData, + eagerConnectForStandardWallets?: boolean, + initOnConnect = false + ) { + this._connecting = false + this.connecting = false + this.connected = false + this._appInitData = appInitData + this._eagerConnectForStandardWallets = eagerConnectForStandardWallets ?? true + this._loading = false + this._initOnConnect = initOnConnect + } + + // version?: 'v1' | 'v2' | undefined + // providerName?: string | undefined + // provider: any + // deeplinkProvider?: ((data: { url: string }) => string) | undefined + // network: () => Promise + // signMessage(message: T): Promise { + // throw new Error('Method not implemented.') + // } + // onNetworkChange: OnNetworkChange + // onAccountChange: OnAccountChange + + public static initApp = async ( + appInitData: AppInitData + ): Promise<[AppAptos, MetadataWallet[]]> => { + try { + return await Promise.all([ + AppAptos.build({ ...appInitData }), + AppAptos.getWalletsMetadata( + `${appInitData.url ?? 'https://nc2.nightly.app'}/get_wallets_metadata` + ) + .then((list) => + list.map((wallet) => ({ + name: wallet.name, + icon: wallet.image.default, + deeplink: wallet.mobile, + link: wallet.homepage, + walletType: wallet.walletType + })) + ) + .catch(() => [] as MetadataWallet[]) + ]) + } catch { + clearSessionIdForNetwork(APTOS_NETWORK) + return await Promise.all([ + AppAptos.build({ ...appInitData }), + AppAptos.getWalletsMetadata( + `${appInitData.url ?? 'https://nc2.nightly.app'}/get_wallets_metadata` + ) + .then((list) => + list.map((wallet) => ({ + name: wallet.name, + icon: wallet.image.default, + deeplink: wallet.mobile, + link: wallet.homepage, + walletType: wallet.walletType + })) + ) + .catch(() => [] as MetadataWallet[]) + ]) + } + } + + public static build = async ( + appInitData: AppInitData, + eagerConnectForStandardWallets?: boolean, + anchorRef?: HTMLElement | null, + uiOverrides?: { + variablesOverride?: object + stylesOverride?: string + qrConfigOverride?: Partial + } + ) => { + const adapter = new NightlyConnectAptosAdapter(appInitData, eagerConnectForStandardWallets) + + adapter._modal = new NightlyConnectSelectorModal( + adapter.walletsList, + appInitData.url ?? 'https://nc2.nightly.app', + { + name: APTOS_NETWORK, + icon: 'https://registry.nightly.app/networks/aptos.png' + }, + anchorRef, + uiOverrides?.variablesOverride, + uiOverrides?.stylesOverride, + uiOverrides?.qrConfigOverride + ) + + const [app, metadataWallets] = await NightlyConnectAptosAdapter.initApp(appInitData) + + adapter._app = app + adapter._metadataWallets = metadataWallets + // adapter.walletsList = getWalletsList( + // metadataWallets, + // suiWalletsFilter, + // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined + // ) + + return adapter + } + + public static buildLazy = ( + appInitData: AppInitData, + eagerConnectForStandardWallets?: boolean, + anchorRef?: HTMLElement | null, + uiOverrides?: { + variablesOverride?: object + stylesOverride?: string + qrConfigOverride?: Partial + } + ) => { + const adapter = new NightlyConnectAptosAdapter(appInitData, eagerConnectForStandardWallets) + + // adapter.walletsList = getWalletsList( + // [], + // suiWalletsFilter, + // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined + // ) + adapter._modal = new NightlyConnectSelectorModal( + adapter.walletsList, + appInitData.url ?? 'https://nc2.nightly.app', + { + name: APTOS_NETWORK, + icon: 'https://registry.nightly.app/networks/sui.png' + }, + anchorRef, + uiOverrides?.variablesOverride, + uiOverrides?.stylesOverride, + uiOverrides?.qrConfigOverride + ) + + adapter._loading = true + + NightlyConnectAptosAdapter.initApp(appInitData).then(([app, metadataWallets]) => { + adapter._app = app + adapter._metadataWallets = metadataWallets + // adapter.walletsList = getWalletsList( + // metadataWallets, + // suiWalletsFilter, + // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined + // ) + adapter._loading = false + }) + + return adapter + } + public static buildWithInitOnConnect = ( + appInitData: AppInitData, + eagerConnectForStandardWallets?: boolean, + anchorRef?: HTMLElement | null, + uiOverrides?: { + variablesOverride?: object + stylesOverride?: string + qrConfigOverride?: Partial + } + ) => { + const adapter = new NightlyConnectAptosAdapter( + appInitData, + eagerConnectForStandardWallets, + true + ) + + // adapter.walletsList = getWalletsList( + // [], + // suiWalletsFilter, + // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined + // ) + + adapter._modal = new NightlyConnectSelectorModal( + adapter.walletsList, + appInitData.url ?? 'https://nc2.nightly.app', + { + name: APTOS_NETWORK, + icon: 'https://registry.nightly.app/networks/sui.png' + }, + anchorRef, + uiOverrides?.variablesOverride, + uiOverrides?.stylesOverride, + uiOverrides?.qrConfigOverride + ) + + return adapter + } + connect = async () => { + return new Promise((resolve, reject) => { + const innerConnect = async () => { + try { + if (this._connecting) { + reject() + return + } + if (this._account) { + resolve(this._account) + return + } + + if (this._initOnConnect) { + this._connecting = true + this.connecting = true + + if (!this._app) { + try { + const [app, metadataWallets] = await NightlyConnectAptosAdapter.initApp( + this._appInitData + ) + + this._app = app + this._metadataWallets = metadataWallets + // this.walletsList = getWalletsList( + // metadataWallets, + // suiWalletsFilter, + // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined + // ) + } catch { + if (!this._app) { + this._connecting = false + this.connecting = false + throw new Error('Wallet not ready') + } + } + } + } else { + if (this._loading) { + // we do it to ensure proper connect flow in case if adapter is lazily built, but e. g. sui wallets selector uses its own eager connect + for (let i = 0; i < 200; i++) { + await sleep(10) + + if (!this._loading) { + break + } + } + + if (this._loading) { + throw new Error('Wallet not ready') + } + } + + if (!this._app) { + throw new Error('Wallet not ready') + } + + this._connecting = true + this.connecting = true + } + + if (this._app.hasBeenRestored() && this._app.connectedPublicKeys.length > 0) { + this.eagerConnectDeeplink() + const keys = this._app.connectedPublicKeys.map((pk) => { + const accountInfo: AccountInfo = JSON.parse(pk) + return accountInfo + }) + this._account = keys[0] + this.connected = true + this._connecting = false + this.connecting = false + this._connectionType = ConnectionType.Nightly + resolve(this._account) + return + } + const recentName = getRecentStandardWalletForNetwork(APTOS_NETWORK) + if ( + this._eagerConnectForStandardWallets && + recentName !== null && + isStandardConnectedForNetwork(APTOS_NETWORK) + ) { + // await this.connectToStandardWallet(recentName, resolve) + return + } + + this._app.on('userConnected', (e) => { + try { + if (this._chosenMobileWalletName) { + persistRecentStandardWalletForNetwork(this._chosenMobileWalletName, APTOS_NETWORK) + } else { + clearRecentStandardWalletForNetwork(APTOS_NETWORK) + } + e.accounts + + // this._accounts = e.publicKeys.map((pk) => createSuiWalletAccountFromString(pk)) + this._account = e.accounts[0] + this.connected = true + this._connecting = false + this.connecting = false + this._connectionType = ConnectionType.Nightly + this._modal?.closeModal() + resolve(this._account) + } catch (e) { + this.disconnect() + this._modal?.closeModal() + reject(e) + } + }) + if (!this._modal) { + this._connecting = false + this.connecting = false + reject(new Error('Wallet not ready')) + } + // _modal is defined here + this._modal!.onClose = () => { + if (this._connecting) { + this._connecting = false + this.connecting = false + const error = new Error('Connection cancelled') + reject(error) + } + } + // Try open + const opened = this._modal!.openModal(this._app!.sessionId, (walletName) => { + if ( + isMobileBrowser() && + !this.walletsList.find((w) => w.name === walletName)?.standardWallet + ) { + this.connectToMobileWallet(walletName) + } else { + // this.connectToStandardWallet(walletName, resolve) + } + }) + // If modal is not opened, reject + // This might be caused by SSR + if (!opened) { + this._connecting = false + this.connecting = false + const error = new Error('Failed to open modal') + reject(error) + } + } catch (error: unknown) { + this._connecting = false + this.connecting = false + + reject(error) + } + } + + innerConnect() + }) + } + + disconnect = async () => { + if (!this.connected) { + throw new Error('Wallet not connected') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + clearSessionIdForNetwork(APTOS_NETWORK) + // Refresh app session + this._app = await AppAptos.build(this._appInitData) + + break + } + case ConnectionType.WalletStandard: { + // if (this._innerStandardAdapter) { + // await this._innerStandardAdapter.disconnect() + // persistStandardDisconnectForNetwork(APTOS_NETWORK) + // this.walletsList = getWalletsList( + // this._metadataWallets, + // suiWalletsFilter, + // getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + // ) + // } + break + } + } + // this._innerStandardAdapter = undefined + this._connectionType = undefined + this.connected = false + this._connecting = false + this.connecting = false + this._account = undefined + } + async account(): Promise { + if (this._account) { + return this._account + } else { + throw new Error('Wallet not connected') + } + } + async network(): Promise { + if (!this.connected) { + throw new Error('Wallet not connected') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + return this._app!.networkInfo + } + case ConnectionType.WalletStandard: { + throw 'not implemented' + } + } + throw 'Should not happen' + } + async onNetworkChange(callback: any): Promise { + throw 'not implemented' + } + async onAccountChange(callback: any): Promise { + throw 'not implemented' + } + async signAndSubmitTransaction( + transaction: Types.TransactionPayload, + options?: any + ): Promise<{ hash: Types.HexEncodedBytes }> { + if (!this._app || !this._connectionType) { + throw new Error('Wallet not ready') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + return await this._app.signAndSubmitTransaction(transaction, options) + } + case ConnectionType.WalletStandard: { + throw 'not implemented' + } + } + } + async signMessage(message: SignMessagePayload): Promise { + if (!this._app || !this._connectionType) { + throw new Error('Wallet not ready') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + return await this._app.signMessage(message) + } + case ConnectionType.WalletStandard: { + throw 'not implemented' + } + } + } + + canEagerConnect = async () => { + // utility for case if somebody wants to fire connect asap, but doesn't want to show modal + // if e. g. there was no user connected on the device yet + if (this._loading) { + for (let i = 0; i < 200; i++) { + await sleep(10) + + if (!this._loading) { + break + } + } + } + + if (this._loading) { + false + } + + if (this._app && this._app.hasBeenRestored() && this._app.connectedPublicKeys.length > 0) { + return true + } + + if ( + this._eagerConnectForStandardWallets && + getRecentStandardWalletForNetwork(APTOS_NETWORK) !== null && + isStandardConnectedForNetwork(APTOS_NETWORK) + ) { + return true + } + + return false + } + + eagerConnectDeeplink = () => { + if (isMobileBrowser() && this._app) { + const mobileWalletName = getRecentStandardWalletForNetwork(APTOS_NETWORK) + const wallet = this.walletsList.find((w) => w.name === mobileWalletName) + + if (typeof wallet === 'undefined') { + return + } + + if (wallet.deeplink === null) { + return + } + + if (wallet.deeplink.native !== null) { + this._app.connectDeeplink({ + walletName: wallet.name, + url: wallet.deeplink.native + }) + return + } + if (wallet.deeplink.universal !== null) { + this._app.connectDeeplink({ + walletName: wallet.name, + url: wallet.deeplink.universal + }) + return + } + } + } + + connectToMobileWallet = (walletName: string) => { + if (this._modal) { + this._modal.setStandardWalletConnectProgress(true) + } + + const wallet = this.walletsList.find((w) => w.name === walletName) + + if (!this._app || typeof wallet === 'undefined') { + return + } + + if (wallet.deeplink === null) { + return + } + + if (wallet.deeplink.native !== null) { + this._app.connectDeeplink({ + walletName: wallet.name, + url: wallet.deeplink.native + }) + + this._chosenMobileWalletName = walletName + + triggerConnect( + wallet.deeplink.native, + this._app.sessionId, + this._appInitData.url ?? 'https://nc2.nightly.app' + ) + return + } + + if (wallet.deeplink.universal !== null) { + this._app.connectDeeplink({ + walletName: wallet.name, + url: wallet.deeplink.universal + }) + + this._chosenMobileWalletName = walletName + + triggerConnect( + wallet.deeplink.universal, + this._app.sessionId, + this._appInitData.url ?? 'https://nc2.nightly.app' + ) + return + } + } + // connectToStandardWallet = async (walletName: string, onSuccess: () => void) => { + // try { + // if (this._modal) { + // this._modal.setStandardWalletConnectProgress(true) + // } + // const wallet = this.walletsList.find((w) => w.name === walletName) + // if (typeof wallet?.standardWallet === 'undefined') { + // throw new Error('Wallet not found') + // } + + // const adapter = new StandardWalletAdapter({ + // wallet: wallet.standardWallet + // } as StandardWalletAdapterConfig) + + // await adapter.connect() + + // persistRecentStandardWalletForNetwork(walletName, SUI_NETWORK) + // persistStandardConnectForNetwork(SUI_NETWORK) + // this._connectionType = ConnectionType.WalletStandard + // this._innerStandardAdapter = adapter + // this._accounts = (await adapter.getAccounts()).map((a) => a) + // this.connected = true + // this._connecting = false + // this.connecting = false + + // this._modal?.closeModal() + // onSuccess() + // } catch (e) { + // if (this._modal) { + // this._modal.setStandardWalletConnectProgress(false) + // } + // clearRecentStandardWalletForNetwork(SUI_NETWORK) + // this._connecting = false + // this.connecting = false + // throw e + // } + // } +} diff --git a/sdk/packages/selector-aptos/src/detection.ts b/sdk/packages/selector-aptos/src/detection.ts new file mode 100644 index 00000000..51446e26 --- /dev/null +++ b/sdk/packages/selector-aptos/src/detection.ts @@ -0,0 +1,13 @@ +// TODO +// import { Wallet } from '@wallet-standard/core' + +// import { isWalletWithRequiredFeatureSet } from '@mysten/wallet-standard' + +// export const suiWalletsFilter = (wallet: Wallet) => { +// const is = isWalletWithRequiredFeatureSet(wallet, [ +// 'sui:signAndExecuteTransactionBlock', +// 'sui:signTransactionBlock' +// ]) +// return is +// } +// diff --git a/sdk/packages/selector-aptos/src/icon.ts b/sdk/packages/selector-aptos/src/icon.ts new file mode 100644 index 00000000..29ad72aa --- /dev/null +++ b/sdk/packages/selector-aptos/src/icon.ts @@ -0,0 +1,2 @@ +export const logoBase64 = + 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyNy4yLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iV2Fyc3R3YV8yXzAwMDAwMDYxNDM5MzEzMjMxMjk4MzY3OTIwMDAwMDAxNjg3NTczNjg2ODIwNzI3MjI1XyINCgkgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCAxMTQ2LjMgMTE0Ni4zIg0KCSBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxMTQ2LjMgMTE0Ni4zOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KCS5zdDB7ZmlsbDojRjdGN0Y3O30NCjwvc3R5bGU+DQo8Zz4NCgk8Zz4NCgkJPHBhdGggY2xhc3M9InN0MCIgZD0iTTc2NS4zLDM0OS40Yy0zNi4xLDUwLjUtODEuNCw4NS40LTEzNC45LDEwOC44Yy0xOC42LTUuMS0zNy42LTcuOC01Ni40LTcuNmMtMC42LDAtMS4xLDAtMS43LDANCgkJCWMtMTguMiwwLTM2LjYsMi43LTU0LjYsNy42Yy01My40LTIzLjQtOTguNy01OC40LTEzNC45LTEwOC44Yy0xMSwyNy41LTUzLDEyMi4yLTIuNSwyNTQuN2MwLDAtMTYuMSw2OS4xLDEzLjUsMTI4LjUNCgkJCWMwLDAsNDIuOS0xOS41LDc3LDcuOWMzNS43LDI5LDI0LjMsNTYuOCw0OS40LDgwLjdjMjEuNiwyMiw1My44LDIyLDUzLjgsMjJzMzIuMiwwLDUzLjgtMjJjMjUuMS0yMy45LDEzLjgtNTEuNyw0OS40LTgwLjcNCgkJCWMzNC4xLTI3LjQsNzctNy45LDc3LTcuOWMyOS42LTU5LjQsMTMuNS0xMjguNSwxMy41LTEyOC41QzgxOC4yLDQ3MS42LDc3Ni4zLDM3Ni45LDc2NS4zLDM0OS40eiBNNDA3LjIsNTg1LjcNCgkJCWMtMjcuNS01Ni4zLTM1LTEzMy43LTE3LjYtMTk0LjhjMjIuOSw1Ny45LDU0LDg0LDkxLjEsMTExLjVDNDY0LjksNTM1LDQzNS40LDU2NS44LDQwNy4yLDU4NS43eiBNNDg2LjIsNjg1DQoJCQljLTIxLjYtOS41LTI2LjItMjguNC0yNi4yLTI4LjRjMjkuNS0xOC41LDcyLjgtNC40LDc0LjIsMzkuNkM1MTEuMyw2ODIuMyw1MDMuOCw2OTIuNyw0ODYuMiw2ODV6IE01NzQuMSw4NDAuOA0KCQkJYy0xNS41LDAtMjgtMTEuMS0yOC0yNC43czEyLjYtMjQuNywyOC0yNC43YzE1LjUsMCwyOCwxMS4xLDI4LDI0LjdTNTg5LjUsODQwLjgsNTc0LjEsODQwLjh6IE02NjIsNjg1DQoJCQljLTE3LjYsNy43LTI1LjEtMi43LTQ4LDExLjFjMS40LTQzLjksNDQuNy01OC4xLDc0LjItMzkuNkM2ODguMiw2NTYuNSw2ODMuNSw2NzUuNSw2NjIsNjg1eiBNNzQwLjksNTg1LjcNCgkJCWMtMjguMi0xOS45LTU3LjctNTAuNy03My41LTgzLjNjMzcuMS0yNy41LDY4LjItNTMuNiw5MS4xLTExMS41Qzc3NS45LDQ1Miw3NjguNCw1MjkuNCw3NDAuOSw1ODUuN3oiLz4NCgk8L2c+DQoJPGc+DQoJCTxnPg0KCQkJPHBhdGggY2xhc3M9InN0MCIgZD0iTTEwMDIuMSw1MjQuOGMtMi40LTIuNi0xNS44LTE2LjctMzcuNi0xNy4zYy0yNC0wLjctMzguOSwxNS41LTQxLDE3LjhjLTguNS02Mi45LTM0LjEtMTIyLjMtNzQuMi0xNzIuNQ0KCQkJCWMtNTktNzMuOC0xNDMuMS0xMjAuMi0yMzYuOS0xMzAuNmMtOTMuOC0xMC41LTE4Ni4xLDE2LjItMjU5LjksNzUuMmMtNTIuNyw0Mi4yLTkyLDk3LjgtMTEzLjcsMTYxYy0zLDguNi01LjYsMTcuNS03LjksMjYuMw0KCQkJCWMtNC4xLDE1LjktNy4xLDMyLjMtOSw0OC43bC0wLjEsMC45Yy0yLjQsMjEuNC0yMS44LDM2LjktNDMuMiwzNC41Yy0yMS4xLTIuNC0zNi42LTIxLjUtMzQuNi00Mi42VjUyNmMwLTAuMSwwLTAuMiwwLTAuNHYtMC40DQoJCQkJYzAtMC4zLDAuMS0wLjYsMC4xLTAuOXYtMC4xYzItMTcuNyw1LjEtMzUuMyw5LjMtNTIuNWMyLjMtOS42LDUtMTkuMiw4LTI4LjhjOC44LTI3LjgsMjAuNS01NC45LDM0LjktODAuNQ0KCQkJCWMyNy4zLTQ4LjcsNjMuMy05MS4xLDEwNy4xLTEyNi4xczkzLjEtNjAuOCwxNDYuNi03Ni43YzM5LjktMTEuOSw4MC44LTE3LjgsMTIyLjItMTcuOGMxNi4xLDAsMzIuMywwLjksNDguNSwyLjcNCgkJCQljNTcuOSw2LjUsMTEyLjgsMjQuMSwxNjMuMiw1Mi40QzgzMi42LDIyNC4yLDg3NSwyNjAuMyw5MTAsMzA0YzM1LDQzLjgsNjAuOCw5My4xLDc2LjcsMTQ2LjYNCgkJCQlDOTk0LjIsNDc0LjksOTk5LjIsNDk5LjgsMTAwMi4xLDUyNC44eiIvPg0KCQk8L2c+DQoJCTxnPg0KCQkJPHBhdGggY2xhc3M9InN0MCIgZD0iTTEwMDIuMiw2MjAuMWMwLDAuMy0wLjEsMC42LTAuMSwwLjlsLTAuMSwwLjRjMCwwLjEsMCwwLjMsMCwwLjR2MC4zYy0yLDE3LjctNS4xLDM1LjMtOS4zLDUyLjUNCgkJCQljLTIuMyw5LjctNSwxOS40LTgsMjguOGMtOC44LDI3LjgtMjAuNSw1NC45LTM0LjksODAuNUM5MjIuNSw4MzIuNiw4ODYuNSw4NzUsODQyLjcsOTEwcy05My4xLDYwLjgtMTQ2LjYsNzYuNw0KCQkJCWMtNTUuNCwxNi41LTExMi45LDIxLjYtMTcwLjgsMTUuMXMtMTEyLjgtMjQuMS0xNjMuMi01Mi40QzMxMy40LDkyMi4xLDI3MSw4ODYuMSwyMzYsODQyLjNzLTYwLjgtOTMuMS03Ni43LTE0Ni42DQoJCQkJYy03LjItMjQuMy0xMi4zLTQ5LjItMTUuMS03NC4yYzIuOSwzLjIsMTUsMTUuNCwzNC42LDE3LjFjMjUuNCwyLjEsNDItMTUuNCw0NC4xLTE3LjZjOC41LDYyLjksMzQuMSwxMjIuMyw3NC4yLDE3Mi41DQoJCQkJYzU5LDczLjgsMTQzLjEsMTIwLjEsMjM2LjksMTMwLjZjMTMuMywxLjUsMjYuNiwyLjIsMzkuOSwyLjJjNzkuOCwwLDE1Ni44LTI2LjgsMjIwLTc3LjRjNTIuNy00Mi4yLDkyLTk3LjgsMTEzLjctMTYxDQoJCQkJYzMtOC42LDUuNi0xNy41LDcuOS0yNi4zYzQuMS0xNS45LDcuMS0zMi4zLDktNDguN2wwLjEtMC45YzEuMS0xMC40LDYuMy0xOS43LDE0LjQtMjYuMmM4LjItNi41LDE4LjMtOS41LDI4LjctOC4zDQoJCQkJQzk4OC44LDU3OS43LDEwMDQuMyw1OTguOCwxMDAyLjIsNjIwLjF6Ii8+DQoJCTwvZz4NCgk8L2c+DQo8L2c+DQo8L3N2Zz4NCg==' diff --git a/sdk/packages/selector-aptos/src/index.ts b/sdk/packages/selector-aptos/src/index.ts new file mode 100644 index 00000000..eed00ad5 --- /dev/null +++ b/sdk/packages/selector-aptos/src/index.ts @@ -0,0 +1,2 @@ +// export * from './detection' +export * from './adapter' diff --git a/sdk/packages/selector-aptos/tsconfig.json b/sdk/packages/selector-aptos/tsconfig.json new file mode 100644 index 00000000..0f7485e2 --- /dev/null +++ b/sdk/packages/selector-aptos/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "ESNext", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "sourceMap": true, + "outDir": "dist", + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationDir": "types", + "emitDeclarationOnly": true + } +} diff --git a/sdk/pnpm-lock.yaml b/sdk/pnpm-lock.yaml index 661d1c1a..b32a4cae 100644 --- a/sdk/pnpm-lock.yaml +++ b/sdk/pnpm-lock.yaml @@ -32,11 +32,72 @@ importers: version: 2.8.0 turbo: specifier: latest - version: 1.10.16 + version: 1.10.7 typescript: specifier: ^4.9.0 version: 4.9.4 + apps/aptos: + dependencies: + '@aptos-labs/wallet-adapter-core': + specifier: ^3.0.0 + version: 3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0) + '@nightlylabs/nightly-connect-base': + specifier: 0.0.27 + version: link:../base + '@noble/hashes': + specifier: ^1.3.0 + version: 1.3.0 + aptos: + specifier: ^1.20.0 + version: 1.20.0 + eventemitter3: + specifier: ^5.0.1 + version: 5.0.1 + uuid: + specifier: ^9.0.0 + version: 9.0.0 + devDependencies: + '@rollup/plugin-commonjs': + specifier: ^25.0.0 + version: 25.0.0(rollup@3.23.1) + '@rollup/plugin-node-resolve': + specifier: ^15.1.0 + version: 15.2.1(rollup@3.23.1) + '@rollup/plugin-terser': + specifier: ^0.4.3 + version: 0.4.3(rollup@3.23.1) + '@rollup/plugin-typescript': + specifier: ^11.1.1 + version: 11.1.1(rollup@3.23.1)(tslib@2.5.3)(typescript@5.1.6) + '@types/node': + specifier: ^20.3.0 + version: 20.4.2 + '@vitest/ui': + specifier: ^0.31.1 + version: 0.31.1(vitest@0.31.1) + bs58: + specifier: ^5.0.0 + version: 5.0.0 + js-sha256: + specifier: ^0.9.0 + version: 0.9.0 + rollup: + specifier: ^3.23.1 + version: 3.23.1 + rollup-plugin-dts: + specifier: ^5.3.0 + version: 5.3.0(rollup@3.23.1)(typescript@5.1.6) + tslib: + specifier: ^2.5.3 + version: 2.5.3 + tweetnacl: + specifier: ^1.0.3 + version: 1.0.3 + typescript: + specifier: ^5.1.3 + version: 5.1.6 + apps/base: dependencies: cross-fetch: @@ -56,7 +117,7 @@ importers: version: 9.0.0 ws: specifier: ^8.13.0 - version: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + version: 8.13.0 devDependencies: '@rollup/plugin-commonjs': specifier: ^25.0.0 @@ -586,6 +647,61 @@ importers: specifier: ^5.1.3 version: 5.1.3 + packages/selector-aptos: + dependencies: + '@aptos-labs/wallet-adapter-core': + specifier: ^3.0.0 + version: 3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0) + '@nightlylabs/nightly-connect-aptos': + specifier: 0.0.1 + version: link:../../apps/aptos + '@nightlylabs/nightly-connect-base': + specifier: ^0.0.27 + version: link:../../apps/base + '@nightlylabs/wallet-selector-base': + specifier: 0.2.4 + version: link:../selector-base + '@wallet-standard/core': + specifier: ^1.0.3 + version: 1.0.3 + aptos: + specifier: ^1.20.0 + version: 1.20.0 + bs58: + specifier: ^4.0.1 + version: 4.0.1 + events: + specifier: ^3.3.0 + version: 3.3.0 + devDependencies: + '@rollup/plugin-commonjs': + specifier: ^25.0.0 + version: 25.0.0(rollup@3.23.1) + '@rollup/plugin-node-resolve': + specifier: ^15.1.0 + version: 15.2.1(rollup@3.23.1) + '@rollup/plugin-terser': + specifier: ^0.4.3 + version: 0.4.3(rollup@3.23.1) + '@rollup/plugin-typescript': + specifier: ^11.1.1 + version: 11.1.1(rollup@3.23.1)(tslib@2.5.3)(typescript@5.1.6) + '@types/bs58': + specifier: ^4.0.1 + version: 4.0.1 + rollup: + specifier: ^3.23.1 + version: 3.23.1 + rollup-plugin-dts: + specifier: ^5.3.0 + version: 5.3.0(rollup@3.23.1)(typescript@5.1.6) + tslib: + specifier: ^2.5.3 + version: 2.5.3 + typescript: + specifier: ^5.1.3 + version: 5.1.6 + packages/selector-base: dependencies: '@nightlylabs/nightly-connect-base': @@ -950,6 +1066,44 @@ packages: /@antfu/utils@0.7.4: resolution: {integrity: sha512-qe8Nmh9rYI/HIspLSTwtbMFPj6dISG6+dJnOguTlPNXtCvS2uezdxscVBb7/3DrmNbQK49TDqpkSQ1chbRGdpQ==} + /@aptos-labs/aptos-client@0.0.2: + resolution: {integrity: sha512-FgKZb5zDPz8MmAcVxXzYhxP6OkzuIPoDRJp48YJ8+vrZ9EOZ35HaWGN2M3u+GPdnFE9mODFqkxw3azh3kHGZjQ==} + engines: {node: '>=15.10.0'} + dependencies: + axios: 0.27.2 + got: 11.8.6 + transitivePeerDependencies: + - debug + dev: false + + /@aptos-labs/ts-sdk@0.0.7: + resolution: {integrity: sha512-6YRVRrrKFIo2wiYVmrgcl6oj87B2LW+AhgrAQGIvwHPzr+ihQl2woFpC/UmygG9dv+n8Ow9XOhuFGlg60Xwngw==} + engines: {node: '>=11.0.0'} + dependencies: + '@aptos-labs/aptos-client': 0.0.2 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/bip32': 1.3.2 + '@scure/bip39': 1.2.1 + form-data: 4.0.0 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - debug + dev: false + + /@aptos-labs/wallet-adapter-core@3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0): + resolution: {integrity: sha512-aeKO4NJWy4pPw54vyUa5embqlaosSeTCdiQ41O+i5fG8gD+YBVepJHaqx/dai3rABFwKTxmckpe+Q7SrIUGyyQ==} + peerDependencies: + '@aptos-labs/ts-sdk': ^0.0.7 + aptos: ^1.19.0 + dependencies: + '@aptos-labs/ts-sdk': 0.0.7 + aptos: 1.20.0 + buffer: 6.0.3 + eventemitter3: 4.0.7 + tweetnacl: 1.0.3 + dev: false + /@aw-web-design/x-default-browser@1.4.88: resolution: {integrity: sha512-AkEmF0wcwYC2QkhK703Y83fxWARttIWXDmQN8+cof8FmFZ5BRhnNXGymeb1S73bOCLfWjYELxtujL56idCN/XA==} hasBin: true @@ -3481,7 +3635,7 @@ packages: serve-handler: 6.1.5 shelljs: 0.8.5 terser-webpack-plugin: 5.3.9(webpack@5.88.0) - tslib: 2.5.3 + tslib: 2.6.2 update-notifier: 5.1.0 url-loader: 4.1.1(file-loader@6.2.0)(webpack@5.88.0) wait-on: 6.0.1(debug@4.3.4) @@ -4709,7 +4863,7 @@ packages: '@jest/schemas': 29.4.3 '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 - '@types/node': 20.4.2 + '@types/node': 20.9.0 '@types/yargs': 17.0.24 chalk: 4.1.2 @@ -4845,8 +4999,8 @@ packages: engines: {node: '>=16'} dependencies: '@mysten/bcs': 0.7.3 - '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 '@open-rpc/client-js': 1.8.1 '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 @@ -4866,7 +5020,7 @@ packages: dependencies: '@mysten/bcs': 0.7.4 '@noble/curves': 1.1.0 - '@noble/hashes': 1.3.1 + '@noble/hashes': 1.3.2 '@open-rpc/client-js': 1.8.1 '@scure/bip32': 1.3.2 '@scure/bip39': 1.2.1 @@ -5057,12 +5211,6 @@ packages: dev: false optional: true - /@noble/curves@1.0.0: - resolution: {integrity: sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==} - dependencies: - '@noble/hashes': 1.3.0 - dev: false - /@noble/curves@1.1.0: resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} dependencies: @@ -5074,6 +5222,10 @@ packages: dependencies: '@noble/hashes': 1.3.2 + /@noble/hashes@1.1.3: + resolution: {integrity: sha512-CE0FCR57H2acVI5UOzIGSSIYxZ6v/HOhDR0Ro9VLyhnzLwx0o8W1mmgaqlEUx4049qJDlIBRztv5k+MM8vbO3A==} + dev: false + /@noble/hashes@1.3.0: resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} dev: false @@ -5225,7 +5377,7 @@ packages: '@polkadot/util': 12.5.1 '@polkadot/util-crypto': 12.3.2(@polkadot/util@12.5.1) '@polkadot/x-global': 12.3.2 - tslib: 2.6.0 + tslib: 2.6.2 transitivePeerDependencies: - bufferutil - supports-color @@ -5766,7 +5918,7 @@ packages: dependencies: '@polkadot/x-global': 12.3.2 tslib: 2.6.2 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -5778,7 +5930,7 @@ packages: dependencies: '@polkadot/x-global': 12.5.1 tslib: 2.6.2 - ws: 8.14.2 + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -5882,6 +6034,7 @@ packages: is-module: 1.0.0 resolve: 1.22.2 rollup: 3.23.1 + dev: true /@rollup/plugin-node-resolve@15.2.1(rollup@3.23.1): resolution: {integrity: sha512-nsbUg588+GDSu8/NS8T4UAshO6xeaOfINNuXeVHcKV02LJtoRaM1SiOacClw4kws1SFiNhdLGxlbMY9ga/zs/w==} @@ -5899,7 +6052,6 @@ packages: is-module: 1.0.0 resolve: 1.22.2 rollup: 3.23.1 - dev: true /@rollup/plugin-terser@0.4.3(rollup@3.23.1): resolution: {integrity: sha512-EF0oejTMtkyhrkwCdg0HJ0IpkcaVg1MMSf2olHb2Jp+1mnLM04OhjpJWGma4HobiDTF0WCyViWuvadyE9ch2XA==} @@ -6027,10 +6179,17 @@ packages: '@scure/base': 1.1.3 dev: false + /@scure/bip39@1.1.0: + resolution: {integrity: sha512-pwrPOS16VeTKg98dYXQyIjJEcWfz7/1YJIwxUEPFfQPtc86Ym/1sVgQ2RLoD43AazMk2l/unK4ITySSpW2+82w==} + dependencies: + '@noble/hashes': 1.1.3 + '@scure/base': 1.1.3 + dev: false + /@scure/bip39@1.2.1: resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==} dependencies: - '@noble/hashes': 1.3.1 + '@noble/hashes': 1.3.2 '@scure/base': 1.1.1 dev: false @@ -6053,6 +6212,11 @@ packages: engines: {node: '>=6'} dev: false + /@sindresorhus/is@4.6.0: + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + dev: false + /@slorber/static-site-generator-webpack-plugin@4.0.7: resolution: {integrity: sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==} engines: {node: '>=14'} @@ -6181,8 +6345,8 @@ packages: deprecated: This build contains a bad TypeScript definition for getProgramAccounts dependencies: '@babel/runtime': 7.22.3 - '@noble/curves': 1.0.0 - '@noble/hashes': 1.3.0 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 '@solana/buffer-layout': 4.0.1 agentkeepalive: 4.3.0 bigint-buffer: 1.1.5 @@ -6818,7 +6982,7 @@ packages: ts-dedent: 2.2.0 util-deprecate: 1.0.2 watchpack: 2.4.0 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - encoding @@ -7292,6 +7456,13 @@ packages: defer-to-connect: 1.1.3 dev: false + /@szmarczak/http-timer@4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: false + /@trysound/sax@0.2.0: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} @@ -7328,18 +7499,18 @@ packages: /@types/bn.js@5.1.1: resolution: {integrity: sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 /@types/body-parser@1.19.2: resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} dependencies: '@types/connect': 3.4.35 - '@types/node': 20.4.2 + '@types/node': 20.9.0 /@types/bonjour@3.5.10: resolution: {integrity: sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/bs58@4.0.1: @@ -7348,6 +7519,15 @@ packages: base-x: 3.0.9 dev: true + /@types/cacheable-request@6.0.3: + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 20.9.0 + '@types/responselike': 1.0.0 + dev: false + /@types/chai-subset@1.3.3: resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} dependencies: @@ -7359,7 +7539,7 @@ packages: /@types/clean-css@4.2.6: resolution: {integrity: sha512-Ze1tf+LnGPmG6hBFMi0B4TEB0mhF7EiMM5oyjLDNPE9hxrPU0W+5+bHvO+eFPA+bt0iC1zkQMoU/iGdRVjcRbw==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 source-map: 0.6.1 dev: true @@ -7367,13 +7547,13 @@ packages: resolution: {integrity: sha512-4x5FkPpLipqwthjPsF7ZRbOv3uoLUFkTA9G9v583qi4pACvq0uTELrB8OLUzPWUI4IJIyvM85vzkV1nyiI2Lig==} dependencies: '@types/express-serve-static-core': 4.17.35 - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/connect@3.4.35: resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 /@types/cookie@0.5.1: resolution: {integrity: sha512-COUnqfB2+ckwXXSFInsFdOAWQzCCx+a5hq2ruyj+Vjund94RJQd4LG2u9hnvJrTgunKAaax7ancBYlDrNYxA0g==} @@ -7420,7 +7600,7 @@ packages: /@types/express-serve-static-core@4.17.35: resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 '@types/qs': 6.9.7 '@types/range-parser': 1.2.4 '@types/send': 0.17.1 @@ -7441,13 +7621,13 @@ packages: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: true /@types/graceful-fs@4.1.6: resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: true /@types/hast@2.3.4: @@ -7471,10 +7651,14 @@ packages: '@types/uglify-js': 3.17.1 dev: true + /@types/http-cache-semantics@4.0.4: + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + dev: false + /@types/http-proxy@1.17.11: resolution: {integrity: sha512-HC8G7c1WmaF2ekqpnFq626xd3Zz0uvaqFmBJNRZCGEZCXkvSdJoNFn/8Ygbd9fKNQj8UzLdCETaI0UWPAjK7IA==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/istanbul-lib-coverage@2.0.4: @@ -7500,7 +7684,7 @@ packages: /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/lodash@4.14.195: @@ -7534,7 +7718,7 @@ packages: /@types/node-fetch@2.6.4: resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 form-data: 3.0.1 dev: true @@ -7640,7 +7824,7 @@ packages: /@types/resolve@1.17.1: resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 /@types/resolve@1.20.2: resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} @@ -7648,7 +7832,7 @@ packages: /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/retry@0.12.0: @@ -7658,7 +7842,7 @@ packages: /@types/sax@1.2.4: resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/scheduler@0.16.3: @@ -7671,7 +7855,7 @@ packages: resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} dependencies: '@types/mime': 1.3.2 - '@types/node': 20.4.2 + '@types/node': 20.9.0 /@types/serve-index@1.9.1: resolution: {integrity: sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==} @@ -7683,12 +7867,12 @@ packages: resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} dependencies: '@types/mime': 3.0.1 - '@types/node': 20.4.2 + '@types/node': 20.9.0 /@types/sockjs@0.3.33: resolution: {integrity: sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/trusted-types@2.0.3: @@ -7706,13 +7890,13 @@ packages: /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/ws@8.5.5: resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 dev: false /@types/yargs-parser@21.0.0: @@ -7900,7 +8084,7 @@ packages: dependencies: '@mapbox/node-pre-gyp': 1.0.10 '@rollup/pluginutils': 4.2.1 - acorn: 8.8.2 + acorn: 8.10.0 async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 @@ -8296,6 +8480,7 @@ packages: /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} + requiresBuild: true dependencies: color-convert: 1.9.3 @@ -8332,6 +8517,20 @@ packages: /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + /aptos@1.20.0: + resolution: {integrity: sha512-driZt7qEr4ndKqqVHMyuFsQAHy4gJ4HPQttgVIpeDfnOIEnIV7A2jyJ9EYO2A+MayuyxXB+7yCNXT4HyBFJdpA==} + engines: {node: '>=11.0.0'} + dependencies: + '@aptos-labs/aptos-client': 0.0.2 + '@noble/hashes': 1.1.3 + '@scure/bip39': 1.1.0 + eventemitter3: 5.0.1 + form-data: 4.0.0 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - debug + dev: false + /are-we-there-yet@2.0.0: resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} engines: {node: '>=10'} @@ -8480,7 +8679,6 @@ packages: /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true /at-least-node@1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} @@ -8519,6 +8717,15 @@ packages: transitivePeerDependencies: - debug + /axios@0.27.2: + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + dependencies: + follow-redirects: 1.15.2(debug@4.3.4) + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: false + /axobject-query@3.2.1: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} dependencies: @@ -8926,6 +9133,11 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + /cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: false + /cacheable-request@6.1.0: resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} engines: {node: '>=8'} @@ -8939,6 +9151,19 @@ packages: responselike: 1.0.2 dev: false + /cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + dev: false + /call-bind@1.0.2: resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} dependencies: @@ -9007,6 +9232,7 @@ packages: /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} + requiresBuild: true dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 @@ -9181,6 +9407,7 @@ packages: /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + requiresBuild: true dependencies: color-name: 1.1.3 @@ -9192,6 +9419,7 @@ packages: /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + requiresBuild: true /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} @@ -9216,7 +9444,6 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 - dev: true /comma-separated-tokens@1.0.8: resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} @@ -9683,6 +9910,13 @@ packages: mimic-response: 1.0.1 dev: false + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: false + /deep-eql@4.1.3: resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} engines: {node: '>=6'} @@ -9734,6 +9968,11 @@ packages: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} dev: false + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: false + /define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} @@ -9774,7 +10013,6 @@ packages: /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: true /delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -10449,6 +10687,7 @@ packages: /escape-string-regexp@1.0.5: resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} engines: {node: '>=0.8.0'} + requiresBuild: true /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} @@ -10852,7 +11091,7 @@ packages: resolution: {integrity: sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==} engines: {node: '>= 0.8'} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 require-like: 0.1.2 dev: false @@ -11272,6 +11511,15 @@ packages: mime-types: 2.1.35 dev: true + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /formdata-polyfill@4.0.10: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} @@ -11612,6 +11860,23 @@ packages: dependencies: get-intrinsic: 1.2.1 + /got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.0 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + dev: false + /got@9.6.0: resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} engines: {node: '>=8.6'} @@ -11691,6 +11956,7 @@ packages: /has-flag@3.0.0: resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} engines: {node: '>=4'} + requiresBuild: true /has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} @@ -11959,6 +12225,14 @@ packages: - debug dev: false + /http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: false + /https-proxy-agent@4.0.0: resolution: {integrity: sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==} engines: {node: '>= 6.0.0'} @@ -12500,7 +12774,7 @@ packages: peerDependencies: ws: '*' dependencies: - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.13.0 dev: false /istanbul-lib-coverage@3.2.0: @@ -12561,7 +12835,7 @@ packages: dependencies: '@jest/types': 29.5.0 '@types/graceful-fs': 4.1.6 - '@types/node': 20.4.2 + '@types/node': 20.9.0 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -12584,7 +12858,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/node': 20.4.2 + '@types/node': 20.9.0 chalk: 4.1.2 ci-info: 3.8.0 graceful-fs: 4.2.11 @@ -12594,7 +12868,7 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -12602,7 +12876,7 @@ packages: resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.4.2 + '@types/node': 20.9.0 jest-util: 29.5.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -12719,6 +12993,10 @@ packages: resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} dev: false + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} @@ -12778,6 +13056,12 @@ packages: json-buffer: 3.0.0 dev: false + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: false + /kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} @@ -13163,6 +13447,11 @@ packages: engines: {node: '>=4'} dev: false + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: false + /mini-css-extract-plugin@2.7.6(webpack@5.88.0): resolution: {integrity: sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw==} engines: {node: '>= 12.13.0'} @@ -13703,6 +13992,11 @@ packages: engines: {node: '>=6'} dev: false + /p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + dev: false + /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -14656,6 +14950,11 @@ packages: inherits: 2.0.4 dev: false + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: false + /ramda@0.29.0: resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} dev: true @@ -15171,6 +15470,10 @@ packages: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: false + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: false + /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -15218,6 +15521,12 @@ packages: lowercase-keys: 1.0.1 dev: false + /responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + dependencies: + lowercase-keys: 2.0.0 + dev: false + /restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -15340,7 +15649,7 @@ packages: resolve: 1.22.2 rollup: 3.23.1 source-map-js: 1.0.2 - tslib: 2.6.0 + tslib: 2.6.2 dev: true /rollup-plugin-visualizer@5.9.2(rollup@3.23.1): @@ -15385,7 +15694,7 @@ packages: '@babel/runtime': 7.22.3 eventemitter3: 4.0.7 uuid: 8.3.2 - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) optionalDependencies: bufferutil: 4.0.7 utf-8-validate: 5.0.10 @@ -15769,7 +16078,7 @@ packages: requiresBuild: true dependencies: pako: 2.1.0 - ws: 8.14.2 + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -15780,7 +16089,7 @@ packages: resolution: {integrity: sha512-Wqw2fL/sELQByLSeeTX1Z/d0H4McmphPMx8vh6UZS/bIIDx81oU7s/drmx2iL/ME36uk++YxpRuJey8/MOyfOA==} requiresBuild: true dependencies: - ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10) + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -15840,7 +16149,7 @@ packages: dependencies: '@rollup/plugin-commonjs': 24.1.0(rollup@3.23.1) '@rollup/plugin-json': 6.0.0(rollup@3.23.1) - '@rollup/plugin-node-resolve': 15.1.0(rollup@3.23.1) + '@rollup/plugin-node-resolve': 15.2.1(rollup@3.23.1) '@vercel/nft': 0.22.6 fast-glob: 3.2.12 micromatch: 4.0.5 @@ -16264,6 +16573,7 @@ packages: /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} + requiresBuild: true dependencies: has-flag: 3.0.0 @@ -16618,9 +16928,7 @@ packages: /tslib@2.5.3: resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==} - - /tslib@2.6.0: - resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} + dev: true /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} @@ -16645,64 +16953,65 @@ packages: typescript: 5.1.6 dev: false - /turbo-darwin-64@1.10.16: - resolution: {integrity: sha512-+Jk91FNcp9e9NCLYlvDDlp2HwEDp14F9N42IoW3dmHI5ZkGSXzalbhVcrx3DOox3QfiNUHxzWg4d7CnVNCuuMg==} + /turbo-darwin-64@1.10.7: + resolution: {integrity: sha512-N2MNuhwrl6g7vGuz4y3fFG2aR1oCs0UZ5HKl8KSTn/VC2y2YIuLGedQ3OVbo0TfEvygAlF3QGAAKKtOCmGPNKA==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-darwin-arm64@1.10.16: - resolution: {integrity: sha512-jqGpFZipIivkRp/i+jnL8npX0VssE6IAVNKtu573LXtssZdV/S+fRGYA16tI46xJGxSAivrZ/IcgZrV6Jk80bw==} + /turbo-darwin-arm64@1.10.7: + resolution: {integrity: sha512-WbJkvjU+6qkngp7K4EsswOriO3xrNQag7YEGRtfLoDdMTk4O4QTeU6sfg2dKfDsBpTidTvEDwgIYJhYVGzrz9Q==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /turbo-linux-64@1.10.16: - resolution: {integrity: sha512-PpqEZHwLoizQ6sTUvmImcRmACyRk9EWLXGlqceogPZsJ1jTRK3sfcF9fC2W56zkSIzuLEP07k5kl+ZxJd8JMcg==} + /turbo-linux-64@1.10.7: + resolution: {integrity: sha512-x1CF2CDP1pDz/J8/B2T0hnmmOQI2+y11JGIzNP0KtwxDM7rmeg3DDTtDM/9PwGqfPotN9iVGgMiMvBuMFbsLhg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-linux-arm64@1.10.16: - resolution: {integrity: sha512-TMjFYz8to1QE0fKVXCIvG/4giyfnmqcQIwjdNfJvKjBxn22PpbjeuFuQ5kNXshUTRaTJihFbuuCcb5OYFNx4uw==} + /turbo-linux-arm64@1.10.7: + resolution: {integrity: sha512-JtnBmaBSYbs7peJPkXzXxsRGSGBmBEIb6/kC8RRmyvPAMyqF8wIex0pttsI+9plghREiGPtRWv/lfQEPRlXnNQ==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /turbo-windows-64@1.10.16: - resolution: {integrity: sha512-+jsf68krs0N66FfC4/zZvioUap/Tq3sPFumnMV+EBo8jFdqs4yehd6+MxIwYTjSQLIcpH8KoNMB0gQYhJRLZzw==} + /turbo-windows-64@1.10.7: + resolution: {integrity: sha512-7A/4CByoHdolWS8dg3DPm99owfu1aY/W0V0+KxFd0o2JQMTQtoBgIMSvZesXaWM57z3OLsietFivDLQPuzE75w==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /turbo-windows-arm64@1.10.16: - resolution: {integrity: sha512-sKm3hcMM1bl0B3PLG4ifidicOGfoJmOEacM5JtgBkYM48ncMHjkHfFY7HrJHZHUnXM4l05RQTpLFoOl/uIo2HQ==} + /turbo-windows-arm64@1.10.7: + resolution: {integrity: sha512-D36K/3b6+hqm9IBAymnuVgyePktwQ+F0lSXr2B9JfAdFPBktSqGmp50JNC7pahxhnuCLj0Vdpe9RqfnJw5zATA==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /turbo@1.10.16: - resolution: {integrity: sha512-2CEaK4FIuSZiP83iFa9GqMTQhroW2QryckVqUydmg4tx78baftTOS0O+oDAhvo9r9Nit4xUEtC1RAHoqs6ZEtg==} + /turbo@1.10.7: + resolution: {integrity: sha512-xm0MPM28TWx1e6TNC3wokfE5eaDqlfi0G24kmeHupDUZt5Wd0OzHFENEHMPqEaNKJ0I+AMObL6nbSZonZBV2HA==} hasBin: true + requiresBuild: true optionalDependencies: - turbo-darwin-64: 1.10.16 - turbo-darwin-arm64: 1.10.16 - turbo-linux-64: 1.10.16 - turbo-linux-arm64: 1.10.16 - turbo-windows-64: 1.10.16 - turbo-windows-arm64: 1.10.16 + turbo-darwin-64: 1.10.7 + turbo-darwin-arm64: 1.10.7 + turbo-linux-64: 1.10.7 + turbo-linux-arm64: 1.10.7 + turbo-windows-64: 1.10.7 + turbo-windows-arm64: 1.10.7 dev: true /tweetnacl@1.0.3: @@ -17553,7 +17862,7 @@ packages: spdy: 4.0.2 webpack: 5.88.0 webpack-dev-middleware: 5.3.3(webpack@5.88.0) - ws: 8.14.2 + ws: 8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - debug @@ -17808,7 +18117,7 @@ packages: optional: true dev: false - /ws@8.13.0(bufferutil@4.0.7)(utf-8-validate@5.0.10): + /ws@8.13.0: resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} engines: {node: '>=10.0.0'} peerDependencies: @@ -17819,11 +18128,9 @@ packages: optional: true utf-8-validate: optional: true - dependencies: - bufferutil: 4.0.7 - utf-8-validate: 5.0.10 + dev: false - /ws@8.14.2: + /ws@8.14.2(bufferutil@4.0.7)(utf-8-validate@5.0.10): resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} engines: {node: '>=10.0.0'} peerDependencies: @@ -17834,7 +18141,9 @@ packages: optional: true utf-8-validate: optional: true - dev: false + dependencies: + bufferutil: 4.0.7 + utf-8-validate: 5.0.10 /xdg-basedir@4.0.0: resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} From 9489f89b8de3d4eaa94a51a94f90ac7b26d05136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?NB=F0=9F=98=88?= Date: Mon, 4 Dec 2023 16:52:37 +0100 Subject: [PATCH 2/4] fixes + demo --- sdk/apps/aptos/src/app.ts | 4 +- sdk/apps/modal-example/package.json | 4 +- sdk/apps/modal-example/src/routes/aptos.tsx | 131 +++++++++++ sdk/build-only-packages.sh | 2 + sdk/packages/selector-aptos/package.json | 5 +- sdk/packages/selector-aptos/src/adapter.ts | 232 ++++++++++--------- sdk/packages/selector-aptos/src/detection.ts | 16 +- sdk/pnpm-lock.yaml | 20 ++ 8 files changed, 284 insertions(+), 130 deletions(-) create mode 100644 sdk/apps/modal-example/src/routes/aptos.tsx diff --git a/sdk/apps/aptos/src/app.ts b/sdk/apps/aptos/src/app.ts index 44d57be4..f08d28b7 100644 --- a/sdk/apps/aptos/src/app.ts +++ b/sdk/apps/aptos/src/app.ts @@ -32,9 +32,7 @@ export class AppAptos extends EventEmitter { sessionId: string base: BaseApp initData: AppAptosInitialize - url = 'https://nightly.app' - providerName?: string - provider: any + constructor(base: BaseApp, initData: AppAptosInitialize) { super() this.initData = initData diff --git a/sdk/apps/modal-example/package.json b/sdk/apps/modal-example/package.json index eaa1dd95..99c3aa4a 100644 --- a/sdk/apps/modal-example/package.json +++ b/sdk/apps/modal-example/package.json @@ -18,6 +18,8 @@ "@mysten/sui.js": "^0.42.0", "@mysten/wallet-adapter-wallet-standard": "^0.8.0", "@nightlylabs/wallet-selector-solana": "0.2.6", + "@nightlylabs/wallet-selector-aptos": "0.0.1", + "aptos": "^1.20.0", "@nightlylabs/nightly-connect-solana": "0.0.28", "@nightlylabs/nightly-connect-sui": "0.0.28", "@nightlylabs/wallet-selector-sui": "0.2.6", @@ -38,4 +40,4 @@ "engines": { "node": ">=16.8" } -} +} \ No newline at end of file diff --git a/sdk/apps/modal-example/src/routes/aptos.tsx b/sdk/apps/modal-example/src/routes/aptos.tsx new file mode 100644 index 00000000..3b098b87 --- /dev/null +++ b/sdk/apps/modal-example/src/routes/aptos.tsx @@ -0,0 +1,131 @@ +import { createEffect, createSignal, onMount, Show } from 'solid-js' +import { Title } from 'solid-start' +import { NightlyConnectAptosAdapter } from '@nightlylabs/wallet-selector-aptos' +import toast from 'solid-toast' +import { AptosClient } from 'aptos' +// Create an AptosClient to interact with devnet. +const client = new AptosClient('https://fullnode.devnet.aptoslabs.com/v1') +export default function Aptos() { + const [adapter, setAdapter] = createSignal() + const [eager, setEager] = createSignal(false) + const [publicKey, setPublicKey] = createSignal() + onMount(async () => { + NightlyConnectAptosAdapter.build( + { + appMetadata: { + name: 'NCTestAptos', + description: 'Nightly Connect Test', + icon: 'https://docs.nightly.app/img/logo.png', + additionalInfo: 'Courtesy of Nightly Connect team' + } + }, + true, + document.getElementById('modalAnchor') + ).then(async (adapter) => { + adapter.canEagerConnect().then((canEagerConnect) => { + setEager(canEagerConnect) + }) + + setAdapter(adapter) + }) + }) + + createEffect(() => { + if (eager()) { + adapter() + ?.connect() + .then( + async () => { + const accounts = await adapter()!.account() + setPublicKey(accounts.address) + console.log('connect resolved successfully') + }, + () => { + console.log('connect rejected') + } + ) + } + }) + + return ( +
+ Aptos Example +
+ { + adapter() + ?.connect() + .then( + async () => { + const accounts = await adapter()!.account() + setPublicKey(accounts.address) + console.log('connect resolved successfully') + }, + () => { + console.log('connect rejected') + } + ) + }}> + Connect + + }> +

Current address: {publicKey()}

+ + + +
+
+ ) +} diff --git a/sdk/build-only-packages.sh b/sdk/build-only-packages.sh index a0156192..b630c880 100644 --- a/sdk/build-only-packages.sh +++ b/sdk/build-only-packages.sh @@ -25,4 +25,6 @@ pnpm build cd ../selector-sui pnpm build cd ../selector-polkadot +pnpm build +cd ../selector-aptos pnpm build \ No newline at end of file diff --git a/sdk/packages/selector-aptos/package.json b/sdk/packages/selector-aptos/package.json index 2ebbfbd0..6ee8e708 100644 --- a/sdk/packages/selector-aptos/package.json +++ b/sdk/packages/selector-aptos/package.json @@ -1,6 +1,6 @@ { "name": "@nightlylabs/wallet-selector-aptos", - "version": "0.2.6", + "version": "0.0.1", "description": "", "type": "module", "exports": { @@ -31,7 +31,8 @@ "events": "^3.3.0", "@aptos-labs/wallet-adapter-core": "^3.0.0", "aptos": "^1.20.0", - "@nightlylabs/nightly-connect-base": "^0.0.27" + "@nightlylabs/nightly-connect-base": "^0.0.27", + "@nightlylabs/aptos-wallet-standard": "^0.0.3" }, "devDependencies": { "@rollup/plugin-commonjs": "^25.0.0", diff --git a/sdk/packages/selector-aptos/src/adapter.ts b/sdk/packages/selector-aptos/src/adapter.ts index bb813b83..8c7e67bc 100644 --- a/sdk/packages/selector-aptos/src/adapter.ts +++ b/sdk/packages/selector-aptos/src/adapter.ts @@ -9,17 +9,21 @@ import { clearRecentStandardWalletForNetwork, clearSessionIdForNetwork, getRecentStandardWalletForNetwork, + getWalletsList, isMobileBrowser, isStandardConnectedForNetwork, persistRecentStandardWalletForNetwork, + persistStandardConnectForNetwork, + persistStandardDisconnectForNetwork, sleep, triggerConnect } from '@nightlylabs/wallet-selector-base' -// import { suiWalletsFilter } from './detection' import { AccountInfo, AdapterPlugin, NetworkInfo, + OnAccountChange, + OnNetworkChange, SignMessagePayload, SignMessageResponse, Types, @@ -27,6 +31,7 @@ import { } from '@aptos-labs/wallet-adapter-core' import { AppAptos } from '@nightlylabs/nightly-connect-aptos' import { logoBase64 } from './icon' +import { aptosWalletsFilter } from './detection' export const AptosWalletName = 'Nightly Connect' as WalletName<'Nightly Connect'> export const APTOS_NETWORK = 'aptos' @@ -37,12 +42,10 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { icon: `data:image/${'svg+xml' | 'webp' | 'png' | 'gif'};base64,${string}` = logoBase64 readonly url = 'https://chromewebstore.google.com/detail/nightly/fiikommddbeccaoicoejoniammnalkfa?hl=en' - provider = undefined connected = false - connecting = false // Nightly connect fields private _app: AppAptos | undefined - // private _innerStandardAdapter: StandardWalletAdapter | undefined + private _innerStandardAdapter: AdapterPlugin | undefined private _loading = false private _modal: NightlyConnectSelectorModal | undefined private _appInitData: AppInitData @@ -73,7 +76,6 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { initOnConnect = false ) { this._connecting = false - this.connecting = false this.connected = false this._appInitData = appInitData this._eagerConnectForStandardWallets = eagerConnectForStandardWallets ?? true @@ -81,16 +83,20 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { this._initOnConnect = initOnConnect } - // version?: 'v1' | 'v2' | undefined - // providerName?: string | undefined - // provider: any - // deeplinkProvider?: ((data: { url: string }) => string) | undefined - // network: () => Promise - // signMessage(message: T): Promise { - // throw new Error('Method not implemented.') - // } - // onNetworkChange: OnNetworkChange - // onAccountChange: OnAccountChange + get provider(): any { + if (!this.connected) { + throw new Error('Wallet not connected') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + throw new Error('Not supported') + } + case ConnectionType.WalletStandard: { + return this._innerStandardAdapter?.provider + } + } + return + } public static initApp = async ( appInitData: AppInitData @@ -159,14 +165,14 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { ) const [app, metadataWallets] = await NightlyConnectAptosAdapter.initApp(appInitData) - + console.log({ metadataWallets }) adapter._app = app adapter._metadataWallets = metadataWallets - // adapter.walletsList = getWalletsList( - // metadataWallets, - // suiWalletsFilter, - // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined - // ) + adapter.walletsList = getWalletsList( + metadataWallets, + aptosWalletsFilter, + getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + ) return adapter } @@ -183,11 +189,11 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { ) => { const adapter = new NightlyConnectAptosAdapter(appInitData, eagerConnectForStandardWallets) - // adapter.walletsList = getWalletsList( - // [], - // suiWalletsFilter, - // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined - // ) + adapter.walletsList = getWalletsList( + [], + aptosWalletsFilter, + getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + ) adapter._modal = new NightlyConnectSelectorModal( adapter.walletsList, appInitData.url ?? 'https://nc2.nightly.app', @@ -206,11 +212,11 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { NightlyConnectAptosAdapter.initApp(appInitData).then(([app, metadataWallets]) => { adapter._app = app adapter._metadataWallets = metadataWallets - // adapter.walletsList = getWalletsList( - // metadataWallets, - // suiWalletsFilter, - // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined - // ) + adapter.walletsList = getWalletsList( + metadataWallets, + aptosWalletsFilter, + getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + ) adapter._loading = false }) @@ -232,11 +238,11 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { true ) - // adapter.walletsList = getWalletsList( - // [], - // suiWalletsFilter, - // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined - // ) + adapter.walletsList = getWalletsList( + [], + aptosWalletsFilter, + getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + ) adapter._modal = new NightlyConnectSelectorModal( adapter.walletsList, @@ -268,7 +274,6 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { if (this._initOnConnect) { this._connecting = true - this.connecting = true if (!this._app) { try { @@ -278,15 +283,14 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { this._app = app this._metadataWallets = metadataWallets - // this.walletsList = getWalletsList( - // metadataWallets, - // suiWalletsFilter, - // getRecentStandardWalletForNetwork(SUI_NETWORK) ?? undefined - // ) + this.walletsList = getWalletsList( + metadataWallets, + aptosWalletsFilter, + getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + ) } catch { if (!this._app) { this._connecting = false - this.connecting = false throw new Error('Wallet not ready') } } @@ -312,7 +316,6 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { } this._connecting = true - this.connecting = true } if (this._app.hasBeenRestored() && this._app.connectedPublicKeys.length > 0) { @@ -324,7 +327,6 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { this._account = keys[0] this.connected = true this._connecting = false - this.connecting = false this._connectionType = ConnectionType.Nightly resolve(this._account) return @@ -335,7 +337,7 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { recentName !== null && isStandardConnectedForNetwork(APTOS_NETWORK) ) { - // await this.connectToStandardWallet(recentName, resolve) + await this.connectToStandardWallet(recentName, resolve) return } @@ -346,13 +348,9 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { } else { clearRecentStandardWalletForNetwork(APTOS_NETWORK) } - e.accounts - - // this._accounts = e.publicKeys.map((pk) => createSuiWalletAccountFromString(pk)) this._account = e.accounts[0] this.connected = true this._connecting = false - this.connecting = false this._connectionType = ConnectionType.Nightly this._modal?.closeModal() resolve(this._account) @@ -364,14 +362,12 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { }) if (!this._modal) { this._connecting = false - this.connecting = false reject(new Error('Wallet not ready')) } // _modal is defined here this._modal!.onClose = () => { if (this._connecting) { this._connecting = false - this.connecting = false const error = new Error('Connection cancelled') reject(error) } @@ -384,21 +380,18 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { ) { this.connectToMobileWallet(walletName) } else { - // this.connectToStandardWallet(walletName, resolve) + this.connectToStandardWallet(walletName, resolve) } }) // If modal is not opened, reject // This might be caused by SSR if (!opened) { this._connecting = false - this.connecting = false const error = new Error('Failed to open modal') reject(error) } } catch (error: unknown) { this._connecting = false - this.connecting = false - reject(error) } } @@ -416,27 +409,25 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { clearSessionIdForNetwork(APTOS_NETWORK) // Refresh app session this._app = await AppAptos.build(this._appInitData) - break } case ConnectionType.WalletStandard: { - // if (this._innerStandardAdapter) { - // await this._innerStandardAdapter.disconnect() - // persistStandardDisconnectForNetwork(APTOS_NETWORK) - // this.walletsList = getWalletsList( - // this._metadataWallets, - // suiWalletsFilter, - // getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined - // ) - // } + if (this._innerStandardAdapter) { + await this._innerStandardAdapter.disconnect() + persistStandardDisconnectForNetwork(APTOS_NETWORK) + this.walletsList = getWalletsList( + this._metadataWallets, + aptosWalletsFilter, + getRecentStandardWalletForNetwork(APTOS_NETWORK) ?? undefined + ) + } break } } - // this._innerStandardAdapter = undefined + this._innerStandardAdapter = undefined this._connectionType = undefined this.connected = false this._connecting = false - this.connecting = false this._account = undefined } async account(): Promise { @@ -455,16 +446,38 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { return this._app!.networkInfo } case ConnectionType.WalletStandard: { - throw 'not implemented' + return this._innerStandardAdapter!.network as NetworkInfo } } throw 'Should not happen' } - async onNetworkChange(callback: any): Promise { - throw 'not implemented' + async onNetworkChange(callback: Parameters[0]): Promise { + if (!this.connected) { + throw new Error('Wallet not connected') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + throw new Error('Not supported') + } + case ConnectionType.WalletStandard: { + return this._innerStandardAdapter!.onNetworkChange(callback) + } + } + throw 'Should not happen' } - async onAccountChange(callback: any): Promise { - throw 'not implemented' + async onAccountChange(callback: Parameters[0]): Promise { + if (!this.connected) { + throw new Error('Wallet not connected') + } + switch (this._connectionType) { + case ConnectionType.Nightly: { + throw new Error('Not supported') + } + case ConnectionType.WalletStandard: { + return this._innerStandardAdapter!.onAccountChange(callback) + } + } + throw 'Should not happen' } async signAndSubmitTransaction( transaction: Types.TransactionPayload, @@ -478,7 +491,7 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { return await this._app.signAndSubmitTransaction(transaction, options) } case ConnectionType.WalletStandard: { - throw 'not implemented' + return await this._innerStandardAdapter!.signAndSubmitTransaction(transaction, options) } } } @@ -491,7 +504,7 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { return await this._app.signMessage(message) } case ConnectionType.WalletStandard: { - throw 'not implemented' + return await this._innerStandardAdapter!.signMessage(message) } } } @@ -605,41 +618,36 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { return } } - // connectToStandardWallet = async (walletName: string, onSuccess: () => void) => { - // try { - // if (this._modal) { - // this._modal.setStandardWalletConnectProgress(true) - // } - // const wallet = this.walletsList.find((w) => w.name === walletName) - // if (typeof wallet?.standardWallet === 'undefined') { - // throw new Error('Wallet not found') - // } - - // const adapter = new StandardWalletAdapter({ - // wallet: wallet.standardWallet - // } as StandardWalletAdapterConfig) - - // await adapter.connect() - - // persistRecentStandardWalletForNetwork(walletName, SUI_NETWORK) - // persistStandardConnectForNetwork(SUI_NETWORK) - // this._connectionType = ConnectionType.WalletStandard - // this._innerStandardAdapter = adapter - // this._accounts = (await adapter.getAccounts()).map((a) => a) - // this.connected = true - // this._connecting = false - // this.connecting = false - - // this._modal?.closeModal() - // onSuccess() - // } catch (e) { - // if (this._modal) { - // this._modal.setStandardWalletConnectProgress(false) - // } - // clearRecentStandardWalletForNetwork(SUI_NETWORK) - // this._connecting = false - // this.connecting = false - // throw e - // } - // } + connectToStandardWallet = async (walletName: string, onSuccess: (acc: AccountInfo) => void) => { + try { + if (this._modal) { + this._modal.setStandardWalletConnectProgress(true) + } + const wallet = this.walletsList.find((w) => w.name === walletName) + if (typeof wallet?.standardWallet === 'undefined') { + throw new Error('Wallet not found') + } + + const adapter = wallet.standardWallet as unknown as AdapterPlugin + + const account: AccountInfo = await adapter.connect() + + persistRecentStandardWalletForNetwork(walletName, APTOS_NETWORK) + persistStandardConnectForNetwork(APTOS_NETWORK) + this._connectionType = ConnectionType.WalletStandard + this._innerStandardAdapter = adapter + this.connected = true + this._connecting = false + + this._modal?.closeModal() + onSuccess(account) + } catch (e) { + if (this._modal) { + this._modal.setStandardWalletConnectProgress(false) + } + clearRecentStandardWalletForNetwork(APTOS_NETWORK) + this._connecting = false + throw e + } + } } diff --git a/sdk/packages/selector-aptos/src/detection.ts b/sdk/packages/selector-aptos/src/detection.ts index 51446e26..d84518b8 100644 --- a/sdk/packages/selector-aptos/src/detection.ts +++ b/sdk/packages/selector-aptos/src/detection.ts @@ -1,13 +1,5 @@ -// TODO -// import { Wallet } from '@wallet-standard/core' +import { type Wallet } from '@wallet-standard/core' +import { isWalletWithRequiredFeatureSet } from '@nightlylabs/aptos-wallet-standard' -// import { isWalletWithRequiredFeatureSet } from '@mysten/wallet-standard' - -// export const suiWalletsFilter = (wallet: Wallet) => { -// const is = isWalletWithRequiredFeatureSet(wallet, [ -// 'sui:signAndExecuteTransactionBlock', -// 'sui:signTransactionBlock' -// ]) -// return is -// } -// +export const aptosWalletsFilter = (wallet: Wallet) => + isWalletWithRequiredFeatureSet(wallet, ['aptos:signAndSubmitTransaction', 'aptos:signMessage']) diff --git a/sdk/pnpm-lock.yaml b/sdk/pnpm-lock.yaml index b32a4cae..c6114e04 100644 --- a/sdk/pnpm-lock.yaml +++ b/sdk/pnpm-lock.yaml @@ -201,6 +201,9 @@ importers: '@nightlylabs/nightly-connect-sui': specifier: 0.0.28 version: link:../sui + '@nightlylabs/wallet-selector-aptos': + specifier: 0.0.1 + version: link:../../packages/selector-aptos '@nightlylabs/wallet-selector-polkadot': specifier: 0.1.12 version: link:../../packages/selector-polkadot @@ -225,6 +228,9 @@ importers: '@solidjs/router': specifier: ^0.8.2 version: 0.8.2(solid-js@1.7.2) + aptos: + specifier: ^1.20.0 + version: 1.20.0 buffer: specifier: ^6.0.3 version: 6.0.3 @@ -652,6 +658,9 @@ importers: '@aptos-labs/wallet-adapter-core': specifier: ^3.0.0 version: 3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0) + '@nightlylabs/aptos-wallet-standard': + specifier: ^0.0.3 + version: 0.0.3(@aptos-labs/ts-sdk@0.0.7) '@nightlylabs/nightly-connect-aptos': specifier: 0.0.1 version: link:../../apps/aptos @@ -5211,6 +5220,17 @@ packages: dev: false optional: true + /@nightlylabs/aptos-wallet-standard@0.0.3(@aptos-labs/ts-sdk@0.0.7): + resolution: {integrity: sha512-LW4uxVJXK2quILUC8b2LEicfe/LxF29aS8B6i2BCCcOEWuBXxP8ghnmnRhq9uWMnS4fI+vIa2UIAJUJJA36U5w==} + dependencies: + '@aptos-labs/wallet-adapter-core': 3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0) + '@wallet-standard/core': 1.0.3 + aptos: 1.20.0 + transitivePeerDependencies: + - '@aptos-labs/ts-sdk' + - debug + dev: false + /@noble/curves@1.1.0: resolution: {integrity: sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==} dependencies: From 24068ea29ff429eabb6a353fb38dfa43a73dced3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?NB=F0=9F=98=88?= Date: Tue, 5 Dec 2023 12:21:09 +0100 Subject: [PATCH 3/4] bump v --- sdk/apps/aptos/src/app.ts | 4 ++-- sdk/packages/selector-aptos/package.json | 2 +- sdk/packages/selector-aptos/src/adapter.ts | 16 ++++++++++++---- sdk/packages/selector-aptos/src/detection.ts | 3 +-- sdk/pnpm-lock.yaml | 8 ++++---- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/sdk/apps/aptos/src/app.ts b/sdk/apps/aptos/src/app.ts index f08d28b7..b7229726 100644 --- a/sdk/apps/aptos/src/app.ts +++ b/sdk/apps/aptos/src/app.ts @@ -92,11 +92,11 @@ export class AppAptos extends EventEmitter { public hasBeenRestored = () => { return this.base.hasBeenRestored } - public get accountInfo() { + public get account() { const accountInfo: AccountInfo = JSON.parse(this.base.connectedPublicKeys[0]) return accountInfo } - public get networkInfo() { + public get network() { const networkInfo: NetworkInfo = JSON.parse(this.base.connectedMetadata!).networkInfo return networkInfo } diff --git a/sdk/packages/selector-aptos/package.json b/sdk/packages/selector-aptos/package.json index 6ee8e708..7ccd6efe 100644 --- a/sdk/packages/selector-aptos/package.json +++ b/sdk/packages/selector-aptos/package.json @@ -32,7 +32,7 @@ "@aptos-labs/wallet-adapter-core": "^3.0.0", "aptos": "^1.20.0", "@nightlylabs/nightly-connect-base": "^0.0.27", - "@nightlylabs/aptos-wallet-standard": "^0.0.3" + "@nightlylabs/aptos-wallet-standard": "^0.0.4" }, "devDependencies": { "@rollup/plugin-commonjs": "^25.0.0", diff --git a/sdk/packages/selector-aptos/src/adapter.ts b/sdk/packages/selector-aptos/src/adapter.ts index 8c7e67bc..8cd69e7b 100644 --- a/sdk/packages/selector-aptos/src/adapter.ts +++ b/sdk/packages/selector-aptos/src/adapter.ts @@ -431,11 +431,19 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { this._account = undefined } async account(): Promise { - if (this._account) { - return this._account - } else { + if (!this.connected) { throw new Error('Wallet not connected') } + switch (this._connectionType) { + case ConnectionType.Nightly: { + return this._app!.account + } + case ConnectionType.WalletStandard: { + // @ts-expect-error Aptos types suck + return this._innerStandardAdapter!.account + } + } + throw 'Should not happen' } async network(): Promise { if (!this.connected) { @@ -443,7 +451,7 @@ export class NightlyConnectAptosAdapter implements AdapterPlugin { } switch (this._connectionType) { case ConnectionType.Nightly: { - return this._app!.networkInfo + return this._app!.network } case ConnectionType.WalletStandard: { return this._innerStandardAdapter!.network as NetworkInfo diff --git a/sdk/packages/selector-aptos/src/detection.ts b/sdk/packages/selector-aptos/src/detection.ts index d84518b8..94946316 100644 --- a/sdk/packages/selector-aptos/src/detection.ts +++ b/sdk/packages/selector-aptos/src/detection.ts @@ -1,5 +1,4 @@ import { type Wallet } from '@wallet-standard/core' import { isWalletWithRequiredFeatureSet } from '@nightlylabs/aptos-wallet-standard' -export const aptosWalletsFilter = (wallet: Wallet) => - isWalletWithRequiredFeatureSet(wallet, ['aptos:signAndSubmitTransaction', 'aptos:signMessage']) +export const aptosWalletsFilter = (wallet: Wallet) => isWalletWithRequiredFeatureSet(wallet, []) diff --git a/sdk/pnpm-lock.yaml b/sdk/pnpm-lock.yaml index c6114e04..075cae52 100644 --- a/sdk/pnpm-lock.yaml +++ b/sdk/pnpm-lock.yaml @@ -659,8 +659,8 @@ importers: specifier: ^3.0.0 version: 3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0) '@nightlylabs/aptos-wallet-standard': - specifier: ^0.0.3 - version: 0.0.3(@aptos-labs/ts-sdk@0.0.7) + specifier: ^0.0.4 + version: 0.0.4(@aptos-labs/ts-sdk@0.0.7) '@nightlylabs/nightly-connect-aptos': specifier: 0.0.1 version: link:../../apps/aptos @@ -5220,8 +5220,8 @@ packages: dev: false optional: true - /@nightlylabs/aptos-wallet-standard@0.0.3(@aptos-labs/ts-sdk@0.0.7): - resolution: {integrity: sha512-LW4uxVJXK2quILUC8b2LEicfe/LxF29aS8B6i2BCCcOEWuBXxP8ghnmnRhq9uWMnS4fI+vIa2UIAJUJJA36U5w==} + /@nightlylabs/aptos-wallet-standard@0.0.4(@aptos-labs/ts-sdk@0.0.7): + resolution: {integrity: sha512-gBg3u4iYy4f1GR1/YdYeSCeT4Mtj6SbGjm3k/Sft9xtWGwlLyRSV9AzaZn3Pxf4zeq1NUfuOFttqVT6ln8nk+w==} dependencies: '@aptos-labs/wallet-adapter-core': 3.0.0(@aptos-labs/ts-sdk@0.0.7)(aptos@1.20.0) '@wallet-standard/core': 1.0.3 From 19bd9055705d417d79d74ca88fd5395bb75020fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?NB=F0=9F=98=88?= Date: Tue, 5 Dec 2023 14:06:44 +0100 Subject: [PATCH 4/4] fixes --- sdk/apps/aptos/src/utils.ts | 1 - sdk/apps/modal-example/src/routes/aptos.tsx | 44 ++++++++++----------- sdk/packages/selector-aptos/src/adapter.ts | 3 +- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/sdk/apps/aptos/src/utils.ts b/sdk/apps/aptos/src/utils.ts index d090b493..7c9c918d 100644 --- a/sdk/apps/aptos/src/utils.ts +++ b/sdk/apps/aptos/src/utils.ts @@ -8,7 +8,6 @@ import { import { SignMessageResponse } from '@aptos-labs/wallet-adapter-core' export type AppAptosInitialize = Omit - export const APTOS_NETWORK = 'Aptos' export const parseRequest = (request: RequestContent, sessionId: string): AptosRequest => { diff --git a/sdk/apps/modal-example/src/routes/aptos.tsx b/sdk/apps/modal-example/src/routes/aptos.tsx index 3b098b87..b7ca7a86 100644 --- a/sdk/apps/modal-example/src/routes/aptos.tsx +++ b/sdk/apps/modal-example/src/routes/aptos.tsx @@ -35,9 +35,13 @@ export default function Aptos() { adapter() ?.connect() .then( - async () => { - const accounts = await adapter()!.account() - setPublicKey(accounts.address) + async (a) => { + console.log(a) + + // const accounts = await adapter()!.account() + // console.log(accounts) + + setPublicKey(a.address) console.log('connect resolved successfully') }, () => { @@ -59,9 +63,10 @@ export default function Aptos() { adapter() ?.connect() .then( - async () => { - const accounts = await adapter()!.account() - setPublicKey(accounts.address) + async (a) => { + // const accounts = await adapter()!.account() + // console.log(accounts) + setPublicKey(a.address) console.log('connect resolved successfully') }, () => { @@ -76,23 +81,18 @@ export default function Aptos() {