From 90d4fbaf9e46de2dc790036871c5583699809387 Mon Sep 17 00:00:00 2001 From: go7066 Date: Fri, 2 Feb 2024 20:43:05 +0800 Subject: [PATCH 01/12] support banker and grc20 together --- .../grc20_dynamic_call/registry/registry.gno | 78 ++++++++++++++----- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 21be84253df..3a4a4294a33 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -8,7 +8,7 @@ import ( const APPROVED_UNREGISTER_CALLER = "g1sqt92sa06ugh8nlt98kyghw83qy84paf4csyh6" -var registered = []GRC20Pair{} +var registered = []TokenInfo{} type GRC20Interface interface { Transfer() func(to users.AddressOrName, amount uint64) @@ -16,14 +16,15 @@ type GRC20Interface interface { BalanceOf() func(owner users.AddressOrName) uint64 } -type GRC20Pair struct { - pkgPath string - igrc20 GRC20Interface +type TokenInfo struct { + isBank bool + token string // token | denom + igrc20 GRC20Interface } -func findGRC20(pkgPath string) (int, bool) { +func findToken(token string) (int, bool) { for i, pair := range registered { - if pair.pkgPath == pkgPath { + if pair.token == token { return i, true } } @@ -32,11 +33,15 @@ func findGRC20(pkgPath string) (int, bool) { } func appendGRC20Interface(pkgPath string, igrc20 GRC20Interface) { - registered = append(registered, GRC20Pair{pkgPath: pkgPath, igrc20: igrc20}) + registered = append(registered, TokenInfo{isBank: false, token: pkgPath, igrc20: igrc20}) } -func removeGRC20Interface(pkgPath string) { - i, found := findGRC20(pkgPath) +func appendBankToken(denom string) { + registered = append(registered, TokenInfo{isBank: true, token: token}) +} + +func removeToken(token string) { + i, found := findToken(token) if !found { return } @@ -44,16 +49,16 @@ func removeGRC20Interface(pkgPath string) { registered = append(registered[:i], registered[i+1:]...) } -func RegisterGRC20Interface(pkgPath string, igrc20 GRC20Interface) { - _, found := findGRC20(pkgPath) +func RegisterGRC20Interface(token string, igrc20 GRC20Interface) { + _, found := findToken(token) if found { panic("GRC20 already registered") } - appendGRC20Interface(pkgPath, igrc20) + appendGRC20Interface(token, igrc20) } -func UnregisterGRC20Interface(pkgPath string) { +func UnregisterToken(token string) { // do not allow realm to unregister std.AssertOriginCall() caller := std.GetOrigCaller() @@ -62,40 +67,71 @@ func UnregisterGRC20Interface(pkgPath string) { panic("unauthorized") } - _, found := findGRC20(pkgPath) + _, found := findToken(token) if found { - removeGRC20Interface(pkgPath) + removeToken(token) } } -func TransferByInterfaceName(pkgPath string, to std.Address, amount uint64) bool { - i, found := findGRC20(pkgPath) +func RegisterBankToken(denom string) { + _, found := findToken(denom) + if found { + panic("Token already registered") + } + + appendBankToken(denom) +} + +func TransferByInterfaceName(token string, to std.Address, amount uint64) bool { + i, found := findToken(token) if !found { return false } + if registered[i].isBank { + banker := std.GetBanker(std.BankerTypeOrigSend) + + coin := std.Coins{{token, amount}} + realmAddr := std.GetOrigPkgAddr() + + // Send coin from realm + banker.SendCoins(realmAddr, to, coin) + return true + } registered[i].igrc20.Transfer()(users.AddressOrName(to), amount) return true } -func TransferFromByInterfaceName(pkgPath string, from, to std.Address, amount uint64) bool { - i, found := findGRC20(pkgPath) +func TransferFromByInterfaceName(token string, from, to std.Address, amount uint64) bool { + i, found := findToken(token) if !found { return false } + if registered[i].isBank { + panic("TransferFrom's not enabled for native token") + } registered[i].igrc20.TransferFrom()(users.AddressOrName(from), users.AddressOrName(to), amount) return true } -func BalanceOfByInterfaceName(pkgPath string, owner std.Address) uint64 { - i, found := findGRC20(pkgPath) +func BalanceOfByInterfaceName(token string, owner std.Address) uint64 { + i, found := findToken(token) if !found { return 0 } + if registered[i].isBank { + coins := banker.GetCoins(owner) + for _, coin := range coins { + if coin.denom == token { + return coin.amount + } + } + return 0 + } balance := registered[i].igrc20.BalanceOf()(users.AddressOrName(owner)) return balance } From 4d9e7cded403d2b83402626d5c1efbd44ff03ac3 Mon Sep 17 00:00:00 2001 From: go7066 Date: Fri, 2 Feb 2024 20:45:47 +0800 Subject: [PATCH 02/12] correct fields --- .../gno.land/r/x/grc20_dynamic_call/registry/registry.gno | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 3a4a4294a33..95ec4ee13ea 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -126,8 +126,8 @@ func BalanceOfByInterfaceName(token string, owner std.Address) uint64 { if registered[i].isBank { coins := banker.GetCoins(owner) for _, coin := range coins { - if coin.denom == token { - return coin.amount + if coin.Denom == token { + return coin.Amount } } return 0 From 4febc86f2af2496f6cbba7496051aa63b80ec039 Mon Sep 17 00:00:00 2001 From: go7066 Date: Fri, 2 Feb 2024 20:48:04 +0800 Subject: [PATCH 03/12] type conversion in balance getter, and update comments --- .../gno.land/r/x/grc20_dynamic_call/registry/registry.gno | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 95ec4ee13ea..4f6adf34744 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -18,8 +18,8 @@ type GRC20Interface interface { type TokenInfo struct { isBank bool - token string // token | denom - igrc20 GRC20Interface + token string // pkgPath (GRC20) | denom (Bank) + igrc20 GRC20Interface // only valid when isBank is false } func findToken(token string) (int, bool) { @@ -127,7 +127,7 @@ func BalanceOfByInterfaceName(token string, owner std.Address) uint64 { coins := banker.GetCoins(owner) for _, coin := range coins { if coin.Denom == token { - return coin.Amount + return uint64(coin.Amount) } } return 0 From bef4e6b546654e00620ec653a37f0d9162cb7ec8 Mon Sep 17 00:00:00 2001 From: go7066 Date: Wed, 7 Feb 2024 00:49:21 +0800 Subject: [PATCH 04/12] resolve issues in existing unit test and updated code --- .../gno.land/r/x/grc20_dynamic_call/registry/registry.gno | 5 +++-- .../r/x/grc20_dynamic_call/registry/registry_test.gno | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 4f6adf34744..c281a923357 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -37,7 +37,7 @@ func appendGRC20Interface(pkgPath string, igrc20 GRC20Interface) { } func appendBankToken(denom string) { - registered = append(registered, TokenInfo{isBank: true, token: token}) + registered = append(registered, TokenInfo{isBank: true, token: denom}) } func removeToken(token string) { @@ -91,7 +91,7 @@ func TransferByInterfaceName(token string, to std.Address, amount uint64) bool { if registered[i].isBank { banker := std.GetBanker(std.BankerTypeOrigSend) - coin := std.Coins{{token, amount}} + coin := std.Coins{{token, int64(amount)}} realmAddr := std.GetOrigPkgAddr() // Send coin from realm @@ -124,6 +124,7 @@ func BalanceOfByInterfaceName(token string, owner std.Address) uint64 { } if registered[i].isBank { + banker := std.GetBanker(std.BankerTypeOrigSend) coins := banker.GetCoins(owner) for _, coin := range coins { if coin.Denom == token { diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_test.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_test.gno index d835723095d..e9647f2ddb9 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_test.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_test.gno @@ -144,7 +144,7 @@ func TestTransferFromByNameBAZ(t *testing.T) { } func TestUnregisterUnauthorized(t *testing.T) { - shouldPanic(t, func() { UnregisterGRC20Interface("gno.land/r/x/grc20_dynamic_call/foo") }) + shouldPanic(t, func() { UnregisterToken("gno.land/r/x/grc20_dynamic_call/foo") }) } func TestUnregisterAuthorized(t *testing.T) { @@ -153,7 +153,7 @@ func TestUnregisterAuthorized(t *testing.T) { } std.TestSetOrigCaller("g1sqt92sa06ugh8nlt98kyghw83qy84paf4csyh6") - UnregisterGRC20Interface("gno.land/r/x/grc20_dynamic_call/foo") + UnregisterToken("gno.land/r/x/grc20_dynamic_call/foo") if len(registered) != 2 { t.Fatal("should have 2 registered interfaces") From 278555c7c311cecf2c0812755cc35de4e33bf3e1 Mon Sep 17 00:00:00 2001 From: go7066 Date: Wed, 7 Feb 2024 08:14:46 +0800 Subject: [PATCH 05/12] update to BankerTypeReadonly for balanceof --- examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index c281a923357..44b8031f52a 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -124,7 +124,7 @@ func BalanceOfByInterfaceName(token string, owner std.Address) uint64 { } if registered[i].isBank { - banker := std.GetBanker(std.BankerTypeOrigSend) + banker := std.GetBanker(std.BankerTypeReadonly) coins := banker.GetCoins(owner) for _, coin := range coins { if coin.Denom == token { From e8bbdd1b47f9216cc21b73476a0081fdc92113de Mon Sep 17 00:00:00 2001 From: go7066 Date: Tue, 13 Feb 2024 21:25:20 +0800 Subject: [PATCH 06/12] add further changes on registry --- .../grc20_dynamic_call/registry/registry.gno | 5 + .../registry/registry_teritori_testnet.sh | 108 ++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 44b8031f52a..03c835ac16b 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -82,6 +82,11 @@ func RegisterBankToken(denom string) { appendBankToken(denom) } +func RealmAddr() string { + realmAddr := std.GetOrigPkgAddr() + return realmAddr.String() +} + func TransferByInterfaceName(token string, to std.Address, amount uint64) bool { i, found := findToken(token) if !found { diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh new file mode 100644 index 00000000000..8df8ba9e098 --- /dev/null +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +gnokey add gopher +- addr: g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt + +gnokey add gopher2 +- addr: g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq + +TERITORI=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 +GOPHER=g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt + +# check balance +gnokey query bank/balances/$TERITORI -remote="51.15.236.215:26657" + +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/registry" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + teritori + +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/bar" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/bar_01" \ + teritori + +# Register Bank token +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -func="RegisterBankToken" \ + -args="ugnot" \ + teritori + +# # Set feeders +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ +# -func="SetFeeders" \ +# -args="$TERITORI" \ +# teritori + +# # Request Random Words +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ +# -func="RequestRandomWords" \ +# -args="1" \ +# teritori + +# # Fulfill Random Words +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ +# -func="FulfillRandomWords" \ +# -args="0" \ +# -args="f440c4980357d8b56db87ddd50f06bd551f1319a" \ +# teritori + +# # Query config +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +# RenderConfig()" -remote="51.15.236.215:26657" + +# # Query Requests +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +# RenderRequests(0, 10)" -remote="51.15.236.215:26657" + +# # Query request +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +# RenderRequest(0)" -remote="51.15.236.215:26657" + +# # Query IsFeeder +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +# IsFeeder(\"$TERITORI\")" -remote="51.15.236.215:26657" + +# # Query RandomValueFromWordsWithIndex +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +# RandomValueFromWordsWithIndex(0, 0)" -remote="51.15.236.215:26657" + +# Query RealmAddr +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +RealmAddr()" -remote="51.15.236.215:26657" From d06c28f07bce6e958a4e6c92f62f646e719937bc Mon Sep 17 00:00:00 2001 From: go7066 Date: Thu, 15 Feb 2024 23:38:36 +0800 Subject: [PATCH 07/12] add update on tokens registry test result --- .../registry/registry_teritori_testnet.sh | 171 ++++++++++++------ .../x/grc20_dynamic_call/wrapper/wrapper.gno | 8 +- 2 files changed, 119 insertions(+), 60 deletions(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh index 8df8ba9e098..0d41ff391e4 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh @@ -12,6 +12,17 @@ GOPHER=g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt # check balance gnokey query bank/balances/$TERITORI -remote="51.15.236.215:26657" +# Send 10 GNOT to realm address +gnokey maketx send \ + -send="10000000ugnot" \ + -to="g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + teritori + gnokey maketx addpkg \ -deposit="1ugnot" \ -gas-fee="1ugnot" \ @@ -46,63 +57,111 @@ gnokey maketx call \ -args="ugnot" \ teritori -# # Set feeders -# gnokey maketx call \ -# -gas-fee="1ugnot" \ -# -gas-wanted="5000000" \ -# -broadcast="true" \ -# -remote="51.15.236.215:26657" \ -# -chainid="teritori-1" \ -# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ -# -func="SetFeeders" \ -# -args="$TERITORI" \ -# teritori - -# # Request Random Words -# gnokey maketx call \ -# -gas-fee="1ugnot" \ -# -gas-wanted="5000000" \ -# -broadcast="true" \ -# -remote="51.15.236.215:26657" \ -# -chainid="teritori-1" \ -# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ -# -func="RequestRandomWords" \ -# -args="1" \ -# teritori - -# # Fulfill Random Words -# gnokey maketx call \ -# -gas-fee="1ugnot" \ -# -gas-wanted="5000000" \ -# -broadcast="true" \ -# -remote="51.15.236.215:26657" \ -# -chainid="teritori-1" \ -# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ -# -func="FulfillRandomWords" \ -# -args="0" \ -# -args="f440c4980357d8b56db87ddd50f06bd551f1319a" \ -# teritori - -# # Query config -# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -# RenderConfig()" -remote="51.15.236.215:26657" - -# # Query Requests -# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -# RenderRequests(0, 10)" -remote="51.15.236.215:26657" - -# # Query request -# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -# RenderRequest(0)" -remote="51.15.236.215:26657" - -# # Query IsFeeder -# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -# IsFeeder(\"$TERITORI\")" -remote="51.15.236.215:26657" - -# # Query RandomValueFromWordsWithIndex -# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -# RandomValueFromWordsWithIndex(0, 0)" -remote="51.15.236.215:26657" +# Register GRC20 token while deploying +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/bar" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/bar" \ + teritori + +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/foo" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ + teritori + +# Get Faucet +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ + -func="Faucet" \ + teritori + +# Transfer to realm +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ + -func="Transfer" \ + -args="g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u" \ + -args="5000000" \ + teritori + +# Deploy baz +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/baz" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/baz" \ + teritori + +# Deploy wrapper & register to registry +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/wrapper" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/wrapper" \ + teritori + +# Transfer ugnot (0.1GNOT to TERITORI) +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -func="TransferByInterfaceName" \ + -args="ugnot" \ + -args="$TERITORI" \ + -args="100000" \ + teritori + +# Transfer foo (0.1FOO to TERITORI) +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -func="TransferByInterfaceName" \ + -args="foo" \ + -args="$TERITORI" \ + -args="100000" \ + teritori # Query RealmAddr gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 RealmAddr()" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +BalanceOfByInterfaceName(\"ugnot\",\"g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +BalanceOfByInterfaceName(\"foo\",\"g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u\")" -remote="51.15.236.215:26657" diff --git a/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno b/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno index 6c81c9a6d2e..223c36ef364 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno @@ -7,7 +7,7 @@ import ( "gno.land/r/x/grc20_dynamic_call/baz" "gno.land/r/x/grc20_dynamic_call/foo" - "gno.land/r/x/grc20_dynamic_call/registry" + registry "gno.land/r/x/grc20_dynamic_call/registry_01" ) type FooTokenInterface struct{} @@ -59,7 +59,7 @@ func (BazTokenInterface) BalanceOf() func(owner users.AddressOrName) uint64 { var _ registry.GRC20Interface = BazTokenInterface{} func init() { - registry.RegisterGRC20Interface("gno.land/r/x/grc20_dynamic_call/foo", FooTokenInterface{}) - registry.RegisterGRC20Interface("gno.land/r/x/grc20_dynamic_call/bar", BarTokenInterface{}) - registry.RegisterGRC20Interface("gno.land/r/x/grc20_dynamic_call/baz", BazTokenInterface{}) + registry.RegisterGRC20Interface("foo", FooTokenInterface{}) + registry.RegisterGRC20Interface("bar", BarTokenInterface{}) + registry.RegisterGRC20Interface("baz", BazTokenInterface{}) } From 6951586b075b77832ef0dc6cf8c9dba75fef6759 Mon Sep 17 00:00:00 2001 From: go7066 Date: Wed, 21 Feb 2024 00:48:43 +0800 Subject: [PATCH 08/12] update origSend to realmSend perm --- .../grc20_dynamic_call/registry/registry.gno | 2 +- .../registry/registry_teritori_testnet.sh | 22 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 03c835ac16b..07c367cf1ba 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -94,7 +94,7 @@ func TransferByInterfaceName(token string, to std.Address, amount uint64) bool { } if registered[i].isBank { - banker := std.GetBanker(std.BankerTypeOrigSend) + banker := std.GetBanker(std.BankerTypeRealmSend) coin := std.Coins{{token, int64(amount)}} realmAddr := std.GetOrigPkgAddr() diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh index 0d41ff391e4..972c5f301ec 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh @@ -15,7 +15,7 @@ gnokey query bank/balances/$TERITORI -remote="51.15.236.215:26657" # Send 10 GNOT to realm address gnokey maketx send \ -send="10000000ugnot" \ - -to="g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u" \ + -to="g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5" \ -gas-fee="1ugnot" \ -gas-wanted="5000000" \ -broadcast="true" \ @@ -31,7 +31,7 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/registry" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ teritori gnokey maketx addpkg \ @@ -52,7 +52,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ -func="RegisterBankToken" \ -args="ugnot" \ teritori @@ -100,7 +100,7 @@ gnokey maketx call \ -chainid="teritori-1" \ -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ -func="Transfer" \ - -args="g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u" \ + -args="g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5" \ -args="5000000" \ teritori @@ -135,7 +135,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ -func="TransferByInterfaceName" \ -args="ugnot" \ -args="$TERITORI" \ @@ -149,7 +149,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_01" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ -func="TransferByInterfaceName" \ -args="foo" \ -args="$TERITORI" \ @@ -157,11 +157,11 @@ gnokey maketx call \ teritori # Query RealmAddr -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 RealmAddr()" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -BalanceOfByInterfaceName(\"ugnot\",\"g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u\")" -remote="51.15.236.215:26657" +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 +BalanceOfByInterfaceName(\"ugnot\",\"g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5\")" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_01 -BalanceOfByInterfaceName(\"foo\",\"g1zeqyg0q5e7m7sr3grzhsq7qpmqymx6uqatts0u\")" -remote="51.15.236.215:26657" +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 +BalanceOfByInterfaceName(\"foo\",\"g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5\")" -remote="51.15.236.215:26657" From 6d366d3a1a0a425d2cb26fcb47a461f130b2d01a Mon Sep 17 00:00:00 2001 From: go7066 Date: Thu, 22 Feb 2024 22:38:46 +0800 Subject: [PATCH 09/12] add updates on banker token management --- .../p/demo/teritori/token_registry/gno.mod | 1 + .../demo/teritori/token_registry/registry.gno | 174 ++++++++++++++++++ .../registry_teritori_testnet.sh | 145 +++++++++++++++ .../r/demo/teritori/escrow/escrow.gno | 46 ++++- examples/gno.land/r/x/README.md | 6 + .../grc20_dynamic_call/registry/registry.gno | 24 ++- .../registry/registry_teritori_testnet.sh | 57 +++--- 7 files changed, 421 insertions(+), 32 deletions(-) create mode 100644 examples/gno.land/p/demo/teritori/token_registry/gno.mod create mode 100644 examples/gno.land/p/demo/teritori/token_registry/registry.gno create mode 100644 examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh diff --git a/examples/gno.land/p/demo/teritori/token_registry/gno.mod b/examples/gno.land/p/demo/teritori/token_registry/gno.mod new file mode 100644 index 00000000000..e693ca7f95c --- /dev/null +++ b/examples/gno.land/p/demo/teritori/token_registry/gno.mod @@ -0,0 +1 @@ +module gno.land/p/demo/teritori/token_registry diff --git a/examples/gno.land/p/demo/teritori/token_registry/registry.gno b/examples/gno.land/p/demo/teritori/token_registry/registry.gno new file mode 100644 index 00000000000..99c09e46f0f --- /dev/null +++ b/examples/gno.land/p/demo/teritori/token_registry/registry.gno @@ -0,0 +1,174 @@ +package token_registry + +import ( + "std" + + "gno.land/r/demo/users" +) + +type Registry struct { + registered []TokenInfo + manager string +} + +func New(manager string) *Registry { + r := Registry{ + registered: []TokenInfo{}, + manager: manager, + } + return &r +} + +type GRC20Interface interface { + Transfer() func(to users.AddressOrName, amount uint64) + TransferFrom() func(from, to users.AddressOrName, amount uint64) + BalanceOf() func(owner users.AddressOrName) uint64 +} + +type TokenInfo struct { + isBank bool + token string // pkgPath (GRC20) | denom (Bank) + igrc20 GRC20Interface // only valid when isBank is false +} + +func (r Registry) findToken(token string) (int, bool) { + for i, pair := range r.registered { + if pair.token == token { + return i, true + } + } + + return -1, false +} + +func (r Registry) appendGRC20Interface(pkgPath string, igrc20 GRC20Interface) { + r.registered = append(r.registered, TokenInfo{isBank: false, token: pkgPath, igrc20: igrc20}) +} + +func (r Registry) appendBankToken(denom string) { + r.registered = append(r.registered, TokenInfo{isBank: true, token: denom}) +} + +func (r Registry) removeToken(token string) { + i, found := r.findToken(token) + if !found { + return + } + + r.registered = append(r.registered[:i], r.registered[i+1:]...) +} + +func (r Registry) RegisterGRC20Interface(token string, igrc20 GRC20Interface) { + _, found := r.findToken(token) + if found { + panic("GRC20 already registered") + } + + r.appendGRC20Interface(token, igrc20) +} + +func (r Registry) UnregisterToken(token string) { + // do not allow realm to unregister + std.AssertOriginCall() + caller := std.GetOrigCaller() + + if caller != r.manager { + panic("unauthorized") + } + + _, found := r.findToken(token) + if found { + r.removeToken(token) + } +} + +func (r Registry) RegisterBankToken(denom string) { + _, found := r.findToken(denom) + if found { + panic("Token already registered") + } + + r.appendBankToken(denom) +} + +func (r Registry) RealmAddr() string { + realmAddr := std.GetOrigPkgAddr() + return realmAddr.String() +} + +func (r Registry) TransferByInterfaceName(token string, to std.Address, amount uint64) bool { + i, found := r.findToken(token) + if !found { + return false + } + + if r.registered[i].isBank { + banker := std.GetBanker(std.BankerTypeRealmSend) + + coin := std.Coins{{token, int64(amount)}} + realmAddr := std.GetOrigPkgAddr() + + // Send coin from realm + banker.SendCoins(realmAddr, to, coin) + return true + } + r.registered[i].igrc20.Transfer()(users.AddressOrName(to), amount) + + return true +} + +func (r Registry) TransferFromByInterfaceName(token string, from, to std.Address, amount uint64) bool { + i, found := r.findToken(token) + if !found { + return false + } + + if r.registered[i].isBank { + coinSent := std.GetOrigSend() // get Coins sent with call + caller := std.GetOrigCaller() // get tx sender + + if len(coinSent) != 1 { + panic("only one coin can be sent") + } + + // if int64(amount) != coinSent.AmountOf(i.token) { + // panic("invalid amount sent") + // } + + if caller.String() != from { + panic("only caller should be configured for banker TransferFrom") + } + + realmAddr := std.GetOrigPkgAddr() + if to.String() != realmAddr.String() { + // Send coin from realm to target + banker := std.GetBanker(std.BankerTypeOrigSend) + coin := std.Coins{{token, int64(amount)}} + banker.SendCoins(realmAddr, to, coin) + } + return true + } + r.registered[i].igrc20.TransferFrom()(users.AddressOrName(from), users.AddressOrName(to), amount) + + return true +} + +func (r Registry) BalanceOfByInterfaceName(token string, owner std.Address) uint64 { + i, found := r.findToken(token) + if !found { + return 0 + } + + if r.registered[i].isBank { + banker := std.GetBanker(std.BankerTypeReadonly) + coins := banker.GetCoins(owner) + for _, coin := range coins { + if coin.Denom == token { + return uint64(coin.Amount) + } + } + return 0 + } + balance := r.registered[i].igrc20.BalanceOf()(users.AddressOrName(owner)) + return balance +} diff --git a/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh b/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh new file mode 100644 index 00000000000..ada6ea2eebd --- /dev/null +++ b/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh @@ -0,0 +1,145 @@ +#!/bin/sh + +gnokey add gopher +- addr: g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt + +gnokey add gopher2 +- addr: g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq + +TERITORI=g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5 +GOPHER=g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt + +# check balance +gnokey query bank/balances/$TERITORI -remote="51.15.236.215:26657" + +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/p/demo/teritori/token_registry" \ + -pkgpath="gno.land/p/demo/teritori/token_registry_02" \ + teritori + +# # Register Bank token +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ +# -func="RegisterBankToken" \ +# -args="ugnot" \ +# teritori + +# # Register GRC20 token while deploying +# gnokey maketx addpkg \ +# -deposit="1ugnot" \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/bar" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/bar" \ +# teritori + +# gnokey maketx addpkg \ +# -deposit="1ugnot" \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/foo" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ +# teritori + +# # Get Faucet +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ +# -func="Faucet" \ +# teritori + +# # Transfer to realm +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ +# -func="Transfer" \ +# -args="g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5" \ +# -args="5000000" \ +# teritori + +# # Deploy baz +# gnokey maketx addpkg \ +# -deposit="1ugnot" \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/baz" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/baz" \ +# teritori + +# # Deploy wrapper & register to registry +# gnokey maketx addpkg \ +# -deposit="1ugnot" \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/wrapper" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/wrapper" \ +# teritori + +# # Transfer ugnot (0.1GNOT to TERITORI) +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ +# -func="TransferByInterfaceName" \ +# -args="ugnot" \ +# -args="$TERITORI" \ +# -args="100000" \ +# teritori + +# # Transfer foo (0.1FOO to TERITORI) +# gnokey maketx call \ +# -gas-fee="1ugnot" \ +# -gas-wanted="5000000" \ +# -broadcast="true" \ +# -remote="51.15.236.215:26657" \ +# -chainid="teritori-1" \ +# -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ +# -func="TransferByInterfaceName" \ +# -args="foo" \ +# -args="$TERITORI" \ +# -args="100000" \ +# teritori + +# # Query RealmAddr +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 +# RealmAddr()" -remote="51.15.236.215:26657" + +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 +# BalanceOfByInterfaceName(\"ugnot\",\"g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5\")" -remote="51.15.236.215:26657" + +# gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 +# BalanceOfByInterfaceName(\"foo\",\"g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5\")" -remote="51.15.236.215:26657" diff --git a/examples/gno.land/r/demo/teritori/escrow/escrow.gno b/examples/gno.land/r/demo/teritori/escrow/escrow.gno index 0d9ada3e92b..28f7cebbdf8 100644 --- a/examples/gno.land/r/demo/teritori/escrow/escrow.gno +++ b/examples/gno.land/r/demo/teritori/escrow/escrow.gno @@ -6,8 +6,8 @@ import ( "strings" "time" + token_registry "gno.land/p/demo/teritori/token_registry_02" fmt "gno.land/p/demo/ufmt" - tori20 "gno.land/r/demo/tori20" "gno.land/r/demo/users" ) @@ -121,6 +121,7 @@ type Contract struct { // Escrow State var contracts []Contract +var token_reg = token_registry.New(CurrentRealm()) func CurrentRealm() string { return std.CurrentRealm().Addr().String() @@ -129,7 +130,7 @@ func CurrentRealm() string { func CreateContract( contractor string, funder string, - escrowToken string, // grc20 token + escrowToken string, metadata string, expiryDuration uint64, milestoneTitles string, @@ -219,7 +220,8 @@ func CreateContract( // If contract creator is funder then he needs to send all the needed fund to contract funded := false if caller.String() == funder { - tori20.TransferFrom( + token_reg.TransferFromByInterfaceName( + contract.escrowToken, users.AddressOrName(caller.String()), users.AddressOrName(std.CurrentRealm().Addr().String()), projectBudget) @@ -371,7 +373,8 @@ func PayPartialMilestone(contractId uint64, milestoneId uint64, amount uint64) { panic("could not pay more than milestone amount") } - tori20.Transfer( + token_reg.TransferByInterfaceName( + contract.escrowToken, users.AddressOrName(contract.contractor), amount) contracts[contractId].milestones[milestoneId].paid += amount @@ -417,7 +420,8 @@ func SubmitFunder(contractId uint64, fundingMilestoneIds string) { budget += milestone.amount } - tori20.TransferFrom( + token_reg.TransferFromByInterfaceName( + contract.escrowToken, users.AddressOrName(caller.String()), users.AddressOrName(std.CurrentRealm().Addr().String()), budget, @@ -514,7 +518,8 @@ func CompleteMilestoneAndPay(contractId uint64, milestoneId uint64) { // Pay the milestone unpaid := milestone.amount - milestone.paid if unpaid > 0 { - tori20.Transfer( + token_reg.TransferByInterfaceName( + contract.escrowToken, users.AddressOrName(contract.contractor), unpaid) contracts[contractId].milestones[milestoneId].paid += unpaid @@ -569,7 +574,8 @@ func ChangeMilestoneStatus(contractId uint64, milestoneId int, newStatus Milesto // Pay the milestone unpaid := milestone.amount - milestone.paid if unpaid > 0 { - tori20.Transfer( + token_reg.TransferByInterfaceName( + contract.escrowToken, users.AddressOrName(contract.contractor), unpaid) contracts[contractId].milestones[milestoneId].paid += unpaid @@ -601,7 +607,8 @@ func FundMilestone(contractId uint64, milestoneId uint64) { if milestone.funded { panic("milestone already funded") } - tori20.TransferFrom( + token_reg.TransferFromByInterfaceName( + contract.escrowToken, users.AddressOrName(caller.String()), users.AddressOrName(std.CurrentRealm().Addr().String()), milestone.amount) @@ -763,10 +770,12 @@ func CompleteContractByConflictHandler(contractId uint64, milestoneId uint64, co funderAmount := unpaidAmount - contractorAmount - tori20.Transfer( + token_reg.TransferByInterfaceName( + contract.escrowToken, users.AddressOrName(contract.contractor), contractorAmount) - tori20.Transfer( + token_reg.TransferByInterfaceName( + contract.escrowToken, users.AddressOrName(contract.funder), funderAmount) @@ -909,3 +918,20 @@ func RenderContracts(startAfter uint64, limit uint64, filterByFunder string, fil rendered += "]" return rendered } + +func RegisterGRC20Interface(token string, igrc20 GRC20Interface) { + token_reg.RegisterGRC20Interface(token, igrc20) +} + +func UnregisterToken(token string) { + token_reg.UnregisterToken(token) +} + +func RegisterBankToken(denom string) { + token_reg.RegisterBankToken(denom) +} + +func RealmAddr() string { + realmAddr := std.GetOrigPkgAddr() + return realmAddr.String() +} diff --git a/examples/gno.land/r/x/README.md b/examples/gno.land/r/x/README.md index a268ab0a9c0..6adb31ba7b6 100644 --- a/examples/gno.land/r/x/README.md +++ b/examples/gno.land/r/x/README.md @@ -17,3 +17,9 @@ its experimental nature. Feel free to explore, experiment, and contribute to the exciting developments happening in the `x/` directory. Together, we can shape the future of GnoVM. + +# Unit test + +``` +gno test examples/gno.land/r/x/grc20_dynamic_call/... +``` diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 07c367cf1ba..1212fb5f775 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -115,7 +115,29 @@ func TransferFromByInterfaceName(token string, from, to std.Address, amount uint } if registered[i].isBank { - panic("TransferFrom's not enabled for native token") + coinSent := std.GetOrigSend() // get Coins sent with call + caller := std.GetOrigCaller() // get tx sender + + if len(coinSent) != 1 { + panic("only one coin can be sent") + } + + // if int64(amount) != coinSent.AmountOf(i.token) { + // panic("invalid amount sent") + // } + + if caller.String() != from { + panic("only caller should be configured for banker TransferFrom") + } + + realmAddr := std.GetOrigPkgAddr() + if to.String() != realmAddr.String() { + // Send coin from realm to target + banker := std.GetBanker(std.BankerTypeOrigSend) + coin := std.Coins{{token, int64(amount)}} + banker.SendCoins(realmAddr, to, coin) + } + return true } registered[i].igrc20.TransferFrom()(users.AddressOrName(from), users.AddressOrName(to), amount) diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh index 972c5f301ec..bb3be8fedbc 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh @@ -12,17 +12,6 @@ GOPHER=g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt # check balance gnokey query bank/balances/$TERITORI -remote="51.15.236.215:26657" -# Send 10 GNOT to realm address -gnokey maketx send \ - -send="10000000ugnot" \ - -to="g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5" \ - -gas-fee="1ugnot" \ - -gas-wanted="5000000" \ - -broadcast="true" \ - -remote="51.15.236.215:26657" \ - -chainid="teritori-1" \ - teritori - gnokey maketx addpkg \ -deposit="1ugnot" \ -gas-fee="1ugnot" \ @@ -31,7 +20,7 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/registry" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ teritori gnokey maketx addpkg \ @@ -52,7 +41,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ -func="RegisterBankToken" \ -args="ugnot" \ teritori @@ -100,7 +89,7 @@ gnokey maketx call \ -chainid="teritori-1" \ -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ -func="Transfer" \ - -args="g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5" \ + -args="g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h" \ -args="5000000" \ teritori @@ -128,6 +117,32 @@ gnokey maketx addpkg \ -pkgpath="gno.land/r/x/grc20_dynamic_call/wrapper" \ teritori +# Send 10 GNOT to realm address +gnokey maketx send \ + -send="10000000ugnot" \ + -to="g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + teritori + +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -send="10000000ugnot" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ + -func="TransferFromByInterfaceName" \ + -args="ugnot" \ + -args="$TERITORI" \ + -args="g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h" \ + -args="0" \ + teritori + # Transfer ugnot (0.1GNOT to TERITORI) gnokey maketx call \ -gas-fee="1ugnot" \ @@ -135,7 +150,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ -func="TransferByInterfaceName" \ -args="ugnot" \ -args="$TERITORI" \ @@ -149,7 +164,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_02" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ -func="TransferByInterfaceName" \ -args="foo" \ -args="$TERITORI" \ @@ -157,11 +172,11 @@ gnokey maketx call \ teritori # Query RealmAddr -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_07 RealmAddr()" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 -BalanceOfByInterfaceName(\"ugnot\",\"g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5\")" -remote="51.15.236.215:26657" +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_07 +BalanceOfByInterfaceName(\"ugnot\",\"g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h\")" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_02 -BalanceOfByInterfaceName(\"foo\",\"g19ffr0zd3ad8n4tr7rxff6dte8dxxss2sleajc5\")" -remote="51.15.236.215:26657" +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_07 +BalanceOfByInterfaceName(\"foo\",\"g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h\")" -remote="51.15.236.215:26657" From ec33b545344086dfcb47f1a1d99c8fcfc8521dc5 Mon Sep 17 00:00:00 2001 From: go7066 Date: Thu, 22 Feb 2024 22:43:00 +0800 Subject: [PATCH 10/12] unexpected selector expression type gnolang.PrimitiveType fix --- .../p/demo/teritori/token_registry/registry.gno | 6 +++--- .../r/x/grc20_dynamic_call/registry/registry.gno | 6 +++--- .../registry/registry_teritori_testnet.sh | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/gno.land/p/demo/teritori/token_registry/registry.gno b/examples/gno.land/p/demo/teritori/token_registry/registry.gno index 99c09e46f0f..ab94eedc84b 100644 --- a/examples/gno.land/p/demo/teritori/token_registry/registry.gno +++ b/examples/gno.land/p/demo/teritori/token_registry/registry.gno @@ -131,9 +131,9 @@ func (r Registry) TransferFromByInterfaceName(token string, from, to std.Address panic("only one coin can be sent") } - // if int64(amount) != coinSent.AmountOf(i.token) { - // panic("invalid amount sent") - // } + if int64(amount) != coinSent.AmountOf(r.registered[i].token) { + panic("invalid amount sent") + } if caller.String() != from { panic("only caller should be configured for banker TransferFrom") diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno index 1212fb5f775..8d05115f7b4 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry.gno @@ -122,9 +122,9 @@ func TransferFromByInterfaceName(token string, from, to std.Address, amount uint panic("only one coin can be sent") } - // if int64(amount) != coinSent.AmountOf(i.token) { - // panic("invalid amount sent") - // } + if int64(amount) != coinSent.AmountOf(registered[i].token) { + panic("invalid amount sent") + } if caller.String() != from { panic("only caller should be configured for banker TransferFrom") diff --git a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh index bb3be8fedbc..6ec0ced6a17 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh +++ b/examples/gno.land/r/x/grc20_dynamic_call/registry/registry_teritori_testnet.sh @@ -20,7 +20,7 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/registry" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_08" \ teritori gnokey maketx addpkg \ @@ -41,7 +41,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_08" \ -func="RegisterBankToken" \ -args="ugnot" \ teritori @@ -135,7 +135,7 @@ gnokey maketx call \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -send="10000000ugnot" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_08" \ -func="TransferFromByInterfaceName" \ -args="ugnot" \ -args="$TERITORI" \ @@ -150,7 +150,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_08" \ -func="TransferByInterfaceName" \ -args="ugnot" \ -args="$TERITORI" \ @@ -164,7 +164,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_07" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/registry_08" \ -func="TransferByInterfaceName" \ -args="foo" \ -args="$TERITORI" \ @@ -172,11 +172,11 @@ gnokey maketx call \ teritori # Query RealmAddr -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_07 +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 RealmAddr()" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_07 +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 BalanceOfByInterfaceName(\"ugnot\",\"g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h\")" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_07 +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 BalanceOfByInterfaceName(\"foo\",\"g1nmh4xp6dlyrk3p484rq9p938juzrf6cmjj4n0h\")" -remote="51.15.236.215:26657" From 345feaf2198913bced501627ba649a56e4cb8c87 Mon Sep 17 00:00:00 2001 From: go7066 Date: Wed, 28 Feb 2024 20:21:03 +0800 Subject: [PATCH 11/12] add update on escrow + token registry --- .../registry_teritori_testnet.sh | 2 +- .../r/demo/teritori/escrow/escrow.gno | 33 +++--- .../escrow/escrow_teritori_testnet.sh | 106 ++++++++++++------ .../x/grc20_dynamic_call/wrapper/wrapper.gno | 9 +- 4 files changed, 95 insertions(+), 55 deletions(-) diff --git a/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh b/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh index ada6ea2eebd..0012d9a28b2 100644 --- a/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh +++ b/examples/gno.land/p/demo/teritori/token_registry/registry_teritori_testnet.sh @@ -20,7 +20,7 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./examples/gno.land/p/demo/teritori/token_registry" \ - -pkgpath="gno.land/p/demo/teritori/token_registry_02" \ + -pkgpath="gno.land/p/demo/teritori/token_registry_3" \ teritori # # Register Bank token diff --git a/examples/gno.land/r/demo/teritori/escrow/escrow.gno b/examples/gno.land/r/demo/teritori/escrow/escrow.gno index 28f7cebbdf8..546b1a46cf2 100644 --- a/examples/gno.land/r/demo/teritori/escrow/escrow.gno +++ b/examples/gno.land/r/demo/teritori/escrow/escrow.gno @@ -6,9 +6,8 @@ import ( "strings" "time" - token_registry "gno.land/p/demo/teritori/token_registry_02" + token_registry "gno.land/p/demo/teritori/token_registry_3" fmt "gno.land/p/demo/ufmt" - "gno.land/r/demo/users" ) type ContractStatus uint32 @@ -221,9 +220,9 @@ func CreateContract( funded := false if caller.String() == funder { token_reg.TransferFromByInterfaceName( - contract.escrowToken, - users.AddressOrName(caller.String()), - users.AddressOrName(std.CurrentRealm().Addr().String()), + escrowToken, + caller, + std.CurrentRealm().Addr(), projectBudget) funded = true @@ -375,7 +374,7 @@ func PayPartialMilestone(contractId uint64, milestoneId uint64, amount uint64) { token_reg.TransferByInterfaceName( contract.escrowToken, - users.AddressOrName(contract.contractor), + std.Address(contract.contractor), amount) contracts[contractId].milestones[milestoneId].paid += amount } @@ -422,8 +421,8 @@ func SubmitFunder(contractId uint64, fundingMilestoneIds string) { token_reg.TransferFromByInterfaceName( contract.escrowToken, - users.AddressOrName(caller.String()), - users.AddressOrName(std.CurrentRealm().Addr().String()), + caller, + std.CurrentRealm().Addr(), budget, ) @@ -520,7 +519,7 @@ func CompleteMilestoneAndPay(contractId uint64, milestoneId uint64) { if unpaid > 0 { token_reg.TransferByInterfaceName( contract.escrowToken, - users.AddressOrName(contract.contractor), + std.Address(contract.contractor), unpaid) contracts[contractId].milestones[milestoneId].paid += unpaid } @@ -576,7 +575,7 @@ func ChangeMilestoneStatus(contractId uint64, milestoneId int, newStatus Milesto if unpaid > 0 { token_reg.TransferByInterfaceName( contract.escrowToken, - users.AddressOrName(contract.contractor), + std.Address(contract.contractor), unpaid) contracts[contractId].milestones[milestoneId].paid += unpaid } @@ -609,8 +608,8 @@ func FundMilestone(contractId uint64, milestoneId uint64) { } token_reg.TransferFromByInterfaceName( contract.escrowToken, - users.AddressOrName(caller.String()), - users.AddressOrName(std.CurrentRealm().Addr().String()), + caller, + std.CurrentRealm().Addr(), milestone.amount) contracts[contractId].milestones[milestoneId].funded = true contracts[contractId].milestones[milestoneId].status = MS_PROGRESS @@ -772,11 +771,11 @@ func CompleteContractByConflictHandler(contractId uint64, milestoneId uint64, co token_reg.TransferByInterfaceName( contract.escrowToken, - users.AddressOrName(contract.contractor), + std.Address(contract.contractor), contractorAmount) token_reg.TransferByInterfaceName( contract.escrowToken, - users.AddressOrName(contract.funder), + std.Address(contract.funder), funderAmount) contracts[contractId].milestones[milestoneId].paid += contractorAmount @@ -872,11 +871,11 @@ func RenderContract(contractId uint64) string { } milestonesText := strings.Join(milestoneEncodes, ",\n") - contractorCandidates = []string{} + contractorCandidates := []string{} for _, candidate := range c.contractorCandidates { contractorCandidates = append(contractorCandidates, "\""+candidate+"\"") } - contractorCandidatesText = strings.Join(contractorCandidates, ",") + contractorCandidatesText := strings.Join(contractorCandidates, ",") return fmt.Sprintf(`{ "id": %d, @@ -919,7 +918,7 @@ func RenderContracts(startAfter uint64, limit uint64, filterByFunder string, fil return rendered } -func RegisterGRC20Interface(token string, igrc20 GRC20Interface) { +func RegisterGRC20Interface(token string, igrc20 token_registry.GRC20Interface) { token_reg.RegisterGRC20Interface(token, igrc20) } diff --git a/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh b/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh index 35eef716520..695e3eae882 100644 --- a/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh +++ b/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh @@ -11,10 +11,12 @@ GOPHER=g1x2xyqca98auaw9lnat2h9ycd4lx3w0jer9vjmt # check balance gnokey query bank/balances/$GOPHER -remote="51.15.236.215:26657" +gnokey query bank/balances/$TERITORI -remote="51.15.236.215:26657" +gnokey query bank/balances/g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq -remote="51.15.236.215:26657" # Send balance to gopher2 account gnokey maketx send \ - -send="10000000ugnot" \ + -send="100000000ugnot" \ -to="g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq" \ -gas-fee="1ugnot" \ -gas-wanted="5000000" \ @@ -31,7 +33,7 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./escrow" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ teritori # Create Contract @@ -41,17 +43,19 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="CreateContract" \ -args="g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq" \ -args="$TERITORI" \ - -args="gopher20" \ + -args="ugnot" \ -args="{}" \ -args="60" \ -args="Milestone1,Milestone2" \ + -args="Milestone Desc1,Milestone Desc2" \ -args="10,15" \ -args="86400,86400" \ -args="https://ref.com/m1,https://ref.com/m2" \ + -args="MS_PRIORITY_HIGH,MS_PRIORITY_HIGH" \ -args="" \ teritori @@ -62,7 +66,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="CancelContract" \ -args="0" \ teritori @@ -74,9 +78,9 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="AcceptContract" \ - -args="0" \ + -args="3" \ gopher2 gnokey maketx call \ @@ -85,7 +89,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="FundMilestone" \ -args="0" \ teritori @@ -97,7 +101,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="PauseContract" \ -args="0" \ teritori @@ -109,7 +113,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="CompleteContract" \ -args="0" \ teritori @@ -121,34 +125,36 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="ResumeContract" \ -args="1" \ teritori -# Pay partial amount of milestone +# Submit milestone as ready for review gnokey maketx call \ -gas-fee="1ugnot" \ -gas-wanted="5000000" \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ - -func="PayPartialMilestone" \ - -args="0" \ - -args="5" \ - teritori + -pkgpath="gno.land/r/demo/escrow_17" \ + -func="ChangeMilestoneStatus" \ + -args="3" \ + -args="1" \ + -args="3" \ + gopher2 -# Pay and complete active milestone +# Pay and complete milestone gnokey maketx call \ -gas-fee="1ugnot" \ -gas-wanted="5000000" \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ - -func="PayAndCompleteActiveMilestone" \ - -args="0" \ + -pkgpath="gno.land/r/demo/escrow_17" \ + -func="CompleteMilestoneAndPay" \ + -args="3" \ + -args="1" \ teritori # Fund active milestone - Start milestone @@ -158,9 +164,10 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="FundMilestone" \ -args="0" \ + -args="2" \ teritori # Add upcoming milestone @@ -170,10 +177,11 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="AddUpcomingMilestone" \ -args="0" \ -args="Milestone3" \ + -args="Milestone3 Desc" \ -args="20" \ -args="86400" \ -args="https://ref.com/m3" \ @@ -186,7 +194,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="CancelUpcomingMilestone" \ -args="0" \ -args="3" \ @@ -199,7 +207,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="SuggestConflictHandler" \ -args="0" \ -args="gno.land/r/demo/conflict_solver_01" \ @@ -212,7 +220,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="ApproveConflictHandler" \ -args="0" \ -args="gno.land/r/demo/conflict_solver_01" \ @@ -225,7 +233,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="CompleteContractByConflictHandler" \ -args="0" \ -args="50" \ @@ -238,28 +246,54 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_15" \ + -pkgpath="gno.land/r/demo/escrow_17" \ -func="GiveFeedback" \ -args="0" \ -args="Amazing work" \ teritori +# Register token +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/demo/escrow_17" \ + -func="RegisterBankToken" \ + -args="ugnot" \ + teritori + +# Deploy wrapper & register to registry +gnokey maketx addpkg \ + -deposit="1ugnot" \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/wrapper" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/wrapper_02" \ + teritori + # Query Contracts -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_15 -RenderContracts(0, 10)" -remote="51.15.236.215:26657" +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +RenderContracts(0, 10, \"ALL\", \"ALL\")" -remote="51.15.236.215:26657" # Query contract -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_15 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 RenderContract(0)" -remote="51.15.236.215:26657" # Query config -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_15 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 RenderConfig()" -remote="51.15.236.215:26657" # Query escrow address -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_15 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 CurrentRealm()" -remote="51.15.236.215:26657" +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +RealmAddr()" -remote="51.15.236.215:26657" # Get gopher20 faucet gnokey maketx call \ @@ -291,3 +325,9 @@ BalanceOf(\"$TERITORI\")" -remote="51.15.236.215:26657" gnokey query "vm/qeval" -data="gno.land/r/demo/gopher20 Render(\"balance/g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 +BalanceOfByInterfaceName(\"ugnot\",\"g1ekzpjudtttrwve88dlqa4qy6wgunhv0r64skly\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 +BalanceOfByInterfaceName(\"foo\",\"g1ekzpjudtttrwve88dlqa4qy6wgunhv0r64skly\")" -remote="51.15.236.215:26657" diff --git a/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno b/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno index 223c36ef364..642405bc142 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno @@ -7,7 +7,8 @@ import ( "gno.land/r/x/grc20_dynamic_call/baz" "gno.land/r/x/grc20_dynamic_call/foo" - registry "gno.land/r/x/grc20_dynamic_call/registry_01" + registry "gno.land/p/demo/teritori/token_registry_3" + escrow "gno.land/r/demo/escrow_17" ) type FooTokenInterface struct{} @@ -59,7 +60,7 @@ func (BazTokenInterface) BalanceOf() func(owner users.AddressOrName) uint64 { var _ registry.GRC20Interface = BazTokenInterface{} func init() { - registry.RegisterGRC20Interface("foo", FooTokenInterface{}) - registry.RegisterGRC20Interface("bar", BarTokenInterface{}) - registry.RegisterGRC20Interface("baz", BazTokenInterface{}) + escrow.RegisterGRC20Interface("foo", FooTokenInterface{}) + escrow.RegisterGRC20Interface("bar", BarTokenInterface{}) + escrow.RegisterGRC20Interface("baz", BazTokenInterface{}) } From 29963ff1c58123bff800677602adab84ce1168d0 Mon Sep 17 00:00:00 2001 From: go7066 Date: Fri, 1 Mar 2024 23:41:59 +0800 Subject: [PATCH 12/12] escrow update on token registry --- .../demo/teritori/token_registry/registry.gno | 21 +-- .../r/demo/teritori/escrow/escrow.gno | 77 ++++++-- .../escrow/escrow_teritori_testnet.sh | 125 ++++++++----- .../r/demo/teritori/escrow/registry.gno | 173 ++++++++++++++++++ .../x/grc20_dynamic_call/wrapper/wrapper.gno | 9 +- 5 files changed, 323 insertions(+), 82 deletions(-) create mode 100644 examples/gno.land/r/demo/teritori/escrow/registry.gno diff --git a/examples/gno.land/p/demo/teritori/token_registry/registry.gno b/examples/gno.land/p/demo/teritori/token_registry/registry.gno index ab94eedc84b..c31a051e5e3 100644 --- a/examples/gno.land/p/demo/teritori/token_registry/registry.gno +++ b/examples/gno.land/p/demo/teritori/token_registry/registry.gno @@ -41,15 +41,15 @@ func (r Registry) findToken(token string) (int, bool) { return -1, false } -func (r Registry) appendGRC20Interface(pkgPath string, igrc20 GRC20Interface) { +func (r *Registry) appendGRC20Interface(pkgPath string, igrc20 GRC20Interface) { r.registered = append(r.registered, TokenInfo{isBank: false, token: pkgPath, igrc20: igrc20}) } -func (r Registry) appendBankToken(denom string) { +func (r *Registry) appendBankToken(denom string) { r.registered = append(r.registered, TokenInfo{isBank: true, token: denom}) } -func (r Registry) removeToken(token string) { +func (r *Registry) removeToken(token string) { i, found := r.findToken(token) if !found { return @@ -58,7 +58,7 @@ func (r Registry) removeToken(token string) { r.registered = append(r.registered[:i], r.registered[i+1:]...) } -func (r Registry) RegisterGRC20Interface(token string, igrc20 GRC20Interface) { +func (r *Registry) RegisterGRC20Interface(token string, igrc20 GRC20Interface) { _, found := r.findToken(token) if found { panic("GRC20 already registered") @@ -67,7 +67,7 @@ func (r Registry) RegisterGRC20Interface(token string, igrc20 GRC20Interface) { r.appendGRC20Interface(token, igrc20) } -func (r Registry) UnregisterToken(token string) { +func (r *Registry) UnregisterToken(token string) { // do not allow realm to unregister std.AssertOriginCall() caller := std.GetOrigCaller() @@ -82,7 +82,7 @@ func (r Registry) UnregisterToken(token string) { } } -func (r Registry) RegisterBankToken(denom string) { +func (r *Registry) RegisterBankToken(denom string) { _, found := r.findToken(denom) if found { panic("Token already registered") @@ -91,11 +91,6 @@ func (r Registry) RegisterBankToken(denom string) { r.appendBankToken(denom) } -func (r Registry) RealmAddr() string { - realmAddr := std.GetOrigPkgAddr() - return realmAddr.String() -} - func (r Registry) TransferByInterfaceName(token string, to std.Address, amount uint64) bool { i, found := r.findToken(token) if !found { @@ -172,3 +167,7 @@ func (r Registry) BalanceOfByInterfaceName(token string, owner std.Address) uint balance := r.registered[i].igrc20.BalanceOf()(users.AddressOrName(owner)) return balance } + +func (r Registry) RegisteredTokens() []TokenInfo { + return r.registered +} diff --git a/examples/gno.land/r/demo/teritori/escrow/escrow.gno b/examples/gno.land/r/demo/teritori/escrow/escrow.gno index 546b1a46cf2..afa12e5e898 100644 --- a/examples/gno.land/r/demo/teritori/escrow/escrow.gno +++ b/examples/gno.land/r/demo/teritori/escrow/escrow.gno @@ -6,7 +6,6 @@ import ( "strings" "time" - token_registry "gno.land/p/demo/teritori/token_registry_3" fmt "gno.land/p/demo/ufmt" ) @@ -120,7 +119,7 @@ type Contract struct { // Escrow State var contracts []Contract -var token_reg = token_registry.New(CurrentRealm()) +var token_reg = NewTokenRegistry(CurrentRealm()) func CurrentRealm() string { return std.CurrentRealm().Addr().String() @@ -219,11 +218,13 @@ func CreateContract( // If contract creator is funder then he needs to send all the needed fund to contract funded := false if caller.String() == funder { - token_reg.TransferFromByInterfaceName( + if !token_reg.TransferFromByInterfaceName( escrowToken, caller, std.CurrentRealm().Addr(), - projectBudget) + projectBudget) { + panic("token transfer failure") + } funded = true } @@ -372,10 +373,12 @@ func PayPartialMilestone(contractId uint64, milestoneId uint64, amount uint64) { panic("could not pay more than milestone amount") } - token_reg.TransferByInterfaceName( + if !token_reg.TransferByInterfaceName( contract.escrowToken, std.Address(contract.contractor), - amount) + amount) { + panic("token transfer failure") + } contracts[contractId].milestones[milestoneId].paid += amount } @@ -419,12 +422,14 @@ func SubmitFunder(contractId uint64, fundingMilestoneIds string) { budget += milestone.amount } - token_reg.TransferFromByInterfaceName( + if !token_reg.TransferFromByInterfaceName( contract.escrowToken, caller, std.CurrentRealm().Addr(), budget, - ) + ) { + panic("token transfer failure") + } contracts[contractId].funded = true contracts[contractId].status = ACCEPTED @@ -517,10 +522,12 @@ func CompleteMilestoneAndPay(contractId uint64, milestoneId uint64) { // Pay the milestone unpaid := milestone.amount - milestone.paid if unpaid > 0 { - token_reg.TransferByInterfaceName( + if !token_reg.TransferByInterfaceName( contract.escrowToken, std.Address(contract.contractor), - unpaid) + unpaid) { + panic("token transfer failure") + } contracts[contractId].milestones[milestoneId].paid += unpaid } @@ -573,10 +580,12 @@ func ChangeMilestoneStatus(contractId uint64, milestoneId int, newStatus Milesto // Pay the milestone unpaid := milestone.amount - milestone.paid if unpaid > 0 { - token_reg.TransferByInterfaceName( + if !token_reg.TransferByInterfaceName( contract.escrowToken, std.Address(contract.contractor), - unpaid) + unpaid) { + panic("token transfer failure") + } contracts[contractId].milestones[milestoneId].paid += unpaid } } @@ -606,11 +615,13 @@ func FundMilestone(contractId uint64, milestoneId uint64) { if milestone.funded { panic("milestone already funded") } - token_reg.TransferFromByInterfaceName( + if !token_reg.TransferFromByInterfaceName( contract.escrowToken, caller, std.CurrentRealm().Addr(), - milestone.amount) + milestone.amount) { + panic("token transfer failure") + } contracts[contractId].milestones[milestoneId].funded = true contracts[contractId].milestones[milestoneId].status = MS_PROGRESS } @@ -769,14 +780,18 @@ func CompleteContractByConflictHandler(contractId uint64, milestoneId uint64, co funderAmount := unpaidAmount - contractorAmount - token_reg.TransferByInterfaceName( + if !token_reg.TransferByInterfaceName( contract.escrowToken, std.Address(contract.contractor), - contractorAmount) - token_reg.TransferByInterfaceName( + contractorAmount) { + panic("token transfer failure") + } + if !token_reg.TransferByInterfaceName( contract.escrowToken, std.Address(contract.funder), - funderAmount) + funderAmount) { + panic("token transfer failure") + } contracts[contractId].milestones[milestoneId].paid += contractorAmount contracts[contractId].milestones[milestoneId].status = MS_COMPLETED @@ -918,7 +933,7 @@ func RenderContracts(startAfter uint64, limit uint64, filterByFunder string, fil return rendered } -func RegisterGRC20Interface(token string, igrc20 token_registry.GRC20Interface) { +func RegisterGRC20Interface(token string, igrc20 GRC20Interface) { token_reg.RegisterGRC20Interface(token, igrc20) } @@ -934,3 +949,27 @@ func RealmAddr() string { realmAddr := std.GetOrigPkgAddr() return realmAddr.String() } + +func RegisteredTokens() string { + tokens := token_reg.RegisteredTokens() + rendered := "[" + for index, token := range tokens { + // If render === "[", it means we are first item => do not add separator + if rendered != "[" { + rendered += "," + } + + rendered += "\"" + rendered += token.token + if token.isBank { + rendered += "(Bank)" + } + rendered += "\"" + } + rendered += "]" + return rendered +} + +func BalanceOfByInterfaceName(token string, owner std.Address) uint64 { + return token_reg.BalanceOfByInterfaceName(token, owner) +} diff --git a/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh b/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh index 695e3eae882..f8484fcbd24 100644 --- a/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh +++ b/examples/gno.land/r/demo/teritori/escrow/escrow_teritori_testnet.sh @@ -33,17 +33,18 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./escrow" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ teritori -# Create Contract +# Create Contract (GNOT) gnokey maketx call \ -gas-fee="1ugnot" \ -gas-wanted="5000000" \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ + -send="25ugnot" \ -func="CreateContract" \ -args="g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq" \ -args="$TERITORI" \ @@ -59,6 +60,30 @@ gnokey maketx call \ -args="" \ teritori +# Create Contract (FOO) +gnokey maketx call \ + -gas-fee="1ugnot" \ + -gas-wanted="5000000" \ + -broadcast="true" \ + -remote="51.15.236.215:26657" \ + -chainid="teritori-1" \ + -pkgpath="gno.land/r/demo/escrow_21" \ + -func="CreateContract" \ + -args="g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq" \ + -args="$TERITORI" \ + -args="foo" \ + -args="{}" \ + -args="60" \ + -args="Milestone1,Milestone2" \ + -args="Milestone Desc1,Milestone Desc2" \ + -args="10,15" \ + -args="86400,86400" \ + -args="https://ref.com/m1,https://ref.com/m2" \ + -args="MS_PRIORITY_HIGH,MS_PRIORITY_HIGH" \ + -args="" \ + teritori + + # Cancel Contract gnokey maketx call \ -gas-fee="1ugnot" \ @@ -66,7 +91,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="CancelContract" \ -args="0" \ teritori @@ -78,9 +103,9 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="AcceptContract" \ - -args="3" \ + -args="2" \ gopher2 gnokey maketx call \ @@ -89,7 +114,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="FundMilestone" \ -args="0" \ teritori @@ -101,7 +126,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="PauseContract" \ -args="0" \ teritori @@ -113,7 +138,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="CompleteContract" \ -args="0" \ teritori @@ -125,7 +150,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="ResumeContract" \ -args="1" \ teritori @@ -137,10 +162,10 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="ChangeMilestoneStatus" \ - -args="3" \ - -args="1" \ + -args="2" \ + -args="0" \ -args="3" \ gopher2 @@ -151,10 +176,10 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="CompleteMilestoneAndPay" \ - -args="3" \ - -args="1" \ + -args="2" \ + -args="0" \ teritori # Fund active milestone - Start milestone @@ -164,7 +189,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="FundMilestone" \ -args="0" \ -args="2" \ @@ -177,7 +202,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="AddUpcomingMilestone" \ -args="0" \ -args="Milestone3" \ @@ -194,7 +219,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="CancelUpcomingMilestone" \ -args="0" \ -args="3" \ @@ -207,7 +232,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="SuggestConflictHandler" \ -args="0" \ -args="gno.land/r/demo/conflict_solver_01" \ @@ -220,7 +245,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="ApproveConflictHandler" \ -args="0" \ -args="gno.land/r/demo/conflict_solver_01" \ @@ -233,7 +258,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="CompleteContractByConflictHandler" \ -args="0" \ -args="50" \ @@ -246,7 +271,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="GiveFeedback" \ -args="0" \ -args="Amazing work" \ @@ -259,7 +284,7 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/escrow_17" \ + -pkgpath="gno.land/r/demo/escrow_21" \ -func="RegisterBankToken" \ -args="ugnot" \ teritori @@ -273,36 +298,55 @@ gnokey maketx addpkg \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ -pkgdir="./examples/gno.land/r/x/grc20_dynamic_call/wrapper" \ - -pkgpath="gno.land/r/x/grc20_dynamic_call/wrapper_02" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/wrapper_03" \ teritori # Query Contracts -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 RenderContracts(0, 10, \"ALL\", \"ALL\")" -remote="51.15.236.215:26657" # Query contract -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 RenderContract(0)" -remote="51.15.236.215:26657" # Query config -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 RenderConfig()" -remote="51.15.236.215:26657" # Query escrow address -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 CurrentRealm()" -remote="51.15.236.215:26657" -gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_17 +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 RealmAddr()" -remote="51.15.236.215:26657" -# Get gopher20 faucet +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 +RegisteredTokens()" -remote="51.15.236.215:26657" + +# Query balance +gnokey query "vm/qeval" -data="gno.land/r/demo/gopher20 +BalanceOf(\"$TERITORI\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/demo/gopher20 +Render(\"balance/g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 +BalanceOfByInterfaceName(\"ugnot\",\"g1jydv2wlyk7xn0z0mxldz4atyxmnp5c7vzq0gfc\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 +BalanceOfByInterfaceName(\"foo\",\"g1jydv2wlyk7xn0z0mxldz4atyxmnp5c7vzq0gfc\")" -remote="51.15.236.215:26657" + +gnokey query "vm/qeval" -data="gno.land/r/demo/escrow_21 +BalanceOfByInterfaceName(\"foo\",\"g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq\")" -remote="51.15.236.215:26657" + +# Get foo faucet gnokey maketx call \ -gas-fee="1ugnot" \ -gas-wanted="5000000" \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/gopher20" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ -func="Faucet" \ teritori @@ -313,21 +357,8 @@ gnokey maketx call \ -broadcast="true" \ -remote="51.15.236.215:26657" \ -chainid="teritori-1" \ - -pkgpath="gno.land/r/demo/gopher20" \ + -pkgpath="gno.land/r/x/grc20_dynamic_call/foo" \ -func="Approve" \ - -args="g1f7p4tuu044w2qsa9m3h64ql4lrqmmjzm2f6jws" \ + -args="g1jydv2wlyk7xn0z0mxldz4atyxmnp5c7vzq0gfc" \ -args="1000" \ teritori - -# Query balance -gnokey query "vm/qeval" -data="gno.land/r/demo/gopher20 -BalanceOf(\"$TERITORI\")" -remote="51.15.236.215:26657" - -gnokey query "vm/qeval" -data="gno.land/r/demo/gopher20 -Render(\"balance/g1c5y8jpe585uezcvlmgdjmk5jt2glfw88wxa3xq\")" -remote="51.15.236.215:26657" - -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 -BalanceOfByInterfaceName(\"ugnot\",\"g1ekzpjudtttrwve88dlqa4qy6wgunhv0r64skly\")" -remote="51.15.236.215:26657" - -gnokey query "vm/qeval" -data="gno.land/r/x/grc20_dynamic_call/registry_08 -BalanceOfByInterfaceName(\"foo\",\"g1ekzpjudtttrwve88dlqa4qy6wgunhv0r64skly\")" -remote="51.15.236.215:26657" diff --git a/examples/gno.land/r/demo/teritori/escrow/registry.gno b/examples/gno.land/r/demo/teritori/escrow/registry.gno new file mode 100644 index 00000000000..2b8d3c3d7d2 --- /dev/null +++ b/examples/gno.land/r/demo/teritori/escrow/registry.gno @@ -0,0 +1,173 @@ +package escrow + +import ( + "std" + + "gno.land/r/demo/users" +) + +type Registry struct { + registered []TokenInfo + manager string +} + +func NewTokenRegistry(manager string) *Registry { + r := Registry{ + registered: []TokenInfo{}, + manager: manager, + } + return &r +} + +type GRC20Interface interface { + Transfer() func(to users.AddressOrName, amount uint64) + TransferFrom() func(from, to users.AddressOrName, amount uint64) + BalanceOf() func(owner users.AddressOrName) uint64 +} + +type TokenInfo struct { + isBank bool + token string // pkgPath (GRC20) | denom (Bank) + igrc20 GRC20Interface // only valid when isBank is false +} + +func (r Registry) findToken(token string) (int, bool) { + for i, pair := range r.registered { + if pair.token == token { + return i, true + } + } + + return -1, false +} + +func (r *Registry) appendGRC20Interface(pkgPath string, igrc20 GRC20Interface) { + r.registered = append(r.registered, TokenInfo{isBank: false, token: pkgPath, igrc20: igrc20}) +} + +func (r *Registry) appendBankToken(denom string) { + r.registered = append(r.registered, TokenInfo{isBank: true, token: denom}) +} + +func (r *Registry) removeToken(token string) { + i, found := r.findToken(token) + if !found { + return + } + + r.registered = append(r.registered[:i], r.registered[i+1:]...) +} + +func (r *Registry) RegisterGRC20Interface(token string, igrc20 GRC20Interface) { + _, found := r.findToken(token) + if found { + panic("GRC20 already registered") + } + + r.appendGRC20Interface(token, igrc20) +} + +func (r *Registry) UnregisterToken(token string) { + // do not allow realm to unregister + std.AssertOriginCall() + caller := std.GetOrigCaller() + + if caller != r.manager { + panic("unauthorized") + } + + _, found := r.findToken(token) + if found { + r.removeToken(token) + } +} + +func (r *Registry) RegisterBankToken(denom string) { + _, found := r.findToken(denom) + if found { + panic("Token already registered") + } + + r.appendBankToken(denom) +} + +func (r Registry) TransferByInterfaceName(token string, to std.Address, amount uint64) bool { + i, found := r.findToken(token) + if !found { + return false + } + + if r.registered[i].isBank { + banker := std.GetBanker(std.BankerTypeRealmSend) + + coin := std.Coins{{token, int64(amount)}} + realmAddr := std.GetOrigPkgAddr() + + // Send coin from realm + banker.SendCoins(realmAddr, to, coin) + return true + } + r.registered[i].igrc20.Transfer()(users.AddressOrName(to), amount) + + return true +} + +func (r Registry) TransferFromByInterfaceName(token string, from, to std.Address, amount uint64) bool { + i, found := r.findToken(token) + if !found { + return false + } + + if r.registered[i].isBank { + coinSent := std.GetOrigSend() // get Coins sent with call + caller := std.GetOrigCaller() // get tx sender + + if len(coinSent) != 1 { + panic("only one coin can be sent") + } + + if int64(amount) != coinSent.AmountOf(r.registered[i].token) { + panic("invalid amount sent") + } + + if caller.String() != from { + panic("only caller should be configured for banker TransferFrom") + } + + realmAddr := std.GetOrigPkgAddr() + if to.String() != realmAddr.String() { + // Send coin from realm to target + banker := std.GetBanker(std.BankerTypeOrigSend) + coin := std.Coins{{token, int64(amount)}} + banker.SendCoins(realmAddr, to, coin) + } + return true + } + r.registered[i].igrc20.TransferFrom()(users.AddressOrName(from), users.AddressOrName(to), amount) + + return true +} + +func (r Registry) BalanceOfByInterfaceName(token string, owner std.Address) uint64 { + i, found := r.findToken(token) + if !found { + return 0 + } + + if r.registered[i].isBank { + banker := std.GetBanker(std.BankerTypeReadonly) + coins := banker.GetCoins(owner) + for _, coin := range coins { + if coin.Denom == token { + return uint64(coin.Amount) + } + } + return 0 + } + balance := r.registered[i].igrc20.BalanceOf()(users.AddressOrName(owner)) + return balance +} + +func (r Registry) RegisteredTokens() []TokenInfo { + return r.registered +} diff --git a/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno b/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno index 642405bc142..2746152cc21 100644 --- a/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno +++ b/examples/gno.land/r/x/grc20_dynamic_call/wrapper/wrapper.gno @@ -7,8 +7,7 @@ import ( "gno.land/r/x/grc20_dynamic_call/baz" "gno.land/r/x/grc20_dynamic_call/foo" - registry "gno.land/p/demo/teritori/token_registry_3" - escrow "gno.land/r/demo/escrow_17" + escrow "gno.land/r/demo/escrow_21" ) type FooTokenInterface struct{} @@ -25,7 +24,7 @@ func (FooTokenInterface) BalanceOf() func(owner users.AddressOrName) uint64 { return foo.BalanceOf } -var _ registry.GRC20Interface = FooTokenInterface{} +var _ escrow.GRC20Interface = FooTokenInterface{} type BarTokenInterface struct{} @@ -41,7 +40,7 @@ func (BarTokenInterface) BalanceOf() func(owner users.AddressOrName) uint64 { return bar.BalanceOf } -var _ registry.GRC20Interface = BarTokenInterface{} +var _ escrow.GRC20Interface = BarTokenInterface{} type BazTokenInterface struct{} @@ -57,7 +56,7 @@ func (BazTokenInterface) BalanceOf() func(owner users.AddressOrName) uint64 { return baz.BalanceOf } -var _ registry.GRC20Interface = BazTokenInterface{} +var _ escrow.GRC20Interface = BazTokenInterface{} func init() { escrow.RegisterGRC20Interface("foo", FooTokenInterface{})