Getting Started With an External Wallet or Custom Signer

Halliday's SDK offers seamless integration for your existing wallets. You can pass in any non-custodial provider and it will be seemlessly integrated with our Smart Accounts.

📘

Smart Account VS External Wallet

When you integrate an external wallet with Halliday, your external wallet address is cryptographically mapped to a unique Smart Account address. The Smart Account is an ERC-4337 Smart Contract, where your external wallet is the sole authority on approving transactions that are sent from the Smart Account. The Smart Account is responsible for initiating transactions and securely storing your assets and tokens. All transactions made by the Smart Account must be approved from your external wallet before appearing on chain. Our SDK abstracts away the cryptographic authorization complexity behind this process, and allows you to conveniently use your existing wallet to authorize transactions through the Halliday Smart Account.

Please refer to our Frequently Asked Questions for more background on Wallets and Signers, and technicalities of how your external wallet is integrated with our Smart Accounts.

Every external wallet possesses the ability to cryptographically sign transactions and messages. This functionality is what is known as a signer. Many popular Web3 libraries, such as ethers.js, allow you to access that signer behind the wallet with minimal additional code. By passing that signer to the HallidayViaSigner client, you will be able to authenticate and approve transactions made from your Halliday Smart Account with that signer. Below, we will walk you through how to integrate your existing wallet with the Halliday SDK to fully manage your Halliday Smart Account.

Initialize the Halliday SDK with an External Signer

To connect your existing wallet and signer to your Halliday Smart Account, first install halliday-sdk:

npm install halliday-sdk

or

yarn add halliday-sdk

Below is an example of how to retrieve the signer with ethers.js from a wallet and how to use it to instantiate our SDK:

// To install ethers.js, run 'npm install ethers'
import ethers from "ethers";
import {HallidayViaSigner, BlockchainType} from "halliday-sdk";

// Create a random wallet with ethers.js, a popular Web3 library
const wallet = ethers.Wallet.createRandom();

// Get the signer for the wallet
const provider = ethers.getDefaultProvider();   // Replace with your RPC provider 
const signer = wallet.connect(provider);

// Initialize the Halliday client with the signer
const hallidayClient = new HallidayViaSigner({
  hallidayPublicApiKey: "API_KEY",
  signer: signer,
  blockchainType: BlockchainType.DFK,           // Specifying blockchainType is optional - defaults to Mumbai
  sandbox: true                                 // Optional argument. If true, makes the SDK interact with your test environment
});

// To get or create the Halliday Smart Account, call getOrCreateHallidayAAWallet. 
// This will get the user's smart account for the blockchain you specified in the constructor.
const userInGameId = "user_in_game_id";         // The user's id in your application. Must be unique for each user.
const hallidayAccount = await hallidayClient.getOrCreateHallidayAAWallet(
  userInGameId,					
  "[email protected]"
);
const hallidayAccountAddress = hallidayAccount.account_address;

// Log out!
await hallidayClient.logOut();

View Assets in the Smart Account

Once you have access to your Halliday Smart Account with your external wallet, you can view assets and balances in the smart account as demonstrated below:

// Get NFTs in the Halliday Smart Account.
const assets = await hallidayClient.getAssets(userInGameId);

// Get ERC20 balances in the Halliday Smart Account.
const balances = await hallidayClient.getBalances(userInGameId);

Create a transferAsset Transaction

To transfer an ERC721 token from one account to another, you can construct and send the transaction as demonstrated below. The SDK will handle the transaction signing with your external wallet automatically.

// Transfer an NFT to a different user, with gas sponsored by the paymaster.
const transferAssetTxInfo = await hallidayClient.transferAsset({
  from_in_game_player_id: userInGameId,                                 // Your user's id in your application
  to_in_game_player_id: "other_player_id",                              // Other user's id in your application
  collection_address: "0xeeaf9e39057002eae4bea8bb4e65b01a9cfd59be",     // ERC721 token contract address
  token_id: "3988",                                                     // Token id to transfer
  sponsor_gas: true,                                                    // Send with gas sponsorship
});
console.log(transferAssetTxInfo.status, transferAssetTxInfo.on_chain_id);

Create a transferBalance Transaction

To transfer an ERC20 token or native token from one account to another, you can construct and send the transaction as demonstrated below. The SDK will handle the transaction signing with your external wallet automatically.

// Transfer an ERC20 to a different user, with gas sponsored by the paymaster.
const balanceTransferTxInfo = await hallidayClient.transferBalance({
  from_in_game_player_id: userInGameId,                         // Your user's id in your application
  to_in_game_player_id: "other_player_id",                      // Other user's id in your application
  token_address: "0x0799ea468f812e40dbabe77b381cac105da500cd",  // ERC20 token contract address
  value: "100000000000000000",                                  // Amount of token to transfer, in the lowest decimal demonition of the token
  sponsor_gas: true,                                            // Send with gas sponsorship
});
console.log(balanceTransferTxInfo.status, balanceTransferTxInfo.on_chain_id);

Create a Transaction to Call Any Smart Contract Function

To call any on-chain smart contract function, you can construct and send the transaction as demonstrated below. The SDK will handle the transaction signing with your external wallet automatically.

// Call an arbitrary contract.
const contractAddress = '0x1f6557356bfb310a556300a36fb18f54fb4791b1';
// The contract's ABI
const contractAbi = [...];                           // Replace with your contract's ABI
// Create an instance of the contract
const contract = new ethers.Contract(contractAddress, contractAbi, signer);
// Get the calldata for a contract call
const calldata = contract.interface.encodeFunctionData('someFunction', ['arg1', 'arg2']);

// Call the contract, with gas sponsored by the paymaster.
const contractCallTxInfo = await hallidayClient.callContract({
  from_in_game_player_id: userInGameId,              // Your user's id in your application
  target_address: contractAddress,
  value: "0",
  calldata,
  sponsor_gas: true,
});
console.log(contractCallTxInfo.status, contractCallTxInfo.on_chain_id);