Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: implement the adena wallet provider #3

Merged
merged 9 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ node_modules
!.yarn/versions

# testing
/coverage
coverage

# Build files
build
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
"@types/eslint": "^9",
"@types/jest": "^29.5.12",
"@types/node": "^22.0.0",
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"@typescript-eslint/eslint-plugin": "^8.2.0",
"@typescript-eslint/parser": "^8.2.0",
"eslint": "^9.8.0",
"eslint-config-prettier": "^9.1.0",
"jest": "^29.7.0",
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/core/providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './wallet';
88 changes: 88 additions & 0 deletions packages/sdk/src/core/providers/wallet.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import {
AccountInfo,
BroadcastType,
SingTransaction,
TransactionData,
TransactionResult,
TransactionResultCommit,
TransactionResultSync,
WalletResponse,
} from '../types';

export interface WalletProvider {
isConnected: () => Promise<WalletResponse<void>>;

/**
* Establish a connection to your site from Adena
* @async
* @param {string} name - The name of the website requesting to connect
* @returns Original Adena response, useful to check if the site was already connected
*/
addEstablish: (name: string) => Promise<WalletResponse<void>>;

/**
* Fetch information about the current connected account
* @async
* @returns Original Adena response with the account information
*/
getAccount: () => Promise<WalletResponse<AccountInfo>>;

/**
* Switches the Adena network to the given chain ID
* @async
* @param {string} chainId - Chain ID
* @returns Nothing, throws an error if it fails
*/
switchNetwork: (chainId: string) => Promise<WalletResponse<void>>;

/**
* Add a custom network to Adena
* @async
* @param {string} chainId - Chain ID
* @param {string} chainName - Chain name
* @param {string} rpcUrl - Network RPC URL
* @returns Nothing, throws an error if it fails
*/
addNetwork: (chainId: string, chainName: string, rpcUrl: string) => Promise<WalletResponse<void>>;

/**
* Sign a transaction crafted by a web-app
* @async
* @param {ContractMessage[]} messages - Messages to send in the transaction
* @param {number} gasFee - Actual network fee to pay (in ugnot)
* @param {number} gasWanted - Gas limit (in ugnot)
* @param {string} memo - Transaction memo (tag)
* @returns {string} Encoded transaction
*/
signTransaction: (transactionData: TransactionData) => Promise<WalletResponse<SingTransaction>>;

/**
* Sign and broadcast a transaction crafted by a web-app
* @async
* @param {ContractMessage[]} messages - Messages to send in the transaction
* @param {number} gasFee - Actual network fee to pay (in ugnot)
* @param {number} gasWanted - Gas limit (in ugnot)
* @param {string} memo - Transaction memo (tag)
* @returns {BroadcastTxCommitResult} Result of the broadcast transaction
*/
broadcastTransaction: (
transactionData: TransactionData,
broadcastType?: BroadcastType
) => Promise<WalletResponse<TransactionResult | TransactionResultSync | TransactionResultCommit>>;

/**
* Add a listener on connected account changes
* @async
* @param {OnAccountChangeFunc} func - Function to call on a new event
* @returns Nothing, throws an error if it fails
*/
onChangeAccount: (callback: (address: string) => void) => void;

/**
* Add a listener on network changes
* @async
* @param {OnNetworkChangeFunc} func - Function to call on a new event
* @returns Nothing, throws an error if it fails
*/
onChangeNetwork: (callback: (chainId: string) => void) => void;
}
14 changes: 14 additions & 0 deletions packages/sdk/src/core/types/account.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export type AccountStatusType = 'ACTIVE' | 'IN_ACTIVE';

export type AccountInfo = {
accountNumber: string;
address: string;
coins: string;
chainId: string;
sequence: string;
status: AccountStatusType;
public_key: {
'@type': string;
value: string;
};
};
3 changes: 3 additions & 0 deletions packages/sdk/src/core/types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './wallet.types';
export * from './account.types';
export * from './transaction.types';
88 changes: 88 additions & 0 deletions packages/sdk/src/core/types/transaction.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { MsgAddPackage, MsgCall, MsgSend } from '@gnolang/gno-js-client';
import { MsgRun } from '@gnolang/gno-js-client/bin/proto/gno/vm';

export type MessageType = '/bank.MsgSend' | '/vm.m_call' | '/vm.m_addpkg' | '/vm.m_run';

export type MessageValue = MsgAddPackage | MsgCall | MsgSend | MsgRun;

export enum BroadcastType {
SYNC = 'SYNC',
COMMIT = 'COMMIT',
}

export type TransactionMessage = {
type: MessageType;
value: MessageValue;
};

export interface TransactionData {
messages: TransactionMessage[];
gasFee: number;
gasWanted: number;
memo?: string;
}

export interface SignTransactionData {
document: SignDocument;
signature: Signature;
}

export interface SignDocument {
msgs: TransactionMessage[];
fee: {
amount: { amount: string; denom: string }[];
gas: string;
};
chain_id: string;
memo: string;
account_number: string;
sequence: string;
}

export interface Signature {
pubKey: {
typeUrl: string;
value: string;
};
signature: string;
}

export interface SingTransaction {
encodedTransaction: string;
}

interface TransactionEvent {
'@type': string;
type: string;
attrs: Record<string, string>[];
pkg_path: string;
func: string;
}

interface TransactionResultResponseBase {
Error: { log: string } | null;
Data: string;
Events: TransactionEvent[];
Log: string;
Info: string;
}

interface TransactionResultResponse {
ResponseBase: TransactionResultResponseBase;
GasWanted: string;
GasUsed: string;
}

export interface TransactionResult {
hash: string;
}

export interface TransactionResultSync extends TransactionResult {
data?: string;
log?: string;
}

export interface TransactionResultCommit extends TransactionResult {
check_tx?: TransactionResultResponse;
deliver_tx?: TransactionResultResponse;
}
49 changes: 49 additions & 0 deletions packages/sdk/src/core/types/wallet.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export interface WalletResponse<D> {
code: number;
status: WalletResponseStatus;
type: WalletResponseType;
message: string;
data: D | null;
}

export enum WalletResponseStatus {
SUCCESS = 'success',
FAILURE = 'failure',
}

export type WalletResponseType = WalletResponseSuccessType | WalletResponseFailedType | WalletResponseRejectedType;

export enum WalletResponseSuccessType {
CONNECTION_SUCCESS = 'CONNECTION_SUCCESS',
GET_ACCOUNT_SUCCESS = 'GET_ACCOUNT_SUCCESS',
SIGN_SUCCESS = 'SIGN_SUCCESS',
ADD_NETWORK_SUCCESS = 'ADD_NETWORK_SUCCESS',
SWITCH_NETWORK_SUCCESS = 'SWITCH_NETWORK_SUCCESS',
TRANSACTION_SUCCESS = 'TRANSACTION_SUCCESS',
}

export enum WalletResponseFailedType {
NOT_CONNECTED = 'NOT_CONNECTED',
UNRESOLVED_TRANSACTION_EXISTS = 'UNRESOLVED_TRANSACTION_EXISTS',
INVALID_FORMAT = 'INVALID_FORMAT',
WALLET_LOCKED = 'WALLET_LOCKED',
ACCOUNT_MISMATCH = 'ACCOUNT_MISMATCH',
NO_ACCOUNT = 'NO_ACCOUNT',
TRANSACTION_FAILED = 'TRANSACTION_FAILED',
SIGN_FAILED = 'SIGN_FAILED',
ALREADY_CONNECTED = 'ALREADY_CONNECTED',
NETWORK_TIMEOUT = 'NETWORK_TIMEOUT',
REDUNDANT_CHANGE_REQUEST = 'REDUNDANT_CHANGE_REQUEST',
NETWORK_ALREADY_EXISTS = 'NETWORK_ALREADY_EXISTS',
UNADDED_NETWORK = 'UNADDED_NETWORK',
UNSUPPORTED_TYPE = 'UNSUPPORTED_TYPE',
UNEXPECTED_ERROR = 'UNEXPECTED_ERROR',
}
Comment on lines +25 to +41
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we unify those types in the future in a common package used by the main Adena repo and this SDK ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I would like to unify the types and responses.
If the SDK and wallet responses were separate, it wouldn't be a problem if the provider did the mapping for me, but I'd have to manage them separately and always consider what I'm missing.


export enum WalletResponseRejectedType {
TRANSACTION_REJECTED = 'TRANSACTION_REJECTED',
SIGN_REJECTED = 'SIGN_REJECTED',
CONNECTION_REJECTED = 'CONNECTION_REJECTED',
SWITCH_NETWORK_REJECTED = 'SWITCH_NETWORK_REJECTED',
ADD_NETWORK_REJECTED = 'ADD_NETWORK_REJECTED',
}
5 changes: 1 addition & 4 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
import { EMessageType } from './types';

export { EMessageType };
export * from './methods';
export * from './providers';
26 changes: 0 additions & 26 deletions packages/sdk/src/methods/events.ts

This file was deleted.

45 changes: 0 additions & 45 deletions packages/sdk/src/methods/general.ts

This file was deleted.

4 changes: 0 additions & 4 deletions packages/sdk/src/methods/index.ts

This file was deleted.

45 changes: 0 additions & 45 deletions packages/sdk/src/methods/network.ts

This file was deleted.

Loading