Skip to content

paulfears/snapalgo

Repository files navigation

SNAPALGO

ALGORAND on MetaMask

SnapAlgo is an Algorand wallet built on metamask developmental snaps feature which allows code to be run in a secure execution enviroment inside the metamask extension itself. Because the feature is so new it is currently only available on Metamask Flask which can be found here https://metamask.io/flask/

Demo

snapalgo.io

example apps

simple wallet

https://snapalgowallet.netlify.app/

Simple Swap app

https://algoswap.netlify.app/

Useage

building

npx mm-snap build

compiles the src folder into a functional version of the snap

serving

npx mm-snap serve

Serves index.html on port 3000

sdk

It is possible to use an sdk to simplify using snapalgo. repository This creates a floating wallet on the dapp for better user experence. As well as creating an easier developer experence by not requiring the developer to call raw rpc functions.

Connect and Install

Add and Call the below function to connect to the wallet. If the user does not have the snap installed, but has metamask flask installed this code will automaticly install it for them. This code snippet can be added to any website with 0 depenancies otheer than metamask flask

async  function  connect () {
	await window.ethereum.request({
		method:  'wallet_enable',
		params: [{
			wallet_snap: { 'npm:algorand': {} },
		}]
	})
}

Calling RPC Methods

Below is an example call to the snap that transacts 1000 microalgos to an entered public address. Again this can be run with 0 dependency other than metamask flask

All methods can be called with the param: testnet: (bool) if the method does not depend on the testnet it is ignored if the method can be used with testnet, testnet is then used instead

const address = prompt("Please enter your recipient Address");
const  response = await  window.ethereum.request({
	method:  'wallet_invokeSnap',
	params: ['npm:algorand', {
		method:  'transfer',
		params:{
			testnet:  false,
			to:  address,
			amount:  1000
		}
	}]
})

Available RPC Methods


Account functions

These functions handle getting infomation about a users account, assets, balance, and history

displayBalance

Displays the users current balance in a metamask flask popup

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params:['npm:algorand',{
		method: 'displayBalance',
		params:{
			testnet: false
		}
	}]
})

getBalance

returns the users current balance

await window.ethereum.request({
	method:  'wallet_invokeSnap',
	params: ['npm:algorand', {
		method:  'getBalance',
		parms:{
			testnet:  false
		}
	}]
})

getAddress

returns the public address of the wallet

let address = await window.ethereum.request({
	method:  'wallet_invokeSnap',
	params: ['npm:algorand', {
		method:  'getAddress',
	}]
})

transfer

transfers a number of algos to a specified address

const address = prompt("Please enter your name");
const  response = await  window.ethereum.request({
	method:  'wallet_invokeSnap',
	params: ['npm:algorand', {
		method:  'transfer',
		params:{
			testnet:  false,
			to:  address,
			amount:  1000
			?note: "string"
		}
	}]
})

displayMnemonic

displays the wallets algorand mnemonic in a secure metamask window

await window.ethereum.request({
	method:  'wallet_invokeSnap',
	params: ['npm:algorand', {
		method:  'displayMnemonic'
	}]
})

getTransactions

returns a list of javascript objects containing transaction data

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'getTransactions',
		params:{
			testnet: false
		}
	}]
})

getAssets

returns a list of the current accounts assets

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'getAssets',
		params:{
			testnet: false
		}
	}]
})

get Accounts

returns an object containing all of the algorand accounts on a users metamask

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'getAccounts',
	}]
})

get Current Account

returns the users current Account

returns the users current Account
await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'getCurrentAccount',
	}]
})

set Current Account

sets the Users Current Account takes an algorand address as a parameter and throws an error if the address is not contained in the users wallet returns the users current Account

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'setCurrentAccount',
	}]
})

Arc Complience Functions

these functions are used ARC complient ways to sign arbitray transactions


signTxns

sign an array of WalletTransaction objects returns an array of signed b64 algorand transactions

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'signTxns'
		params:{
			txns:[WalletTransaction]
		}
	}]
})

postTxns

takes an array of b64 signed algorand transactions. Like the output of signTxns and sends them to the algorand blockchain.

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'postTxns'
		params:{
			stxns: ["b64SignedTxn"]
		}
	}]
})

signAndPostTxns

takes an array of WalletTransaction objects and signs then posts them to the algorand blockchain

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'signAndPostTxns'
		params:{
			txns: [WalletTransaction]
		}
	}]
})

Asset Functions

the functions are used to interact with algorand assets


assetOptIn

opts into an algorand asset

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'assetOptIn'
		params:{
			assetIndex: int
		}
	}]
})

assetOptOut

opts out of an algorand asset

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'assetOptOut'
		params:{
			assetIndex: int
		}
	}]
})

transferAsset

sends an algorand asset to another wallet that is opted into the given asset

await window.ethereum.request({
	method: 'wallet_invokeSnap',
	params: ['npm:algorand', {
		method: 'assetOptOut'
		params:{
			assetIndex: int
			to: "algorandAddress"
			amount: string
		}
	}]
})

swapping functions

These functions are used to swap crypto between Algorand, Etherum, and Binance Smart Chain The ticker values are algo | eth | bsc


get Minimum

get minimum input amount for a specific swap

    async function getMin(){
      const result = await ethereum.request({
        method: 'wallet_invokeSnap',
        params: [
          'npm:algorand', {
            method: 'getMin',
			params:{
            	from: 'eth' | 'bsc' | 'algo',
            	to: 'eth' | 'bsc' | 'algo',
			}
          }
        ]
      })
      return result;
    }

preSwap

Get infomation about a swap without actually swapping

	async function preSwap(){
		const result = await ethereum.request({
			method: 'wallet_invokeSnap',
			params: [
			'npm:algorand', {
				method: 'preSwap',
				params:{
					from: 'eth' | 'bsc' | 'algo',
					to: 'eth' | 'bsc' | 'algo',
					amount: Number(amount) //done in base units i.e. eth not wei
				}
			}
			]
		})
		return result
	}

swap

swap currencies this will automatically send send the required currency to the exchange and use the selected address to receive the cash uses changenow

	async function swap(){
		const result = await ethereum.request({
			method: 'wallet_invokeSnap',
			params: [
			'npm:algorand', {
				method: 'swap',
				params:{
					from: 'eth' | 'bsc' | 'algo',
					to: 'eth' | 'bsc' | 'algo',
					amount: Number(amount) //done in base units i.e. eth not wei
					email: String("[email protected]") //completely optional
				}
			}
			]
		})
		return result
	}

swapHistory

the method returns an array of swap objects that give info about a swap performed by a given wallet.

	async function swapHistory(){
		const result = await ethereum.request({
			method: 'wallet_invokeSnap',
			params: [
			'npm:algorand', {
				method: 'swapHistory',
			}
			]
		})
		return result
	}

getSwapStatus

this method returns a status object of swap given the swaps id that can be obtained from swap history

	async function swapHistory(){
		const result = await ethereum.request({
			method: 'wallet_invokeSnap',
			params: [
			'npm:algorand', {
				method: 'getSwapStatus',
				params:{
					id: 'changenowSwapID'
				}
			}
			]
		})
		return result
	}

More RPC methods to come