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/
https://snapalgowallet.netlify.app/
npx mm-snap build
compiles the src folder into a functional version of the snap
npx mm-snap serve
Serves index.html on port 3000
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.
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': {} },
}]
})
}
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
}
}]
})
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
}
}]
})
returns the users current balance
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'getBalance',
parms:{
testnet: false
}
}]
})
returns the public address of the wallet
let address = await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'getAddress',
}]
})
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"
}
}]
})
displays the wallets algorand mnemonic in a secure metamask window
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'displayMnemonic'
}]
})
returns a list of javascript objects containing transaction data
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'getTransactions',
params:{
testnet: false
}
}]
})
returns a list of the current accounts assets
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'getAssets',
params:{
testnet: false
}
}]
})
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',
}]
})
returns the users current Account
returns the users current Account
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'getCurrentAccount',
}]
})
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',
}]
})
these functions are used ARC complient ways to sign arbitray transactions
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]
}
}]
})
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"]
}
}]
})
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]
}
}]
})
the functions are used to interact with algorand assets
opts into an algorand asset
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'assetOptIn'
params:{
assetIndex: int
}
}]
})
opts out of an algorand asset
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: ['npm:algorand', {
method: 'assetOptOut'
params:{
assetIndex: int
}
}]
})
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
}
}]
})
These functions are used to swap crypto between Algorand, Etherum, and Binance Smart Chain The ticker values are algo | eth | bsc
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;
}
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 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
}
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
}
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