# Golang

## Core SDK - Golang

The XpansionChain Core SDK provides convenient access to XpansionChain's APIs and smart contracts to help projects build better web3 games and marketplaces.

💡ROLLUPS THIS SDK SUPPORTS

* XpansionChain

CONTENTS

* <mark style="color:blue;">Installation</mark>
* <mark style="color:blue;">Initialization</mark>
* <mark style="color:blue;">Get data (on assets, orders, past transactions, etc.)</mark>
* <mark style="color:blue;">Generating Stark (Layer 2) keys</mark>
* <mark style="color:blue;">Operations requiring user signatures</mark>
* <mark style="color:blue;">How do applications generate and use signers?</mark>
* <mark style="color:blue;">Contract requests</mark>
* <mark style="color:blue;">Smart contract autogeneration</mark>
* <mark style="color:blue;">Further documentation</mark>

***

📚SDK LINKS

* <mark style="color:blue;">SDK reference</mark>
* <mark style="color:blue;">Package reference</mark>
* <mark style="color:blue;">Code examples</mark>
* <mark style="color:blue;">Github repository</mark>

### Installation[​](https://docs.x.immutable.com/docs/sdks/core/golang#installation) <a href="#installation" id="installation"></a>

The supported go versions are 1.18 or above.

```
go get github.com/XpansionChain/imx-core-sdk-golang
```

### Initialization[​](https://docs.x.immutable.com/docs/sdks/core/golang#initialization) <a href="#initialization" id="initialization"></a>

Initialize the Core SDK client with the network on which you want your application to run (see <mark style="color:blue;">all networks available</mark>):

Select one of the following Ethereum networks XpansionChain platform currently supports.

| Environment | Description                                        |
| ----------- | -------------------------------------------------- |
| Sandbox     | The default test network (currently, it is Goërli) |
| Mainnet     | Ethereum network                                   |

```
import "github.com/XpansionChain/imx-core-sdk-golang/imx/api"

const alchemyAPIKey = "alchemy api key"

func main() {
    apiConfiguration := api.NewConfiguration()
    cfg := imx.Config{
        APIConfig:     apiConfiguration,
        AlchemyAPIKey: YOUR_ALCHEMY_API_KEY,
        Environment:   imx.Sandbox,
    }
    client, err := imx.NewClient(&cfg)
    if err != nil {
        log.Panicf("error in NewClient: %v\n", err)
    }
    defer c.EthClient.Close()
}
```

### Get data (on assets, orders, past transactions, etc.)[​](https://docs.x.immutable.com/docs/sdks/core/golang#get-data-on-assets-orders-past-transactions-etc) <a href="#get-data-on-assets-orders-past-transactions-etc" id="get-data-on-assets-orders-past-transactions-etc"></a>

These methods allow you to read data about events, transactions or current state on XpansionChain (layer 2). They do not require any user authentication because no state is being changed.

Examples of the types of data that are typically retrieved include:

* Assets or details of a particular asset
* Token balances for a particular user
* Orders or details about a particular order
* Historical trades and transfers

#### Examples[​](https://docs.x.immutable.com/docs/sdks/core/golang#examples) <a href="#examples" id="examples"></a>

**Get all collections and get assets from a particular collection:**[**​**](https://docs.x.immutable.com/docs/sdks/core/golang#get-all-collections-and-get-assets-from-a-particular-collection)

```
listCollectionsRequest := c.NewListCollectionsRequest(context.TODO())
listCollectionsRequest.PageSize(2)

listCollectionsResponse, err := c.ListCollections(&listCollectionsRequest)
if err != nil {
    log.Panicf("error in ListCollections: %v\n", err)
}

collection := listCollectionsResponse.Result[0]

listAssetsRequest := c.NewListAssetsRequest(context.TODO())
listAssetsRequest.Collection(collection.Address)
listAssetsRequest.PageSize(10)

listAssetsResponse, err := c.ListAssets(&listAssetsRequest)
if err != nil {
    log.Panicf("error in ListAssets: %v\n", err)
}
```

### Generating Stark (Layer 2) keys[​](https://docs.x.immutable.com/docs/sdks/core/golang#generating-stark-layer-2-keys) <a href="#generating-stark-layer-2-keys" id="generating-stark-layer-2-keys"></a>

Stark keys are required to transact on XpansionChain's StarkEx Layer 2. They are the equivalent of Ethereum keys on L1 and allow users to sign transactions like trade, transfer, etc.

#### Key registration[​](https://docs.x.immutable.com/docs/sdks/core/golang#key-registration) <a href="#key-registration" id="key-registration"></a>

On XpansionChain, the goal of generating a Stark key is to <mark style="color:blue;">register</mark> a mapping between the Stark public key and the user's Ethereum public key so that transactions requiring both L1 and L2 signers can be executed by users.

#### How to generate Stark keys on XpansionChain[​](https://docs.x.immutable.com/docs/sdks/core/golang#how-to-generate-stark-keys-on-immutablex) <a href="#how-to-generate-stark-keys-on-immutablex" id="how-to-generate-stark-keys-on-immutablex"></a>

XpansionChain provides two Stark key generation methods: | Type of Stark key generated: | User connection methods: | When to use this method: | XpansionChain tools: | | --- | --- | --- | --- | | <mark style="color:blue;">Deterministic</mark> - generated using the user's Ethereum key as a seed (which means that the same Ethereum key will always generate the same Stark key) | Users connect with their L1 wallet (ie. Metamask), as the L2 key can simply be obtained from the L1 key. | ***User experience*** - users don't have to store or remember Stark keys.\
\
\&#xNAN;***Interoperability*** - when generating Stark keys for a user, think about how else they will use these keys. If they will be connecting to other applications and those applications connect to users' Stark keys (L2 wallets) via an L1 wallet, then it is best that their Stark keys are generated using this method. | <mark style="color:blue;">Link SDK</mark>\
\
Core SDK's <mark style="color:blue;">`GenerateLegacyKey()`</mark> method | | <mark style="color:blue;">Random and non-reproducible</mark> - not generated from a user's Ethereum key | Once this Stark key is <mark style="color:blue;">registered</mark> on XpansionChain (mapped to an Ethereum key), the Stark key owner needs to know and input this.\
\
**🚨 NOTE:** If this key isn't persisted and stored by the user, it cannot be recovered and a new key cannot be re-registered. | ***Security*** - a Stark key generated using this method is completely independent of an Ethereum key, so the compromise of an Ethereum key does not compromise a user's corresponding Stark key.\
\
\&#xNAN;***Isolated use-case*** - this method is ideal for keys that are only used for one particular function, ie. in the backend of an application that allows tokens to be minted from a collection registered with this key. |\
\
Core SDK's <mark style="color:blue;">`GenerateKey()`</mark> method |

#### Generating or retrieving a deterministic key[​](https://docs.x.immutable.com/docs/sdks/core/golang#generating-or-retrieving-a-deterministic-key) <a href="#generating-or-retrieving-a-deterministic-key" id="generating-or-retrieving-a-deterministic-key"></a>

If your user has a Stark key that was generated using the deterministic method, the Core SDK provides a way for you to retrieve this key using the <mark style="color:blue;">`GenerateLegacyKey()`</mark> method:

```
import { AlchemyProvider } from '@ethersproject/providers';
import { Wallet } from '@ethersproject/wallet';
import { generateLegacyStarkPrivateKey } from '@imtbl/core-sdk';

// Create Ethereum signer
const ethNetwork = 'goerli'; // Or 'mainnet'
const provider = new AlchemyProvider(ethNetwork, YOUR_ALCHEMY_API_KEY);
const ethSigner = new Wallet(YOUR_PRIVATE_ETH_KEY).connect(provider);

// Get the legacy Stark private key
const starkPrivateKey = generateLegacyStarkPrivateKey(ethSigner);
```

#### Generating a random, non-deterministic key[​](https://docs.x.immutable.com/docs/sdks/core/golang#generating-a-random-non-deterministic-key) <a href="#generating-a-random-non-deterministic-key" id="generating-a-random-non-deterministic-key"></a>

The Core SDK also provides a way to generate a random, non-reproducible key using the <mark style="color:blue;">`GenerateKey()`</mark> method:

**🚨🚨🚨 Warning 🚨🚨🚨**[**​**](https://docs.x.immutable.com/docs/sdks/core/golang#-warning-)

> If you generate your own Stark private key, you will have to persist it. The key is <mark style="color:blue;">randomly generated</mark> so ***cannot*** be deterministically re-generated.

```
starkPrivateKey, err = stark.GenerateKey(l1signer)
if err != nil {
    log.Panicf("error in Generating Stark Private Key: %v\n", err)
}
```

### Operations requiring user signatures[​](https://docs.x.immutable.com/docs/sdks/core/golang#operations-requiring-user-signatures) <a href="#operations-requiring-user-signatures" id="operations-requiring-user-signatures"></a>

As XpansionChain enables applications to execute signed transactions on both Ethereum (layer 1) and StarkEx (layer 2), signers are required for both these layers. In order to generate an Ethereum or Stark signer, a user's Ethereum or Stark private key is required.

There are two types of operations requiring user signatures:

1. Transactions that update blockchain state
2. Operations that XpansionChain require authorization for

In order to get user signatures, applications need to <mark style="color:blue;">generate "signers"</mark>.

#### What are transactions that update blockchain state?[​](https://docs.x.immutable.com/docs/sdks/core/golang#what-are-transactions-that-update-blockchain-state) <a href="#what-are-transactions-that-update-blockchain-state" id="what-are-transactions-that-update-blockchain-state"></a>

A common transaction type is the transfer of asset ownership from one user to another (ie. asset sale). These operations require users to sign (approve) them to prove that they are valid.

#### What are operations that require authorization?[​](https://docs.x.immutable.com/docs/sdks/core/golang#what-are-operations-that-require-authorization) <a href="#what-are-operations-that-require-authorization" id="what-are-operations-that-require-authorization"></a>

These operations add to or update data in XpansionChain's databases and typically require the authorization of an object's owner (ie. a user creating a project on XpansionChain).

### How do applications generate and use signers?[​](https://docs.x.immutable.com/docs/sdks/core/golang#how-do-applications-generate-and-use-signers) <a href="#how-do-applications-generate-and-use-signers" id="how-do-applications-generate-and-use-signers"></a>

Signers are abstractions of user accounts that can be used to sign transactions. A user's private key is required to generate them.

There are two ways to get signers in your application:

1. <mark style="color:blue;">Generate your own by obtaining and using the user's private keys</mark>
2. <mark style="color:blue;">Use our Wallet SDK to connect to a user's wallet application</mark>

The first option, where an application obtains a user's private key directly, is risky because these keys allow anyone in possession of them full control of an account.

The second option provides an application with an interface to the user's account by prompting the user to connect with their wallet application (ie. mobile or browser wallet). Once connected the app can begin asking the user to sign transactions and messages without having to reveal their private key.

#### 1. Generate L1 and L2 signers[​](https://docs.x.immutable.com/docs/sdks/core/golang#1-generate-l1-and-l2-signers) <a href="#id-1-generate-l1-and-l2-signers" id="id-1-generate-l1-and-l2-signers"></a>

The Core SDK provides functionality for applications to generate Stark (L2) <mark style="color:blue;">signers.</mark>

```
apiConfiguration := api.NewConfiguration()
cfg := imx.Config{
    APIConfig:     apiConfiguration,
    AlchemyAPIKey: YOUR_ALCHEMY_API_KEY,
    Environment:   imx.Sandbox,
}

// Create Ethereum signer
l1signer, err := ethereum.NewSigner(YOUR_PRIVATE_ETH_KEY, cfg.ChainID)
if err != nil {
    log.Panicf("error in creating L1Signer: %v\n", err)
}

// Endpoints like Withdrawal, Orders, Trades, Transfers require an L2 (stark) signer
// Create Stark signer
l2signer, err := stark.NewSigner(YOUR_PRIVATE_STARK_KEY)
if err != nil {
    log.Panicf("error in creating StarkSigner: %v\n", err)
}
```

#### 2. Generate signers using the Wallet SDK[​](https://docs.x.immutable.com/docs/sdks/core/golang#2-generate-signers-using-the-wallet-sdk) <a href="#id-2-generate-signers-using-the-wallet-sdk" id="id-2-generate-signers-using-the-wallet-sdk"></a>

The <mark style="color:blue;">Wallet SDK Web</mark> provides connections to Metamask and WalletConnect browser wallets.

See <mark style="color:blue;">this guide</mark> for how to set this up.

#### Examples[​](https://docs.x.immutable.com/docs/sdks/core/golang#examples-1) <a href="#examples-1" id="examples-1"></a>

**Create a project (requires an Ethereum layer 1 signer)**[**​**](https://docs.x.immutable.com/docs/sdks/core/golang#create-a-project-requires-an-ethereum-layer-1-signer)

```
// Create a new project demo.
createProjectResponse, err := c.CreateProject(ctx, l1signer, "My Company", "Project name", "project@company.com")
if err != nil {
    log.Panicf("error in CreateProject: %v\n", err)
}

// Get the project details we just created.
projectId := strconv.FormatInt(int64(createProjectResponse.Id), 10)
getProjectResponse, err := c.GetProject(ctx, l1signer, projectId)
if err != nil {
    log.Panicf("error in GetProject: %v", err)
}
```

**Deposit tokens from L1 to L2 (requires an Ethereum layer 1 signer)**[**​**](https://docs.x.immutable.com/docs/sdks/core/golang#deposit-tokens-from-l1-to-l2-requires-an-ethereum-layer-1-signer)

```
// Eth Deposit
ethAmountInWei := uint(500000000000000000) // Amount in wei
depositResponse, err := imx.NewETHDeposit(ethAmountInWei).Deposit(ctx, c, l1signer, nil)
if err != nil {
    log.Panicf("error calling Eth deposit workflow: %v", err)
}
```

**Create an order (requires an Ethereum layer 1 and StarkEx layer 2 signer)**[**​**](https://docs.x.immutable.com/docs/sdks/core/golang#create-an-order-requires-an-ethereum-layer-1-and-starkex-layer-2-signer)

```
// The amount (listing price) should be in Wei for Eth tokens,
// see https://docs.starkware.co/starkex-v4/starkex-deep-dive/starkex-specific-concepts
// and https://eth-converter.com/
createOrderRequest := &api.GetSignableOrderRequest{
    AmountBuy:  strconv.FormatUint(amount, 10),
    AmountSell: "1",
    Fees:       nil,
    TokenBuy:   imx.SignableETHToken(),                         // The listed asset can be bought with 
    TokenSell:  imx.SignableERC721Token(tokenID, tokenAddress), // NFT Token
    User:       l1signer.GetAddress(),                          // Address of the user listing for sale.
}
createOrderRequest.SetExpirationTimestamp(0)

// Create order will list the given asset for sale.
createOrderResponse, err := c.CreateOrder(ctx, l1signer, l2signer, createOrderRequest)
if err != nil {
    log.Panicf("error in CreateOrder: %v", err)
}
```

### Contract requests[​](https://docs.x.immutable.com/docs/sdks/core/golang#contract-requests) <a href="#contract-requests" id="contract-requests"></a>

XpansionChain is built as a zkRollup (zero-knowledge rollup) in partnership with StarkWare. The choice of zkRollups is deliberate, as it offers unparalleled scalability without compromising security. This means the following:

* **Cost-effectiveness:** When you mint or trade an NFT on XpansionChain, you enjoy the advantage of zero gas fees.
* **Security:** All transactions are secured by zero-knowledge proofs, which makes XpansionChain the first ever layer 2 solution for NFTs on Ethereum.

The Core SDK provides an interface with the smart contracts necessary for interacting with the XpansionChain platform.

<mark style="color:blue;">See all smart contracts available in the Core SDK.</mark>

```
// This example is only to demonstrate using the generated smart contract clients
// We recommend using the Deposit method from https://github.com/XpansionChain/imx-core-sdk-golang/blob/69af5db9a0be05afd9c91c6b371547cfe3bea719/imx/deposit.go to deposit NFT
func DepositNft(l1signer XpansionChain.L1Signer, starkPublicKey, assetType, vaultID, tokenID *big.Int, overrides *bind.TransactOpts) (*types.Transaction, error) {
    apiConfiguration := api.NewConfiguration()
    cfg := imx.Config{
        APIConfig:     apiConfiguration,
        AlchemyAPIKey: YOUR_ALCHEMY_API_KEY,
        Environment:   imx.Sandbox,
    }
    client, err := imx.NewClient(&cfg)
    if err != nil {
        log.Panicf("error in NewClient: %v\n", err)
    }
    defer c.EthClient.Close()

    opts := c.buildTransactOpts(ctx, l1signer, overrides)
    transaction, err := client.CoreContract.DepositNft(opts, starkPublicKey, assetType, vaultID, tokenID)
    if err != nil {
        return nil, err
    }
    log.Println("transaction hash:", transaction.Hash())
    return transaction, nil
}
```

### Smart contract autogeneration[​](https://docs.x.immutable.com/docs/sdks/core/golang#smart-contract-autogeneration) <a href="#smart-contract-autogeneration" id="smart-contract-autogeneration"></a>

The XpansionChain Solidity contracts can be found in the `contracts` folder. Contract bindings in Golang are generated using <mark style="color:blue;">abigen.</mark>

| Contract         | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Core**         | The Core contract is XpansionChain's main interface with the Ethereum blockchain, based on <mark style="color:blue;">StarkEx.</mark>                                                                                                                                                                                                                                                                                                                              |
| **Registration** | <p>The Registration contract is a proxy smart contract for the Core contract that combines transactions related to onchain registration, deposits, and withdrawals.<br><br>When a user who is not registered onchain attempts to perform a deposit or a withdrawal, the Registration combines requests to the Core contract in order to register the user first.<br><br>Users who are not registered onchain are not able to perform a deposit or withdrawal.</p> |
| **IERC20**       | Standard interface for interacting with ERC20 contracts, taken from <mark style="color:blue;">OpenZeppelin.</mark>                                                                                                                                                                                                                                                                                                                                                |
| **IERC721**      | Standard interface for interacting with ERC721 contracts, taken from <mark style="color:blue;">OpenZeppelin.</mark>                                                                                                                                                                                                                                                                                                                                               |

### Further documentation[​](https://docs.x.immutable.com/docs/sdks/core/golang#further-documentation) <a href="#further-documentation" id="further-documentation"></a>

* See the <mark style="color:blue;">Developer homepage</mark> for general information on building on XpansionChain.
* Build on XpansionChain zkEVM:
  * <mark style="color:blue;">Documentation</mark>
  * <mark style="color:blue;">API reference</mark>
  * <mark style="color:blue;">Support</mark>
* Build on XpansionChain:
  * <mark style="color:blue;">Documentation</mark>
  * <mark style="color:blue;">API reference</mark>
  * <mark style="color:blue;">Support</mark>
