# AccountV3

This is an opinionated, flexible, and audited tokenbound account implementation.

\
The full contract code of the AccountV3 can be found [**here**](https://github.com/horuslabsio/TBA/blob/v3/src/accountV3/accountV3.cairo)**.**

## <mark style="color:green;">What's new?</mark>

The AccountV3 comes with breaking changes as we no longer maintain compatibility with [SNIP-6](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-6.md).

It majorly focuses on flexibility and ease with integration, comprising of plug'n'play components which developers can utilize. More on this in the [component section](/contracts/components.md).

## Functions

### **Constructor**

The constructor function initializes certain parameters on deployment.

<pre class="language-rust"><code class="lang-rust">fn constructor(
    ref self: ContractState,
    token_contract: ContractAddress,
    token_id: u256,
    registry: ContractAddress,
<strong>    implementation_hash: felt252,
</strong>    salt: felt252
)
</code></pre>

#### **Parameters**

| Name                  | Type              | Description                     |
| --------------------- | ----------------- | ------------------------------- |
| `token_contract`      | `ContractAddress` | The address of the NFT          |
| `token_id`            | `u256`            | The NFT token ID                |
| `registry`            | `ContractAddress` | Tokenbound's canonical registry |
| `implementation_hash` | `felt252`         | AccountV3 implementation hash   |
| `salt`                | `felt252`         | for randomness                  |

### **ACCOUNTV3 IMPLEMENTATION**

### **`on_erc721_received`**

This function is called each time an NFT is received. Prevents ownership cycle.

```rust
fn on_erc721_received(
    self: @ContractState,
    operator: ContractAddress,
    from: ContractAddress,
    token_id: u256,
    data: Span<felt252>
) -> felt252;
```

### **`context`**

Context gives deployment details of the TBA. Will be needed for cross-chain compatibility (v4?).

```rust
fn context(self: @ContractState) -> (ContractAddress, felt252, felt252)
```

### **SIGNATORY IMPLEMENTATION**

### **`is_valid_signer`**

Checks if the signer is the owner or a permissioned address.

```rust
fn is_valid_signer(self: @ContractState, signer: ContractAddress) -> bool;
```

### **`is_valid_signature`**

Validates tokenbound account signatures.

```rust
fn is_valid_signature(
    self: @ContractState, hash: felt252, signature: Span<felt252>
) -> felt252;
```

### **EXECUTABLE IMPLEMENTATION**

### **`execute`**

Executes transactions on the TokenBound account. Checks caller is a valid signer and account is not locked.

```rust
fn execute(ref self: ContractState, mut calls: Array<Call>) -> Array<Span<felt252>>
```

### **UPGRADEABLE IMPLEMENTATION**

### **`upgrade`**

It upgrades the Token Bound Account by replacing with a `new_class_hash` . An account can only be upgraded by the owner and requires the account to be locked.

```rust
fn upgrade(ref self: ContractState, new_class_hash: ClassHash)
```

### **LOCKABLE IMPLEMENTATION**

### **`lock`**

Locks an account for a specified period of time which is measured in seconds. the function can only be called by a valid signer.

```rust
fn lock(ref self: ContractState, lock_until: u64)
```

### **`is_locked`**

Checks if an account is locked and returns true if it is locked and false if it is not. If the account is locked, it also returns the time left until the account is unlocked.

```rust
fn is_locked(self: @ContractState) -> (bool, u64)
```

### **PERMISSIONABLE IMPLEMENTATION**

### **`set_permission`**

Gives a set of specified addresses permission to execute from a tokenbound account, lock it etc. (Think guardians). Can also remove permissions by setting permissions to `false`.

```rust
fn set_permission(
    ref self: ContractState,
    permissioned_addresses: Array<ContractAddress>,
    permissions: Array<bool>
)
```

### **`has_permission`**

Checks if an address passed in is a `permissioned_address`. It returns true if permission has been set for the address, else it returns false.

```rust
fn has_permission(
    self: @ContractState, owner: ContractAddress, permissioned_address: ContractAddress
) -> bool; 
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tbaexplorer.com/contracts/accountv3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
