# Endless Web Wallet SDK Usage Guide

## Installation

```bash
npm install @endlesslab/endless-ts-sdk
npm install @endlesslab/endless-web3-sdk
```

---

## Import Modules

```ts
import {
  Network,
  EntryFunctionABI,
  TypeTagAddress,
  TypeTagU128,
  AccountAddress,
  EndlessConfig,
  Endless,
  AccountAuthenticator,
  Hex,
  Deserializer,
  AccountAuthenticator
} from '@endlesslab/endless-ts-sdk';

import {
  EndlessJsSdk,
  UserResponseStatus,
  EndlessSignAndSubmitTransactionInput,
  EndlessWalletTransactionType,
  EndLessSDKEvent,
} from '@endlesslab/endless-web3-sdk';
```

---

## SDK Initialization

```ts
const jssdk = new EndlessJsSdk({
  // optional: Network.MAINNET
  network: Network.TESTNET,
  // optional: 'dark' | 'light'
  colorMode: 'dark'
});
```

---

## Wallet Connection

### Connect Wallet

```ts
const res = await jssdk.connect();
if (res.status === UserResponseStatus.APPROVED) {
  console.log('Account:', res.args.account);
}
```

### Disconnect Wallet

```ts
await jssdk.disconnect();
console.log('Disconnect success');
```

### Get Current Account

```ts
const res = await jssdk.getAccount();
if (res.status === UserResponseStatus.APPROVED) {
  console.log('Current account:', res.args.account);
}
```

---

## Signing Features

### Sign Message
```ts
signMessage({
  nonce: 1,
  message: 'Welcome to dapp!'
})
```
This would generate the `fullMessage` to be signed and returned as the `signature`:
```ts
Endless::Message
message: Welcome to dapp!
nonce: 1
```
```ts
export interface EndlessSignMessageInput {
  address?: boolean; // Should we include the address of the account in the message
  application?: boolean; // Should we include the domain of the dapp
  chainId?: boolean; // Should we include the current chain id the wallet is connected to
  message: string; // The message to be signed and displayed to the user
  nonce: string; // A nonce the dapp should generate
}
 
export interface EndlessSignMessageOutput {
  address: string;
  application: string;
  chainId: number;
  fullMessage: string; // The message that was generated to sign
  message: string; // The message passed in by the user
  nonce: string;
  prefix: string; // Should always be Endless::Message
  signature: string; // The signed full message
}

const signMessage = 'Welcome to dapp!';
const res = await jssdk.signMessage({
  address: true, // optional: include address in message
  application: true, // optional: include application in message
  chainId: true, // optional: include chainId in message
  message: signMessage,
  nonce: '1'
});
if (res.status === UserResponseStatus.APPROVED) {
  console.log(res.args);
}
```

### Sign and Submit Transaction

```ts
const toAccountAddress = 'xxx';
const transferAmount = 1;
const abi: EntryFunctionABI = {
  typeParameters: [],
  parameters: [new TypeTagAddress(), new TypeTagU128()],
};

const txData: EndlessSignAndSubmitTransactionInput = {
  payload: {
    function: '0x1::endless_account::transfer',
    functionArguments: [
      AccountAddress.fromBs58String(toAccountAddress),
      BigInt(Number(transferAmount) * 1e8),
    ],
    abi,
  },
  // options (optional)
  // This parameter is optional and can be omitted in most cases.
  /* options: {
    maxGasAmount: 100,
    gasUnitPrice: 100,
    expireTimestamp: Math.floor(Date.now() / 1000 + 20),
    accountSequenceNumber: 0
  } */
};

const res = await jssdk.signAndSubmitTransaction(txData);
if (res.status === UserResponseStatus.APPROVED) {
  console.log('Transaction submitted:', res);
}
```

### With Generic Type (typeArguments Required)

If the function uses generics, `typeArguments` must be provided:

```ts
const coinAddress = 'xxx';
const txData: EndlessSignAndSubmitTransactionInput = {
  payload: {
    function: '0x1::endless_account::transfer_coins',
    functionArguments: [
      AccountAddress.fromBs58String(toAccountAddress),
      BigInt(Number(transferAmount) * 1e8),
      coinAddress,
    ],
    typeArguments: ['0x1::fungible_asset::Metadata'],
  },
};

const res = await jssdk.signAndSubmitTransaction(txData);
console.log('transactionRes:', res);
```

### Sign Transaction Only (Without Submit)

```ts
const config = new EndlessConfig({ network: Network.TESTNET });
const endless = new Endless(config);

const abi: EntryFunctionABI = {
  typeParameters: [],
  parameters: [new TypeTagAddress(), new TypeTagU128()],
};

const txData: EndlessSignAndSubmitTransactionInput = {
  payload: {
    function: '0x1::endless_account::transfer',
    functionArguments: [
      AccountAddress.fromBs58String(toAccountAddress),
      BigInt(Number(transferAmount) * 1e8),
    ],
    abi,
  },
};

const txn = await endless.transaction.build.simple({
  sender: accountAddress,
  data: txData.payload,
});
const hexTxn = txn.bcsToHex().toString();
const res = await jssdk.signTransaction(hexTxn, EndlessWalletTransactionType.SIMPLE);
if (res.status === UserResponseStatus.APPROVED) {
  const data = Hex.fromHexString(res.args.data).toUint8Array();
  const deserializer = new Deserializer(data);
  const auth = AccountAuthenticator.deserialize(deserializer);
  console.log('AccountAuthenticator:', auth);
}
```

---
## Change Network

```ts
jssdk.changeNetwork({
  network: Network.MAINNET,
});
```
---

## Change Color Mode (Dark / Light)

```ts
jssdk.setWalletColorMode({ colorMode: 'dark' });
jssdk.setWalletColorMode({ colorMode: 'light' });
```
---

## Event Listeners

```ts
jssdk.on(EndLessSDKEvent.CONNECT, (res) => {
  console.log('Wallet connected:', res);
});

jssdk.on(EndLessSDKEvent.DISCONNECT, (res) => {
  console.log('Wallet disconnected:', res);
});

jssdk.on(EndLessSDKEvent.ACCOUNT_CHANGE, (res) => {
  if (res.account) {
    console.log('Account changed:', res);
  }
});

jssdk.on(EndLessSDKEvent.NETWORK_CHANGE, (networkInfo) => {
  console.log('Network changed:', networkInfo);
});

jssdk.on(EndLessSDKEvent.COLOR_MODE_CHANGE, (res) => {
  console.log('Color Mode Change:', res);
});
```

---

## Optional: UI Panel Open/Close Events

```ts
const openHandler = () => {};
jssdk.on(EndLessSDKEvent.OPEN, openHandler);
jssdk.off(EndLessSDKEvent.OPEN, openHandler);

const closeHandler = () => {};
jssdk.on(EndLessSDKEvent.CLOSE, closeHandler);
jssdk.off(EndLessSDKEvent.CLOSE, closeHandler);
```

---

## Notes

* All amounts are assumed to be in smallest unit (e.g., 1 EDS = 1e8 units).
* If ABI is not passed, the SDK will try to auto-resolve it. But if the contract function uses generics, you must pass `typeArguments` manually.
* Make sure `accountAddress`, `toAccountAddress`, and `transferAmount` are correctly set before performing transactions.
* The SDK supports multiple wallet events and operations; use `.on()` and `.off()` to bind/unbind custom handlers.
* Color mode can be configured at initialization or dynamically via `setWalletColorMode()`.
* To override a user-customized color mode, remove the `ENDLESS_WALLET_WEB3_SDK_ENABLETHEME_TOGGLE_KEY` from `localStorage` before calling `setWalletColorMode()`.
```ts
import { ENDLESS_WALLET_WEB3_SDK_ENABLETHEME_TOGGLE_KEY } from '@endlesslab/endless-web3-sdk';

localStorage.removeItem(ENDLESS_WALLET_WEB3_SDK_ENABLETHEME_TOGGLE_KEY);
jssdk.setWalletColorMode({ colorMode: 'light' });
````
