Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
paulfears committed Aug 8, 2023
1 parent 59c8e68 commit 38ed6a9
Show file tree
Hide file tree
Showing 12 changed files with 1,862 additions and 990 deletions.
27 changes: 26 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</head>

<body>
<h1>Hello, Snaps!</h1>
<h1>Stellar On Metamask!</h1>
<details>
<summary>Instructions</summary>
<ul>
Expand All @@ -28,6 +28,10 @@ <h1>Hello, Snaps!</h1>
<button class="sendHello">get Address</button>
<button class="fund">fundAccount</button>
<button class="getAccount">get Account info</button>
<br>
<input value="GC4FIQFSE66E4HR7D4QCSHKMS6M7LKKYPP72ICY5WYLCEJVHGBZAKQJK" id="recepient"/>
<input type="number" id="amount"/>
<button id="send">send</button>
</body>

<script>
Expand All @@ -37,11 +41,13 @@ <h1>Hello, Snaps!</h1>
const sendButton = document.querySelector('button.sendHello')
const fundButton = document.querySelector('button.fund')
const getAccountButton = document.querySelector('button.getAccount')
const sendTxnButton = document.getElementById('send');

connectButton.addEventListener('click', connect)
sendButton.addEventListener('click', send)
getAccountButton.addEventListener('click', getAccount)
fundButton.addEventListener('click', fund)
sendTxnButton.addEventListener('click', sendTxn)

// here we get permissions to interact with and install the snap
async function connect () {
Expand All @@ -68,6 +74,23 @@ <h1>Hello, Snaps!</h1>
alert('Problem happened: ' + err.message || err)
}
}

async function sendTxn(){
console.log("send transaction called");
const recepient = document.getElementById("recepient").value;
const amount = document.getElementById("amount").value;
const response = await ethereum.request({
method: 'wallet_invokeSnap',
params: {snapId:snapId, request:{
method: 'transfer',
params:{
to: recepient,
amount: amount
}
}}
})
console.log(response);
}
async function fund () {
try {
const addr = await ethereum.request({
Expand All @@ -92,11 +115,13 @@ <h1>Hello, Snaps!</h1>
}}
})
console.log(addr)
console.log(addr.balances[0])
alert(addr)
} catch (err) {
console.error(err)
alert('Problem happened: ' + err.message || err)
}
}

</script>
</html>
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@metamask/eslint-config-nodejs": "^8.0.0",
"@metamask/eslint-config-typescript": "^8.0.0",
"@metamask/snap-types": "^0.23.0",
"@metamask/snaps-cli": "^0.28.0",
"@metamask/snaps-cli": "^0.32.2",
"@typescript-eslint/eslint-plugin": "^5.19.0",
"@typescript-eslint/parser": "^5.19.0",
"eslint": "^7.30.0",
Expand All @@ -57,10 +57,11 @@
"registry": "https://registry.npmjs.org/"
},
"dependencies": {
"@metamask/snaps-ui": "^0.32.2",
"buffer": "^6.0.3",
"crc": "^4.3.2",
"nacl": "^0.1.3",
"soroban-client": "^0.4.0",
"stellar-base": "^9.0.0",
"tweetnacl": "^1.0.3"
}
}
8 changes: 6 additions & 2 deletions snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/MetaMask/template-typescript-snap.git"
},
"source": {
"shasum": "IhJrd87EMkGB+wQV+HaOHS0YEKHUuWWnsq3jeep17lA=",
"shasum": "8CMHGlXmEPOyc3pAOVHiv7APPGNWxWk+BipyVg6MlTA=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand All @@ -18,11 +18,15 @@
}
},
"initialPermissions": {
"snap_dialog": {},
"snap_notify": {},
"snap_manageState": {},
"endowment:rpc": {
"dapps": true,
"snaps": true
},
"snap_getEntropy": {}
"snap_getEntropy": {},
"endowment:network-access": {}
},
"manifestVersion": "0.1"
}
42 changes: 42 additions & 0 deletions src/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module.exports = {
env: {
es6: true,
},
parser: "@babel/eslint-parser",
extends: ["airbnb-base", "prettier"],
plugins: ["prettier", "prefer-import"],
rules: {
// OFF
"import/prefer-default-export": 0,
"node/no-unsupported-features/es-syntax": 0,
"node/no-unsupported-features/es-builtins": 0,
camelcase: 0,
"class-methods-use-this": 0,
"linebreak-style": 0,
"new-cap": 0,
"no-param-reassign": 0,
"no-underscore-dangle": 0,
"no-use-before-define": 0,
"prefer-destructuring": 0,
"lines-between-class-members": 0,

// WARN
"prefer-import/prefer-import-over-require": [1],
"no-console": ["warn", { allow: ["assert"] }],
"no-debugger": 1,
"no-unused-vars": 1,
"arrow-body-style": 1,
"valid-jsdoc": [
1,
{
requireReturnDescription: false,
},
],
"prefer-const": 1,
"object-shorthand": 1,
"require-await": 1,

// ERROR
"no-unused-expressions": [2, { allowTaggedTemplates: true }],
},
};
38 changes: 32 additions & 6 deletions src/Client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { wallet } from "./accounts";
import { Transaction } from "stellar-base";

export async function fund(wallet){
const response = await fetch(
Expand All @@ -14,18 +14,44 @@ export async function fund(wallet){
export class Client{
testNetURL:string
enpoint:string
wallet: wallet
constructor(wallet: wallet){
constructor(){
this.testNetURL = "https://horizon-testnet.stellar.org"
this.enpoint = this.testNetURL;
this.wallet = wallet;
}
async get(path){
console.log("here")
const response = await fetch(this.enpoint+'/'+path)
const json = await response.json()
return json
}
async getAccount(){
return await this.get(`accounts/${this.wallet.address}`);
async post(path){
console.log("here")
const response = await fetch(this.enpoint+'/'+path, {
method: "POST",
headers: {
'Accept': 'application/json'
}
})
const json = await response.json()
return json
}
async getAccount(address: string){
const data = await this.get(`accounts/${address}`);
console.log(data);
return data
}
async getBalance(address: string){
const info = await this.getAccount(address)
return info.balances[0].balance
}
async getSequence(address: string){
const info = await this.getAccount(address)
return info.sequence
}
async submitTransaction(transaction: Transaction){
const tx = encodeURIComponent(transaction.toEnvelope().toXDR().toString("base64"));
const path = `transactions?tx=${tx}`;
const response = await this.post(path);
return response;
}
}
72 changes: 72 additions & 0 deletions src/TxnBuilder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import {
Account,
FeeBumpTransaction,
Operation,
Transaction,
TransactionBuilder,
xdr,
Networks,
Asset
} from "stellar-base";
import { Client } from "./Client";

export class TxnBuilder{
account: Account
client: Client
constructor(account: Account){
this.account = account;
}

createAccountTxn(destination: string, amount: string, fee?:string): Transaction{
if(!fee){
console.log("no fee provided")
fee = "1000"
}

const transactionBuilder = new TransactionBuilder(this.account, {fee, networkPassphrase: Networks.TESTNET })
console.log("transaction initialized");
console.log(transactionBuilder);
transactionBuilder
.addOperation(Operation.createAccount({
destination: destination,
startingBalance: amount
})) // <- funds and creates destinationA
.setTimeout(30)
console.log(transactionBuilder);
const transaction = transactionBuilder.build();
console.log(transaction);
console.log(transaction.toXDR());
return transaction;
}

buildPaymentTxn(destination: string, amount: string, fee?:string): Transaction{
if(!fee){
console.log("no fee provided")
fee = "1000"
}

const transactionBuilder = new TransactionBuilder(this.account, {fee, networkPassphrase: Networks.TESTNET })
console.log("transaction initialized");
console.log(transactionBuilder);
transactionBuilder
/*
.addOperation(Operation.createAccount({
destination: destinationA,
startingBalance: "20"
})) // <- funds and creates destinationA
*/
.addOperation(Operation.payment({
destination: destination,
amount: amount,
asset: Asset.native()
})) // <- sends 100 XLM to destinationB
.setTimeout(30)
console.log(transactionBuilder);
const transaction = transactionBuilder.build();
console.log(transaction);
console.log(transaction.toXDR());
return transaction;
}


}
99 changes: 99 additions & 0 deletions src/Utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@


/*
Class for utility functions
wallet is a global in the metamask context
*/
import { panel, text, heading, divider, copyable, Panel } from '@metamask/snaps-ui';
export default class Utils {

static throwError(code, msg){
if(code === undefined){
code = 0
}
//metamask overrides Error codes
//This function encodes an arc complient error code
//into the error message, and is then seperated by the SDK
console.log(JSON.stringify(msg));
throw new Error(`${code}\n${msg}`);
}

static async notify(message: string): Promise<boolean>{
try{
await snap.request({
method: 'snap_notify',
params: {
type: 'inApp',
message: message,
},
});

const result = await snap.request({
method: 'snap_notify',
params: {
type: 'native',
message: message,
},
});
return true;
}
catch(e){
console.log("error - ")
console.log(e);
await Utils.sendConfirmation("alert", "notifcation", message);
return false;
}


}

static async sendConfirmation(prompt: string, description: string, textAreaContent: string): Promise<boolean>{
if(!textAreaContent){
textAreaContent = ""
}
const confirm= await snap.request({
method: 'snap_dialog',
params: {
type: 'confirmation',
content: panel([
heading(prompt),
divider(),
text(description),
divider(),
text(textAreaContent),
]),
},
});

return confirm;
}

static async sendAlert(title: string, info: string): Promise<boolean>{
const alert = await snap.request({
method: 'snap_dialog',
params:{
type: 'alert',
content: panel([
heading(title),
divider(),
text(info)
])
}
})
return true;
}

static async displayPanel(panel: Panel, type:"confirmation" | "alert" | "prompt" = "confirmation"): Promise<any>{
const disp = await snap.request({
method: 'snap_dialog',
params:{
type: type,
content: panel
}
})
return disp
}


}
Loading

0 comments on commit 38ed6a9

Please sign in to comment.