mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-04 20:05:50 +00:00
merge master in
This commit is contained in:
@@ -4,6 +4,7 @@
|
|||||||
[AMMオブジェクト]: /@l10n/ja/docs/references/protocol/ledger-data/ledger-entry-types/amm.md
|
[AMMオブジェクト]: /@l10n/ja/docs/references/protocol/ledger-data/ledger-entry-types/amm.md
|
||||||
[AMMBid]: /@l10n/ja/docs/references/protocol/transactions/types/ammbid.md
|
[AMMBid]: /@l10n/ja/docs/references/protocol/transactions/types/ammbid.md
|
||||||
[AMMBidトランザクション]: /@l10n/ja/docs/references/protocol/transactions/types/ammbid.md
|
[AMMBidトランザクション]: /@l10n/ja/docs/references/protocol/transactions/types/ammbid.md
|
||||||
|
[AMMClawbackトランザクション]: /@l10n/ja/docs/references/protocol/transactions/types/ammclawback.md
|
||||||
[AMMCreate]: /@l10n/ja/docs/references/protocol/transactions/types/ammcreate.md
|
[AMMCreate]: /@l10n/ja/docs/references/protocol/transactions/types/ammcreate.md
|
||||||
[AMMCreateトランザクション]: /@l10n/ja/docs/references/protocol/transactions/types/ammcreate.md
|
[AMMCreateトランザクション]: /@l10n/ja/docs/references/protocol/transactions/types/ammcreate.md
|
||||||
[AMMDelete]: /@l10n/ja/docs/references/protocol/transactions/types/ammdelete.md
|
[AMMDelete]: /@l10n/ja/docs/references/protocol/transactions/types/ammdelete.md
|
||||||
@@ -148,6 +149,7 @@
|
|||||||
[PermissionDelegation amendment]: /@l10n/ja/resources/known-amendments.md#permissiondelegation
|
[PermissionDelegation amendment]: /@l10n/ja/resources/known-amendments.md#permissiondelegation
|
||||||
[PermissionedDEX amendment]: /@l10n/ja/resources/known-amendments.md#permissioneddex
|
[PermissionedDEX amendment]: /@l10n/ja/resources/known-amendments.md#permissioneddex
|
||||||
[PermissionedDomains amendment]: /@l10n/ja/resources/known-amendments.md#permissioneddomains
|
[PermissionedDomains amendment]: /@l10n/ja/resources/known-amendments.md#permissioneddomains
|
||||||
|
[PermissionedDomainSetトランザクション]: /@l10n/ja/docs/references/protocol/transactions/types/permissioneddomainset.md
|
||||||
[許可型ドメイン]: /@l10n/ja/docs/concepts/tokens/decentralized-exchange/permissioned-domains.md
|
[許可型ドメイン]: /@l10n/ja/docs/concepts/tokens/decentralized-exchange/permissioned-domains.md
|
||||||
[PriceOracle amendment]: /@l10n/ja/resources/known-amendments.md#priceoracle
|
[PriceOracle amendment]: /@l10n/ja/resources/known-amendments.md#priceoracle
|
||||||
[MPTokensV1_1 amendment]: /@l10n/ja/resources/known-amendments.md#priceoracle
|
[MPTokensV1_1 amendment]: /@l10n/ja/resources/known-amendments.md#priceoracle
|
||||||
@@ -173,7 +175,7 @@
|
|||||||
[通貨額の指定]: /@l10n/ja/docs/references/protocol/data-types/basic-data-types.md#通貨額の指定
|
[通貨額の指定]: /@l10n/ja/docs/references/protocol/data-types/basic-data-types.md#通貨額の指定
|
||||||
[レジャーの指定]: /@l10n/ja/docs/references/protocol/data-types/basic-data-types.md#レジャーの指定
|
[レジャーの指定]: /@l10n/ja/docs/references/protocol/data-types/basic-data-types.md#レジャーの指定
|
||||||
[時間の指定]: /@l10n/ja/docs/references/protocol/data-types/basic-data-types.md#時間の指定
|
[時間の指定]: /@l10n/ja/docs/references/protocol/data-types/basic-data-types.md#時間の指定
|
||||||
[Specifying Without Amounts]: /@l10n/ja/docs/references/protocol/data-types/currency-formats.md#specifying-without-amounts
|
[金額なしの指定]: /@l10n/ja/docs/references/protocol/data-types/currency-formats.md#金額なしでの通貨の指定
|
||||||
[SusPay amendment]: /@l10n/ja/resources/known-amendments.md#suspay
|
[SusPay amendment]: /@l10n/ja/resources/known-amendments.md#suspay
|
||||||
[TickSize amendment]: /@l10n/ja/resources/known-amendments.md#ticksize
|
[TickSize amendment]: /@l10n/ja/resources/known-amendments.md#ticksize
|
||||||
[Ticketエントリ]: /@l10n/ja/docs/references/protocol/ledger-data/ledger-entry-types/ticket.md
|
[Ticketエントリ]: /@l10n/ja/docs/references/protocol/ledger-data/ledger-entry-types/ticket.md
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
|
||||||
|
'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
|
||||||
|
<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto" color-interpolation="auto" text-rendering="auto" stroke="black" stroke-linecap="square" width="630" stroke-miterlimit="10" shape-rendering="auto" stroke-opacity="1" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" viewBox="0 0 630 460" height="460" xmlns="http://www.w3.org/2000/svg" font-family="'Dialog'" font-style="normal" stroke-linejoin="miter" font-size="12px" stroke-dashoffset="0" image-rendering="auto"
|
||||||
|
><!--Generated by the Batik Graphics2D SVG Generator--><defs id="genericDefs"
|
||||||
|
/><g
|
||||||
|
><defs id="defs1"
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"
|
||||||
|
><path d="M0 0 L2147483647 0 L2147483647 2147483647 L0 2147483647 L0 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"
|
||||||
|
><path d="M0 0 L0 140 L160 140 L160 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"
|
||||||
|
><path d="M0 0 L0 140 L200 140 L200 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath4"
|
||||||
|
><path d="M0 0 L0 140 L190 140 L190 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath5"
|
||||||
|
><path d="M0 0 L0 80 L140 80 L140 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath6"
|
||||||
|
><path d="M0 0 L0 40 L110 40 L110 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath7"
|
||||||
|
><path d="M0 0 L0 30 L120 30 L120 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath8"
|
||||||
|
><path d="M0 0 L0 180 L270 180 L270 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
></defs
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(450,300)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><circle r="7" clip-path="url(#clipPath2)" cx="80.5" cy="7.5" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(450,300)"
|
||||||
|
><circle fill="none" r="7" clip-path="url(#clipPath2)" cx="80.5" cy="7.5"
|
||||||
|
/><path fill="none" d="M59.5 21.5 L101.5 21.5" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M80.5 14.5 L80.5 42.5" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M80.5 42.5 L66.5 70.5" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M80.5 42.5 L94.5 70.5" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="60" font-size="14px" y="93.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>Tracy</text
|
||||||
|
><text x="25" font-size="14px" y="109.2188" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>(許可型DEXの</text
|
||||||
|
><text x="33" font-size="14px" y="125.3281" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>トレーダー)</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(20,20)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><rect x="0.5" width="198.5" height="138.5" y="0.5" clip-path="url(#clipPath3)" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(20,20)"
|
||||||
|
><rect fill="none" x="0.5" width="198.5" height="138.5" y="0.5" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="60" font-size="14px" y="18.1094" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="11" font-size="14px" y="34.2188" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>USD.Acme:FOO.WayGate</text
|
||||||
|
><path fill="none" d="M1 40.2188 L199 40.2188" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="5" font-size="14px" y="55.3281" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" font-weight="bold" xml:space="preserve"
|
||||||
|
>DomainID: ドメインA</text
|
||||||
|
><path fill="none" d="M1 61.3281 L199 61.3281" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="5" font-size="14px" y="76.4375" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>10 FOO : 10 USD – Marko</text
|
||||||
|
><path fill="none" d="M1 82.4375 L199 82.4375" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="5" font-size="14px" y="97.5469" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>9 FOO : 15 USD – Tracy</text
|
||||||
|
><path fill="none" d="M1 103.5469 L199 103.5469" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="5" font-size="14px" y="118.6562" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>...</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(290,60)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><rect x="0.5" width="188.5" height="138.5" y="0.5" clip-path="url(#clipPath4)" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(290,60)"
|
||||||
|
><rect fill="none" x="0.5" width="188.5" height="138.5" y="0.5" clip-path="url(#clipPath4)"
|
||||||
|
/><text x="60" font-size="14px" y="18.1094" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>ドメインA</text
|
||||||
|
><path fill="none" d="M1 24.1094 L189 24.1094" clip-path="url(#clipPath4)"
|
||||||
|
/><text x="5" font-size="14px" y="39.2188" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>所有者: Owen</text
|
||||||
|
><text x="5" font-size="14px" y="55.3281" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>承認された資格情報:</text
|
||||||
|
><text x="5" font-size="14px" y="71.4375" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>- "認可済" by Isabel</text
|
||||||
|
><text x="5" font-size="14px" y="87.5469" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
></text
|
||||||
|
><text x="5" font-size="14px" y="103.6562" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" font-weight="bold" xml:space="preserve"
|
||||||
|
>- "認可済" by Owen</text
|
||||||
|
><text x="5" font-size="14px" y="119.7656" clip-path="url(#clipPath4)" font-family="sans-serif" stroke="none" font-weight="bold" xml:space="preserve"
|
||||||
|
></text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(120,300)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><circle r="7" clip-path="url(#clipPath2)" cx="80.5" cy="7.5" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(120,300)"
|
||||||
|
><circle fill="none" r="7" clip-path="url(#clipPath2)" cx="80.5" cy="7.5"
|
||||||
|
/><path fill="none" d="M59.5 21.5 L101.5 21.5" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M80.5 14.5 L80.5 42.5" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M80.5 42.5 L66.5 70.5" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M80.5 42.5 L94.5 70.5" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="60" font-size="14px" y="93.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>Owen</text
|
||||||
|
><text x="19" font-size="14px" y="109.2188" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>(資格情報の発行者</text
|
||||||
|
><text x="11" font-size="14px" y="125.3281" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>かつドメインの所有者)</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(300,290)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L80.7725 0.5 L80.7725 21.6094 L139 21.6094 L139 79 L0.5 79 Z" stroke="none" clip-path="url(#clipPath5)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(300,290)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L80.7725 0.5 L80.7725 21.6094 L139 21.6094 L139 79 L0.5 79 Z" clip-path="url(#clipPath5)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L80.7725 21.6094" clip-path="url(#clipPath5)"
|
||||||
|
/><text x="5" font-size="14px" y="16.1094" clip-path="url(#clipPath5)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>資格情報</text
|
||||||
|
><text x="5" font-size="14px" y="39.5" clip-path="url(#clipPath5)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>タイプ: "認可済"</text
|
||||||
|
><text x="5" font-size="14px" y="55.6094" clip-path="url(#clipPath5)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>発行者: Owen</text
|
||||||
|
><text x="5" font-size="14px" y="71.7188" clip-path="url(#clipPath5)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>対象: Tracy</text
|
||||||
|
></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(430,310)" stroke-linecap="butt"
|
||||||
|
><path fill="none" d="M90.5 20.5 L11.5 20.5" clip-path="url(#clipPath6)"
|
||||||
|
/><path fill="white" d="M22.2583 14 L11 20.5 L22.2583 27 Z" clip-path="url(#clipPath6)" stroke="none"
|
||||||
|
/><path fill="none" stroke-miterlimit="10" stroke-dasharray="none" d="M22.2583 14 L11 20.5 L22.2583 27 Z" clip-path="url(#clipPath6)" stroke-linecap="square"
|
||||||
|
/></g
|
||||||
|
><g font-family="sans-serif" font-size="14px" transform="translate(430,310)"
|
||||||
|
><text x="32.2207" xml:space="preserve" y="16" clip-path="url(#clipPath6)" stroke="none"
|
||||||
|
>保有</text
|
||||||
|
></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(190,60)" stroke-linecap="butt"
|
||||||
|
><path fill="none" d="M99.5 10.5 L10.5 10.5" clip-path="url(#clipPath7)"
|
||||||
|
/><path fill="white" d="M88.7417 4 L100 10.5 L88.7417 17 Z" clip-path="url(#clipPath7)" stroke="none"
|
||||||
|
/><path fill="none" stroke-miterlimit="10" stroke-dasharray="none" d="M88.7417 4 L100 10.5 L88.7417 17 Z" clip-path="url(#clipPath7)" stroke-linecap="square"
|
||||||
|
/></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(170,150)" stroke-linecap="butt"
|
||||||
|
><path fill="none" d="M10.5 11.5 L10.5 40.5" clip-path="url(#clipPath8)"
|
||||||
|
/><path fill="none" d="M10.5 40.5 L230.5 40.5" clip-path="url(#clipPath8)"
|
||||||
|
/><path fill="none" d="M230.5 40.5 L230.5 150.5" clip-path="url(#clipPath8)"
|
||||||
|
/><path fill="none" d="M230.5 150.5 L250.5 160.5" clip-path="url(#clipPath8)"
|
||||||
|
/><path fill="white" d="M4 22.2583 L10.5 11 L17 22.2583 Z" clip-path="url(#clipPath8)" stroke="none"
|
||||||
|
/><path fill="none" stroke-miterlimit="10" stroke-dasharray="none" d="M4 22.2583 L10.5 11 L17 22.2583 Z" clip-path="url(#clipPath8)" stroke-linecap="square"
|
||||||
|
/></g
|
||||||
|
><g font-family="sans-serif" font-size="14px" transform="translate(170,150)"
|
||||||
|
><text x="14" xml:space="preserve" y="55.2188" clip-path="url(#clipPath8)" stroke="none"
|
||||||
|
>アクセス許可</text
|
||||||
|
></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(210,310)" stroke-linecap="butt"
|
||||||
|
><path fill="none" d="M89.5 20.5 L10.5 20.5" clip-path="url(#clipPath6)"
|
||||||
|
/><path fill="white" d="M78.7417 14 L90 20.5 L78.7417 27 Z" clip-path="url(#clipPath6)" stroke="none"
|
||||||
|
/><path fill="none" stroke-miterlimit="10" stroke-dasharray="none" d="M78.7417 14 L90 20.5 L78.7417 27 Z" clip-path="url(#clipPath6)" stroke-linecap="square"
|
||||||
|
/></g
|
||||||
|
><g font-family="sans-serif" font-size="14px" transform="translate(210,310)"
|
||||||
|
><text x="29.3696" xml:space="preserve" y="16" clip-path="url(#clipPath6)" stroke="none"
|
||||||
|
>発行</text
|
||||||
|
></g
|
||||||
|
></g
|
||||||
|
></svg
|
||||||
|
>
|
||||||
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,164 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
|
||||||
|
'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
|
||||||
|
<svg fill-opacity="1" xmlns:xlink="http://www.w3.org/1999/xlink" color-rendering="auto" color-interpolation="auto" text-rendering="auto" stroke="black" stroke-linecap="square" width="810" stroke-miterlimit="10" shape-rendering="auto" stroke-opacity="1" fill="black" stroke-dasharray="none" font-weight="normal" stroke-width="1" viewBox="0 10 810 330" height="330" xmlns="http://www.w3.org/2000/svg" font-family="'Dialog'" font-style="normal" stroke-linejoin="miter" font-size="12px" stroke-dashoffset="0" image-rendering="auto"
|
||||||
|
><!--Generated by the Batik Graphics2D SVG Generator--><defs id="genericDefs"
|
||||||
|
/><g
|
||||||
|
><defs id="defs1"
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath1"
|
||||||
|
><path d="M0 0 L2147483647 0 L2147483647 2147483647 L0 2147483647 L0 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath2"
|
||||||
|
><path d="M0 0 L0 70 L110 70 L110 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
><clipPath clipPathUnits="userSpaceOnUse" id="clipPath3"
|
||||||
|
><path d="M0 0 L0 290 L250 290 L250 0 Z"
|
||||||
|
/></clipPath
|
||||||
|
></defs
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(670,240)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(670,240)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="27" font-size="14px" y="42.5547" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>EUR:JPY</text
|
||||||
|
><text x="10" font-size="14px" y="58.6641" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>DomainID: B</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(550,240)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(550,240)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="27" font-size="14px" y="42.5547" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>JPY:EUR</text
|
||||||
|
><text x="10" font-size="14px" y="58.6641" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>DomainID: B</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(280,30)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><rect x="0.5" width="248.5" height="288.5" y="0.5" clip-path="url(#clipPath3)" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(280,30)" stroke-linecap="butt"
|
||||||
|
><rect fill="none" x="0.5" width="248.5" height="288.5" y="0.5" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="54" font-size="14px" y="18.1094" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>許可型DEX A</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(30,160)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(30,160)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="22" font-size="14px" y="50.6094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>USD:FOO</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(30,240)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(30,240)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="23" font-size="14px" y="50.6094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>BAR:BAZ</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(150,160)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(150,160)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="22" font-size="14px" y="50.6094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>FOO:USD</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(150,80)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(150,80)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="23" font-size="14px" y="50.6094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>FOO:XRP</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(30,80)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(30,80)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="23" font-size="14px" y="50.6094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>XRP:FOO</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(20,30)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><rect x="0.5" width="248.5" height="288.5" y="0.5" clip-path="url(#clipPath3)" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(20,30)" stroke-linecap="butt"
|
||||||
|
><rect fill="none" x="0.5" width="248.5" height="288.5" y="0.5" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="89" font-size="14px" y="18.1094" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オープンDEX</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(410,240)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(410,240)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="27" font-size="14px" y="42.5547" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>EUR:JPY</text
|
||||||
|
><text x="11" font-size="14px" y="58.6641" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>DomainID: A</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(290,160)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(290,160)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="22" font-size="14px" y="42.5547" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>USD:FOO</text
|
||||||
|
><text x="11" font-size="14px" y="58.6641" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>DomainID: A</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(410,80)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><path d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" stroke="none" clip-path="url(#clipPath2)"
|
||||||
|
/></g
|
||||||
|
><g transform="translate(410,80)"
|
||||||
|
><path fill="none" d="M0.5 0.5 L88.998 0.5 L88.998 21.6094 L109 21.6094 L109 69 L0.5 69 Z" clip-path="url(#clipPath2)"
|
||||||
|
/><path fill="none" d="M0.5 21.6094 L88.998 21.6094" clip-path="url(#clipPath2)"
|
||||||
|
/><text x="5" font-size="12px" y="16.1094" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>オーダーブック</text
|
||||||
|
><text x="23" font-size="14px" y="42.5547" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>FOO:XRP</text
|
||||||
|
><text x="11" font-size="14px" y="58.6641" clip-path="url(#clipPath2)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>DomainID: A</text
|
||||||
|
></g
|
||||||
|
><g fill="rgb(255,255,255)" fill-opacity="0" transform="translate(540,30)" stroke-opacity="0" stroke="rgb(255,255,255)"
|
||||||
|
><rect x="0.5" width="248.5" height="288.5" y="0.5" clip-path="url(#clipPath3)" stroke="none"
|
||||||
|
/></g
|
||||||
|
><g stroke-dasharray="8,5" stroke-miterlimit="5" transform="translate(540,30)" stroke-linecap="butt"
|
||||||
|
><rect fill="none" x="0.5" width="248.5" height="288.5" y="0.5" clip-path="url(#clipPath3)"
|
||||||
|
/><text x="54" font-size="14px" y="18.1094" clip-path="url(#clipPath3)" font-family="sans-serif" stroke="none" xml:space="preserve"
|
||||||
|
>許可型DEX B</text
|
||||||
|
></g
|
||||||
|
></g
|
||||||
|
></svg
|
||||||
|
>
|
||||||
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,113 @@
|
|||||||
|
---
|
||||||
|
seo:
|
||||||
|
description: 許可型メインインスタンスの定義と詳細について
|
||||||
|
labels:
|
||||||
|
- コンプライアンス
|
||||||
|
- 分散型取引所
|
||||||
|
---
|
||||||
|
# 許可型DEX
|
||||||
|
|
||||||
|
許可型DEXは、XRP Ledgerの[分散型取引所(DEX)](./index.md)内での取引を制御する環境です。許可型DEXでの取引は、オープンDEXと同様ですが、[_許可型ドメイン_](./permissioned-domains.md)によって誰がオファーを置くことができるか、またはオファーを受け入れることができるかを制御します。許可型DEXを利用することで、規制下にある企業はXRP Ledgerでの取引に参加し、取引先のすべての相手方が適切に検証されていることを確認することができます。
|
||||||
|
|
||||||
|
XRP Ledgerブロックチェーン内には、複数の許可型DEXが存在することができます。それぞれは、許可型ドメインと関連付けられており、そのDEXへのアクセスを許可するリストとして機能します。許可型DEX内に置かれた取引は、同じ許可型DEX内の他の取引にのみ実行できます。各許可型DEXは、必要に応じて、任意の数の通貨ペアの注文帳を持つことができます。
|
||||||
|
|
||||||
|
|
||||||
|
## 背景: 許可型DEXの必要性
|
||||||
|
|
||||||
|
XRP Ledgerは、ローンチ以来、単一の、_オープンDEX_ を持っています。XRPLアカウントを持っていれば誰でもこのDEXで取引することができ、システムは誰がオファーを作成したに関係なく、マッチングする注文、もしくはオファーを自動的に約定します。注文はまた、クロスカレンシー支払いに流動性を提供し、潜在的に1つのアトミック取引の一部として複数の取引を実行することができます。
|
||||||
|
|
||||||
|
システムは、アカウントの背後にある人々や組織について何も知らないため、ある取引の相手方が誰かは確実ではありません。しかし、経済制裁や金融規制は、犯罪者、テロリスト、または特定の国との取引に対して厳格なルールを課しています。これらの制限により、規制下にある金融機関は、オープンDEXでの取引に対するリスクを負うことを望んでいないかもしれません。
|
||||||
|
|
||||||
|
さらなる背景情報:
|
||||||
|
|
||||||
|
- [分散型取引所](./index.md)
|
||||||
|
- [オファー](./offers.md)
|
||||||
|
- [許可型ドメイン](./permissioned-domains.md)
|
||||||
|
|
||||||
|
|
||||||
|
## 許可型DEXの重要な役割
|
||||||
|
|
||||||
|
許可型DEXを使用するには、以下の役割と責任を持つ参加者が必要です。
|
||||||
|
|
||||||
|
- 少なくとも2人のトレーダーがマッチングするオファーを置く必要があります。例えば、1人がXRPをUSDに交換し、もう1人がUSDをXRPに交換します。
|
||||||
|
- 許可型ドメインの所有者。許可型ドメインへのアクセスを許可する資格情報を制御します。
|
||||||
|
- 資格情報(Credentials)の発行者。許可型ドメインへのアクセスを許可する資格情報を発行します。
|
||||||
|
|
||||||
|
1つのアカウントがこれらの役割のいずれかを複数回果たすことができます。例えば、許可型ドメインの所有者、資格情報の発行者、およびトレーダーの3つの役割を同時に果たすことができます。唯一の制限は、トレーダーが異なるアカウントである必要があることです。
|
||||||
|
|
||||||
|
{% inline-svg file="./permissioned-dex-roles.svg" /%}
|
||||||
|
|
||||||
|
_図: 許可型オーダーブック。Owenは許可型ドメインの所有者であり、許可型ドメインの承認された資格情報の1つの発行者です。TracyはOwenが発行した適切な資格情報を保有しているため、許可型オーダーブックで取引することができます。_
|
||||||
|
|
||||||
|
|
||||||
|
## 許可型DEXの構造を理解する: オファーの種類と相互作用
|
||||||
|
|
||||||
|
許可型DEX機能を使用すると、取引オファーは _オープン_、_許可型_、または _ハイブリッド_ のいずれかになります。
|
||||||
|
|
||||||
|
### オープンオファー
|
||||||
|
|
||||||
|
オープンオファーはオープンDEXを使用し、他のオープンなオファー、ハイブリッドなオファー、[自動マーケットメーカー(AMM)](./automated-market-makers.md)、またはオファーとAMMの組み合わせによってマッチングすることができます。_オープンオファー_ は、許可型DEXがない場合のXRPLのDEXの動作と変わりません。
|
||||||
|
|
||||||
|
### 許可型オファー
|
||||||
|
|
||||||
|
許可型オファーはドメインIDを指定し、そのドメインIDに一致する許可型ドメインが存在し、オファーを置いたアカウントがそのドメインにアクセスできる場合にのみ有効です。許可型オファーは、指定されたドメインと通貨ペアのオーダーブックに配置され、オープンDEXのオーダーブックとは別です。
|
||||||
|
|
||||||
|
許可型オファーは、同じドメインIDを指定する許可型オファーとのみマッチングすることができます。[クロスカレンシー支払い](../../payment-types/cross-currency-payments.md)もドメインIDを指定することができ、その場合は、対応する許可型DEXからのみオファーを約定するように制限されます。許可型DEX内の取引は、必要な注文がすべて同じ許可型DEX内に存在する限り、[オートブリッジング](./autobridging.md)を使用することができます。
|
||||||
|
|
||||||
|
### ハイブリッドオファー
|
||||||
|
|
||||||
|
ハイブリッドオファーはドメインIDを指定し、ハイブリッドフラグを付けます。許可型オファーと同様に、指定された許可型ドメインが存在し、オファーを置いたアカウントがそのドメインにアクセスできる場合にのみ有効です。ただし、ハイブリッドオファーは、指定されたDEXとオープンDEXの両方でオファーをマッチングすることができます。
|
||||||
|
|
||||||
|
ハイブリッドオファーは、オープンDEXのオーダーブックと、その通貨ペアの許可型ドメイン固有のオーダーブックの両方で追跡され、どちらかのオファーとマッチングすることができます。配置された場合、許可型DEXのオファーと優先的にマッチングします。
|
||||||
|
|
||||||
|
|
||||||
|
### オープン、ハイブリッド、許可型オファーのマッチング方法
|
||||||
|
|
||||||
|
要約すると、以下の表に、どのオファーがマッチングできるかをまとめています:
|
||||||
|
|
||||||
|
| オファー/支払いタイプ | オープンオファー | ハイブリッドオファー | 許可型オファー | AMM |
|
||||||
|
|-----------------------|------------------|----------------------|-------------------|-----|
|
||||||
|
| オープン | ✅ | ✅ | ❌ | ✅ |
|
||||||
|
| ハイブリッド | ✅ | ✅ | ✅ (同じドメイン) | ✅ |
|
||||||
|
| 許可型 | ❌ | ❌ | ✅ (同じドメイン) | ❌ |
|
||||||
|
|
||||||
|
許可型DEXを表すための単一のレジャーエントリはありません。 それは暗黙的に、同じドメインIDを持つすべてのオーダーブックとして存在します。指定されたドメインIDを使用して有効なオファーが配置されると、そのオーダーブックが作成され、空になると自動的に削除されます。
|
||||||
|
|
||||||
|
1つのトランザクションは、同じドメインIDを持つ複数のオーダーブックを使用できます。つまり、同じ許可型DEX内の異なる通貨ペアです。それは、長い[クロスカレンシー支払い](../../payment-types/cross-currency-payments.md)の一部として、またはオートブリッジングを介して使用することができます。ハイブリッドオファーは、許可型オファーとオープンオファーの混合をマッチングすることができますが、トランザクションは複数の異なるドメインを使用することはできません。
|
||||||
|
|
||||||
|
どのDEXでも利用可能な流動性の量と最良の交換レートは、そのDEXに配置されたオファーによって異なる場合があります。一部のトレーダーは、価格差を利用するために複数の許可型DEXとオープンDEXで取引することを選択するかもしれませんが、他のトレーダーは、そのコンプライアンス要件に応じて、1つのドメインで厳密に取引するかもしれません。
|
||||||
|
|
||||||
|
{% inline-svg file="./permissioned-dex-structure.svg" /%}
|
||||||
|
|
||||||
|
_図: オープンDEXと2つの異なる許可型DEX。それぞれが、可能な通貨ペアのサブセットの注文帳を含んでいます。_
|
||||||
|
|
||||||
|
|
||||||
|
### 無効な許可型オファー
|
||||||
|
|
||||||
|
オープンDEXでオファーが資金不足になる方法に加えて、許可型DEXでのオファーは _無効_ になる可能性があります。無効なオファーは、資金不足のオファーと同じ方法で処理され、トランザクションがそれらを含むオーダーブックを変更するたびに自動的に削除されます。トランザクションがそれらを削除するまで、レジャーデータ内に無期限に残ることができますが、無効な場合は約定できません。
|
||||||
|
|
||||||
|
許可型オファーが無効になる理由には、以下のようなものがあります。
|
||||||
|
|
||||||
|
- オファーを置いたアカウントが保有する資格情報が期限切れまたは削除された。
|
||||||
|
- 許可型ドメインが更新され、アクセスを許可する資格情報のセットが変更され、オファーを置いたアカウントが新しい資格情報を保有していない。
|
||||||
|
- 許可型ドメインが削除された。
|
||||||
|
|
||||||
|
資金不足のオファーと同様に、オファーが一時的に無効になり、再度有効になる可能性があります。例えば、トレーダーの資格情報が許可型ドメインへのアクセスを許可する資格情報が期限切れになった場合、そのトレーダーの許可型DEXでのオファーは無効になります。しかし、資格情報が更新された場合、すでに削除されていないオファーは自動的に有効になります。
|
||||||
|
|
||||||
|
### 許可型DEXの制限
|
||||||
|
|
||||||
|
許可型DEX機能は、**PermissionedDEX** Amendmentによって有効になり、[Credentials](../../decentralized-storage/credentials.md)と[Permissioned Domains](./permissioned-domains.md) Amendmentに依存しているため、それらのAmendmentが _すべて_ 有効になるまで利用できません。
|
||||||
|
|
||||||
|
#### AMMとの互換性なし
|
||||||
|
|
||||||
|
許可型DEXは、[自動マーケットメーカー(AMM)](../../tokens/decentralized-exchange/automated-market-makers.md)と互換性がありません。許可型オファーと許可型支払いはAMMで約定できません。また、許可型ドメインによってAMMへのアクセスを制限することはできません。オープンDEXを使用する取引は、場合によってはハイブリッドオファーを消費し、同じトランザクションでAMMを使用することができますが、ドメインを指定するトランザクションではAMMを使用することはできません。
|
||||||
|
|
||||||
|
**許可型DEXは独立しています**
|
||||||
|
|
||||||
|
許可型DEXは独立しており、それぞれが独自のオーダーブックとオファーを持っています。1つのトランザクションは、複数の許可型DEXで取引することはできません。また、複数の許可型DEXから流動性を集約することはできません。ハイブリッドオファーは、1つの許可型DEXとオープンDEXの両方を使用することができますが、複数の異なる許可型DEXを使用することはできません。
|
||||||
|
|
||||||
|
#### 許可型DEXのセキュリティに関する考慮事項
|
||||||
|
|
||||||
|
許可型DEXのセキュリティと公平性は、許可型ドメインの所有者と、そのドメインへのアクセスを許可する資格情報の発行者に依存します。基本的に、各資格情報の定義とその資格情報を取得するための要件は、資格情報の発行者によって定義され、適用されているため、許可型ドメインの存在は、実際に誰がそれを使用できるかについて、本質的に何も意味しません。
|
||||||
|
|
||||||
|
資格情報の発行者は、資格情報を発行または取り消すことができます。もし、それらが信頼できないか、侵害されている場合、それらの資格情報を受け入れる許可型ドメインも同様です。同様に、ドメインの所有者は、ドメインの承認された資格情報のリストを変更して、ドメインへのアクセスを許可または拒否することができるため、もし、それらが信頼できないか、侵害されている場合、ドメインも同様です。
|
||||||
@@ -36,4 +36,4 @@ _([PermissionedDomains amendment][]が必要です {% not-enabled /%})_
|
|||||||
- 単一資産Vaultと貸付プロトコル
|
- 単一資産Vaultと貸付プロトコル
|
||||||
- 許可型DEX
|
- 許可型DEX
|
||||||
|
|
||||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -313,9 +313,6 @@ _**公開ハブを使用してバリデータをネットワークに接続す
|
|||||||
|
|
||||||
4. 記入したGoogleフォームを送信すると、ドメイン検証の成否を通知するメールがXRP Chartsから送信されます。ドメイン検証が成功した場合は、XRP Chartsの[バリデータレジストリー](https://xrpcharts.ripple.com/#/validators)にバリデータとドメインが表示されます。
|
4. 記入したGoogleフォームを送信すると、ドメイン検証の成否を通知するメールがXRP Chartsから送信されます。ドメイン検証が成功した場合は、XRP Chartsの[バリデータレジストリー](https://xrpcharts.ripple.com/#/validators)にバリデータとドメインが表示されます。
|
||||||
|
|
||||||
<!--{ ***TODO: For the future - add a new section or separate document: "Operating a Trusted Validator" -- things that you need to be aware of once your validator has been added to a UNL and is participating in consensus. We should tell the user what to expect once they are listed in a UNL. How to tell if your validator is participating in the consensus process? How to tell if something isn't right with your validator - warning signs that they should look out for? How to tell if your validator has fallen out of agreement - what is the acceptable vs unacceptable threshold? Maybe provide a script that will alert them when something is going wrong.*** }-->
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## バリデータキーの破棄
|
## バリデータキーの破棄
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ rippled json ledger_entry '{ "index": "7DB0788C020F02780A673DC74757F23823FA3014C
|
|||||||
アドレスから[AccountRootエントリ](../../../protocol/ledger-data/ledger-entry-types/accountroot.md)を取得します。これは[account_infoメソッド][]とほぼ同じです。
|
アドレスから[AccountRootエントリ](../../../protocol/ledger-data/ledger-entry-types/accountroot.md)を取得します。これは[account_infoメソッド][]とほぼ同じです。
|
||||||
|
|
||||||
| フィールド | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:----------- ---|:--------------------|:----------------------|
|
|:---------------|:--------------------|:----------------------|
|
||||||
| `account_root` | 文字列 - [アドレス][] | 取得する[AccountRootエントリ](../../../protocol/ledger-data/ledger-entry-types/accountroot.md)の標準アドレス。 |
|
| `account_root` | 文字列 - [アドレス][] | 取得する[AccountRootエントリ](../../../protocol/ledger-data/ledger-entry-types/accountroot.md)の標準アドレス。 |
|
||||||
|
|
||||||
{% tabs %}
|
{% tabs %}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
---
|
---
|
||||||
html: book_offers.html
|
|
||||||
parent: path-and-order-book-methods.html
|
|
||||||
seo:
|
seo:
|
||||||
description: オーダーブックと呼ばれる、2つの通貨間のオファーのリストを取得します。
|
description: オーダーブックと呼ばれる、2つの通貨間のオファーのリストを取得します。
|
||||||
labels:
|
labels:
|
||||||
@@ -10,7 +8,7 @@ labels:
|
|||||||
# book_offers
|
# book_offers
|
||||||
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/rpc/handlers/BookOffers.cpp "Source")
|
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/rpc/handlers/BookOffers.cpp "Source")
|
||||||
|
|
||||||
`book_offers`メソッドは、[オーダーブック](http://www.investopedia.com/terms/o/order-book.asp)と呼ばれる、2つの通貨間のオファーのリストを取得します。結果が非常に大きい場合、結果の一部がマーカー付きで返されます。これにより、その後のリクエストは前回のリクエストで終わった箇所から再開できます。
|
`book_offers`メソッドは、2つの通貨間の[オファー](../../../../concepts/tokens/decentralized-exchange/offers.md)のリストを取得します。これは、_オーダーブック_ とも呼ばれます。レスポンスは、[資金供給のないオファー](../../../../concepts/tokens/decentralized-exchange/offers.md#オファーのライフサイクル)を省略し、残りの各オファーの合計に対して資金供給されている割合を報告します。
|
||||||
|
|
||||||
## リクエストのフォーマット
|
## リクエストのフォーマット
|
||||||
リクエストのフォーマットの例:
|
リクエストのフォーマットの例:
|
||||||
@@ -69,15 +67,16 @@ rippled book_offers 'USD/rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' 'EUR/rvYAfWj5gh67oV6
|
|||||||
|
|
||||||
リクエストには以下のパラメーターが含まれます。
|
リクエストには以下のパラメーターが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 必須? | 説明 |
|
||||||
|:---------------|:-------------------------------------------|:-------------------------------|
|
|:---------------|:-------------------------|:-------|:-------------------------------|
|
||||||
| `ledger_hash` | 文字列 | _(省略可)_ 使用するレジャーバージョンの20バイトの16進文字列。([レジャーの指定][]をご覧ください) |
|
| `taker_gets` | オブジェクト | はい | オファーを受諾するアカウントが受け取る通貨を、[通貨額][通貨額]と同様に、`currency`フィールドと`issuer`フィールドを持つオブジェクトとして指定します(XRPの場合はissuerを省略)。 |
|
||||||
| `ledger_index` | 文字列または符号なし整数 | _(省略可)_ 使用するレジャーの[レジャーインデックス][]、またはレジャーを自動的に選択するためのショートカット文字列。([レジャーの指定][]をご覧ください) |
|
| `taker_pays` | オブジェクト | はい | オファーを受諾するアカウントが支払う通貨を、[通貨額][通貨額]と同様に、`currency`フィールドと`issuer`フィールドを持つオブジェクトとして指定します(XRPの場合はissuerを省略)。 |
|
||||||
| `limit` | 符号なし整数 | _(省略可)_ 指定されている場合、サーバはこの制限を超える数のオファーを結果に含めません。資金供給のないオファーはサーバにより省略されるため、返される結果の総数はこの制限よりも少ないことがあります。 |
|
| `domain` | [ハッシュ][] | いいえ | 許可型ドメインのレジャーエントリID。指定された場合、オープンDEXの代わりに、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)からオファーを返します。 _([PermissionedDEX amendment][]が必要です。 {% not-enabled /%})_ |
|
||||||
| `marker` | [マーカー][] | _(省略可)_ 以前にページネーションされたレスポンスの値。そのレスポンスを停止した箇所からデータの取得を再開します。 |
|
| `ledger_hash` | [ハッシュ][] | いいえ | 使用するレジャーバージョンの20バイトの16進文字列。([レジャーの指定][]をご覧ください) |
|
||||||
| `taker` | 文字列 | _(省略可)_ パースペクティブとして使用するアカウントの[アドレス][]。このアカウントが発行した[資金供給のないオファー](../../../../concepts/tokens/decentralized-exchange/offers.md#オファーのライフサイクル)は常にレスポンスに含まれます。(これを使用して、キャンセルしたい各自のオーダーを検索できます。) |
|
| `ledger_index` | [レジャーインデックス][] | いいえ | 使用するレジャーの[レジャーインデックス][]、またはレジャーを自動的に選択するためのショートカット文字列。([レジャーの指定][]をご覧ください) |
|
||||||
| `taker_gets` | オブジェクト | オファーを受諾するアカウントが受け取る通貨を、[通貨額][通貨額]と同様に、`currency`フィールドと`issuer`フィールドを持つオブジェクトとして指定します(XRPの場合はissuerを省略)。 |
|
| `limit` | 整数 | いいえ | 指定されている場合、サーバはこの制限を超える数のオファーを結果に含めません。資金供給のないオファーはサーバにより省略されるため、返される結果の総数はこの制限よりも少ないことがあります。 |
|
||||||
| `taker_pays` | オブジェクト | オファーを受諾するアカウントが支払う通貨を、[通貨額][通貨額]と同様に、`currency`フィールドと`issuer`フィールドを持つオブジェクトとして指定します(XRPの場合はissuerを省略)。 |
|
| `taker` | 文字列 | いいえ | パースペクティブとして使用するアカウントの[アドレス][]。このアカウントが発行した[資金供給のないオファー](../../../../concepts/tokens/decentralized-exchange/offers.md#オファーのライフサイクル)は常にレスポンスに含まれます。(これを使用して、キャンセルしたい各自のオーダーを検索できます。) |
|
||||||
|
|
||||||
|
|
||||||
## レスポンスのフォーマット
|
## レスポンスのフォーマット
|
||||||
|
|
||||||
@@ -161,26 +160,97 @@ rippled book_offers 'USD/rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' 'EUR/rvYAfWj5gh67oV6
|
|||||||
```
|
```
|
||||||
{% /tab %}
|
{% /tab %}
|
||||||
|
|
||||||
|
{% tab label="Commandline" %}
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"result" : {
|
||||||
|
"ledger_current_index" : 56867201,
|
||||||
|
"offers" : [
|
||||||
|
{
|
||||||
|
"Account" : "rnixnrMHHvR7ejMpJMRCWkaNrq3qREwMDu",
|
||||||
|
"BookDirectory" : "7E5F614417C2D0A7CEFEB73C4AA773ED5B078DE2B5771F6D56038D7EA4C68000",
|
||||||
|
"BookNode" : "0000000000000000",
|
||||||
|
"Flags" : 131072,
|
||||||
|
"LedgerEntryType" : "Offer",
|
||||||
|
"OwnerNode" : "0000000000000000",
|
||||||
|
"PreviousTxnID" : "E43ADD1BD4AC2049E0D9DE6BC279B7FD95A99C8DE2C4694A4A7623F6D9AAAE29",
|
||||||
|
"PreviousTxnLgrSeq" : 47926685,
|
||||||
|
"Sequence" : 219,
|
||||||
|
"TakerGets" : {
|
||||||
|
"currency" : "EUR",
|
||||||
|
"issuer" : "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"value" : "2.459108753792364"
|
||||||
|
},
|
||||||
|
"TakerPays" : {
|
||||||
|
"currency" : "USD",
|
||||||
|
"issuer" : "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"value" : "24.59108753792364"
|
||||||
|
},
|
||||||
|
"index" : "3087B4828C6B5D8595EA325D69C0F396C57452893647799493A38F2C164990AB",
|
||||||
|
"owner_funds" : "2.872409153061363",
|
||||||
|
"quality" : "10"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Account" : "rKwjWCKBaASEvtHCxtvReNd2i9n8DxSihk",
|
||||||
|
"BookDirectory" : "7E5F614417C2D0A7CEFEB73C4AA773ED5B078DE2B5771F6D56038D7EA4C68000",
|
||||||
|
"BookNode" : "0000000000000000",
|
||||||
|
"Flags" : 131072,
|
||||||
|
"LedgerEntryType" : "Offer",
|
||||||
|
"OwnerNode" : "0000000000000000",
|
||||||
|
"PreviousTxnID" : "B63B2ECD124FE6B02BC2998929517266BD221A02FEE51DDE4992C1BCB7E86CD3",
|
||||||
|
"PreviousTxnLgrSeq" : 43166305,
|
||||||
|
"Sequence" : 19,
|
||||||
|
"TakerGets" : {
|
||||||
|
"currency" : "EUR",
|
||||||
|
"issuer" : "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"value" : "3.52"
|
||||||
|
},
|
||||||
|
"TakerPays" : {
|
||||||
|
"currency" : "USD",
|
||||||
|
"issuer" : "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"value" : "35.2"
|
||||||
|
},
|
||||||
|
"index" : "89865F2C70D1140796D9D249AC2ED765AE2D007A52DEC6D6D64CCB1A77A6EB7F",
|
||||||
|
"owner_funds" : "3.523192614770459",
|
||||||
|
"quality" : "10",
|
||||||
|
"taker_gets_funded" : {
|
||||||
|
"currency" : "EUR",
|
||||||
|
"issuer" : "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"value" : "3.516160294182094"
|
||||||
|
},
|
||||||
|
"taker_pays_funded" : {
|
||||||
|
"currency" : "USD",
|
||||||
|
"issuer" : "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"value" : "35.16160294182094"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"status" : "success",
|
||||||
|
"validated" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
{% /tab %}
|
||||||
|
|
||||||
{% /tabs %}
|
{% /tabs %}
|
||||||
|
|
||||||
このレスポンスは[標準フォーマット][]に従っており、正常に完了した場合は結果に次のフィールドが含まれます。
|
このレスポンスは[標準フォーマット][]に従っており、正常に完了した場合は結果に次のフィールドが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:-----------------------|:--------------------------|:------------------------|
|
|:-----------------------|:-------------------------|:------------------------|
|
||||||
| `ledger_current_index` | 数値 - [レジャーインデックス][] | _(`ledger_current_index`が指定されている場合は省略)_ この情報の取得時に使用した、現在処理中のレジャーバージョンの[レジャーインデックス][]。 |
|
| `ledger_current_index` | [レジャーインデックス][] | _(`ledger_current_index`が指定されている場合は省略)_ この情報の取得時に使用した、現在処理中のレジャーバージョンの[レジャーインデックス][]。 |
|
||||||
| `ledger_index` | 数値 - [レジャーインデックス][] | _(`ledger_current_index`が指定されている場合は省略可)_ リクエストに従って、このデータの取得時に使用されたレジャーバージョンのレジャーインデックス。 |
|
| `ledger_index` | [レジャーインデックス][] | _(`ledger_current_index`が指定されている場合は省略)_ リクエストに従って、このデータの取得時に使用されたレジャーバージョンのレジャーインデックス。 |
|
||||||
| `ledger_hash` | 文字列 - [ハッシュ][] | _(省略される場合があります)_ リクエストに従って、このデータの取得時に使用されたレジャーバージョンの識別用ハッシュ。 |
|
| `ledger_hash` | [ハッシュ][] | _(省略される場合があります)_ リクエストに従って、このデータの取得時に使用されたレジャーバージョンの識別用ハッシュ。 |
|
||||||
| `marker` | [マーカー][] | _(省略される場合があります)_ レスポンスがページネーションされていることを示す、サーバが定義した値。この値を次のコールに渡して、このコールで終わった箇所から再開します。この後に情報ページがない場合は省略されます。 |
|
| `offers` | 配列 | Offerオブジェクトの配列。詳細は下記にて。 |
|
||||||
| `offers` | 配列 | Offerオブジェクトの配列。各オブジェクトには[Offer オブジェクト](../../../protocol/ledger-data/ledger-entry-types/offer.md)のフィールドが含まれています。 |
|
|
||||||
|
|
||||||
`offers`配列の要素には、Offerの標準フィールドの他に以下のフィールドが含まれます。
|
`offers`配列の各要素には、[Offerエントリ][]の標準フィールドの他に、以下の追加フィールドが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:--------------------|:---------------------------------|:--------------------|
|
|:--------------------|:-----------|:--------------------|
|
||||||
| `owner_funds` | 文字列 | オファーの発行元が保有する取引可能なTakerGets通貨の金額。(XRPはdrop単位で表されます。その他のすべての通貨は10進数値として表されます。)1人のトレーダーの複数のオファーが同一のブックに含まれている場合、このフィールドは最高順位のオファーにのみ含まれます。 |
|
| `owner_funds` | 文字列 | オファーの発行元が保有する取引可能なTakerGets通貨の金額。(XRPはdrop単位で表されます。その他のすべての通貨は10進数値として表されます。)1人のトレーダーの複数のオファーが同一のブックに含まれている場合、このフィールドは最高順位のオファーにのみ含まれます。 |
|
||||||
| `taker_gets_funded` | 文字列(XRP)またはオブジェクト(XRP以外) | (部分的に資金供給されているオファーのみに含まれます)オファーの資金供給ステータスが指定されている場合に、受取人が受領できる最大通貨額。 |
|
| `taker_gets_funded` | [通貨額][] | (部分的に資金供給されているオファーのみに含まれます) オファーの資金供給ステータスが指定されている場合に、受取人が受領できる最大通貨額。 |
|
||||||
| `taker_pays_funded` | 文字列(XRP)またはオブジェクト(XRP以外) | (部分的に資金供給されているオファーのみに含まれます)オファーの資金供給ステータスが指定されている場合に、受取人が支払う最大通貨額。 |
|
| `taker_pays_funded` | [通貨額][] | (部分的に資金供給されているオファーのみに含まれます) オファーの資金供給ステータスが指定されている場合に、受取人が支払う最大通貨額。 |
|
||||||
| `quality` | 文字列 | 為替レート(`taker_pays`を`taker_gets`で割った比率)。公正を期すため、同じクオリティのオファーは先入れ先出しで自動的に受諾されます。(つまり、複数の人々が通貨を同じレートで取引するオファーを出した場合、最も古いオファーが最初に受諾されます。) |
|
| `quality` | 文字列 | 為替レート(`taker_pays`を`taker_gets`で割った比率)。公正を期すため、同じクオリティのオファーは先入れ先出しで自動的に約定されます。(つまり、複数の人々が通貨を同じレートで取引するオファーを出した場合、最も古いオファーが最初に受諾されます。) |
|
||||||
|
|
||||||
## 考えられるエラー
|
## 考えられるエラー
|
||||||
|
|
||||||
|
|||||||
@@ -55,14 +55,15 @@ path_findコマンドには3種類のモード(サブコマンド)があり
|
|||||||
|
|
||||||
リクエストには以下のパラメーターが含まれます。
|
リクエストには以下のパラメーターが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 必須? | 説明 |
|
||||||
|:----------------------|:-----------------|:----------------------------------|
|
|:----------------------|:-------------------------|:-------|:---------------------------|
|
||||||
| `subcommand` | 文字列 | `"create"`を使用してcreateサブコマンドを送信します。 |
|
| `subcommand` | 文字列 | はい | `"create"`を使用してcreateサブコマンドを送信します。 |
|
||||||
| `source_account` | 文字列 | 探索するパスの送金元アカウントの一意のアドレス。(つまり、支払いを送金するアカウントです。) |
|
| `source_account` | 文字列 - [アドレス][] | はい | 検索するパスの送金元アカウントのドレス。(つまり、支払いを送金するアカウント) |
|
||||||
| `destination_account` | 文字列 | 探索するパスの送金先アカウントの一意のアドレス。(つまり、支払いを受領するアカウントです。) |
|
| `destination_account` | 文字列 - [アドレス][] | はい | 検索するパスの送金先アカウントのアドレス。(つまり、支払いを受領するアカウント) |
|
||||||
| `destination_amount` | 文字列またはオブジェクト | 送金先アカウントがトランザクションで受領する[通貨額][]。**特殊なケース:**{% badge href="https://github.com/XRPLF/rippled/releases/tag/0.30.0" %}新規: rippled 0.30.0{% /badge %}`value`フィールドには`"-1"`(XRPの場合)または-1(XRP以外の通貨の場合)を指定できます。これにより、最大限の額を送金できるパスがリクエストされます。ただし`send_max`が指定されている場合は、指定額を上回る額が支払われることはありません。 |
|
| `destination_amount` | [通貨額][] | はい | 送金先アカウントが受け取る金額。 **特殊ケース:** XRPの場合、`"-1"`を指定するか、トークンの場合、`value`フィールドの内容として-1を指定できます。これにより、`send_max`で指定された金額を超えない範囲で、可能な限り多くの送金先への送金を要求します。 |
|
||||||
| `send_max` | 文字列またはオブジェクト | _(省略可)_ トランザクションに使用する[通貨額][]。`source_currencies`と同時に指定することはできません。{% badge href="https://github.com/XRPLF/rippled/releases/tag/0.30.0" %}新規: rippled 0.30.0{% /badge %} |
|
| `domain` | 文字列 - [ハッシュ][] | いいえ | 許可型ドメインのレジャーエントリID。指定された場合、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用するパスを返します。 _([PermissionedDEX amendment][]が必要です。 {% not-enabled /%})_ |
|
||||||
| `paths` | 配列 | _(省略可)_ チェックする[ペイメントパス](../../../../concepts/tokens/fungible-tokens/paths.md)を表すオブジェクトの配列。すでに判明している特定パスの変更内容を常に把握する場合や、特定パスに沿った支払いにかかる総コストを確認する場合にこのフィールドを使用できます。 |
|
| `paths` | 配列 | いいえ | チェックする[支払いパス](../../../../concepts/tokens/fungible-tokens/paths.md)を表すオブジェクトの配列。すでに判明している特定パスの変更内容を常に把握する場合や、特定パスに沿った支払いにかかる総コストを確認する場合にこのフィールドを使用できます。 |
|
||||||
|
| `send_max` | [通貨額][] | いいえ | トランザクションに使用する[通貨額][]。`source_currencies`と同時に指定することはできません。|
|
||||||
|
|
||||||
サーバは`source_currencies`および`bridges`フィールドも認識しますが、これらのフィールドを使用した場合の結果は保証されません。これらのフィールドは将来のために予約されているものと考えてください。
|
サーバは`source_currencies`および`bridges`フィールドも認識しますが、これらのフィールドを使用した場合の結果は保証されません。これらのフィールドは将来のために予約されているものと考えてください。
|
||||||
|
|
||||||
@@ -444,8 +445,8 @@ path_findコマンドには3種類のモード(サブコマンド)があり
|
|||||||
|
|
||||||
この初期レスポンスは[標準フォーマット](../../api-conventions/response-formatting.md)に従っており、正常に完了した場合は次のフィールドが含まれています。
|
この初期レスポンスは[標準フォーマット](../../api-conventions/response-formatting.md)に従っており、正常に完了した場合は次のフィールドが含まれています。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:----------------------|:-----------------|:----------------------------------|
|
|:----------------------|:-----------------|:---------------------------|
|
||||||
| `alternatives` | 配列 | 以下に説明する、提案される[パス](../../../../concepts/tokens/fungible-tokens/paths.md)のオブジェクトの配列。空の場合、送金元アカウントと送金先アカウントを結ぶパスが見つかりませんでした。 |
|
| `alternatives` | 配列 | 以下に説明する、提案される[パス](../../../../concepts/tokens/fungible-tokens/paths.md)のオブジェクトの配列。空の場合、送金元アカウントと送金先アカウントを結ぶパスが見つかりませんでした。 |
|
||||||
| `destination_account` | 文字列 | トランザクションを受信するアカウントの一意のアドレス。 |
|
| `destination_account` | 文字列 | トランザクションを受信するアカウントの一意のアドレス。 |
|
||||||
| `destination_amount` | 文字列またはオブジェクト | 送金先がトランザクションで受領する[通貨額][]。 |
|
| `destination_amount` | 文字列またはオブジェクト | 送金先がトランザクションで受領する[通貨額][]。 |
|
||||||
@@ -455,8 +456,8 @@ path_findコマンドには3種類のモード(サブコマンド)があり
|
|||||||
|
|
||||||
`alternatives`配列の各要素は、1つの送金元通貨(開始アカウントが保有)から送金先アカウントへのパスと通貨を表すオブジェクトです。このオブジェクトのフィールドを次に示します。
|
`alternatives`配列の各要素は、1つの送金元通貨(開始アカウントが保有)から送金先アカウントへのパスと通貨を表すオブジェクトです。このオブジェクトのフィールドを次に示します。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:-----------------|:-----------------|:---------------------------------------|
|
|:-----------------|:-----------------|:--------------------------------|
|
||||||
| `paths_computed` | 配列 | [ペイメントパス](../../../../concepts/tokens/fungible-tokens/paths.md)を定義するオブジェクトの配列。 |
|
| `paths_computed` | 配列 | [ペイメントパス](../../../../concepts/tokens/fungible-tokens/paths.md)を定義するオブジェクトの配列。 |
|
||||||
| `source_amount` | 文字列またはオブジェクト | 送金先が必要な額を受領するために、送金元がこのパスで送金する必要がある[通貨額][]。 |
|
| `source_amount` | 文字列またはオブジェクト | 送金先が必要な額を受領するために、送金元がこのパスで送金する必要がある[通貨額][]。 |
|
||||||
|
|
||||||
@@ -521,17 +522,17 @@ path_find createリクエストからの非同期フォローアップの例を
|
|||||||
|
|
||||||
リクエストには以下のパラメーターが含まれます。
|
リクエストには以下のパラメーターが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:-------------|:-------|:-------------------------------------------|
|
|:-------------|:-------|:------------------------------------|
|
||||||
| `subcommand` | 文字列 | closeサブコマンドを送信するため`"close"`を使用します。 |
|
| `subcommand` | 文字列 | closeサブコマンドを送信するため`"close"`を使用します。 |
|
||||||
|
|
||||||
### レスポンスのフォーマット
|
### レスポンスのフォーマット
|
||||||
|
|
||||||
Pathfindingリクエストが正常にクローズされた場合、レスポンスは[`path_find create`](#path_find-create)に対する初期レスポンスと同じフォーマットであり、されに以下のフィールドが含まれます。
|
Pathfindingリクエストが正常にクローズされた場合、レスポンスは[`path_find create`](#path_find-create)に対する初期レスポンスと同じフォーマットであり、されに以下のフィールドが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:---------|:--------|:--------------------------------------------------------|
|
|:-----------|:--------|:-------------------------------------------------|
|
||||||
| `closed` | ブール値 | 値が`true`の場合、これは`path_find close`コマンドに対するレスポンスです。 |
|
| `closed` | ブール値 | 値が`true`の場合、これは`path_find close`コマンドに対するレスポンスです。 |
|
||||||
|
|
||||||
未処理のPathfindingリクエストがない場合はエラーが返されます。
|
未処理のPathfindingリクエストがない場合はエラーが返されます。
|
||||||
|
|
||||||
@@ -566,17 +567,17 @@ Pathfindingリクエストが正常にクローズされた場合、レスポン
|
|||||||
|
|
||||||
リクエストには以下のパラメーターが含まれます。
|
リクエストには以下のパラメーターが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:-------------|:-------|:---------------------------------------------|
|
|:-------------|:-------|:--------------------------------------|
|
||||||
| `subcommand` | 文字列 | `"status"`を使用して、statusサブコマンドを送信します。 |
|
| `subcommand` | 文字列 | `"status"`を使用して、statusサブコマンドを送信します。 |
|
||||||
|
|
||||||
### レスポンスのフォーマット
|
### レスポンスのフォーマット
|
||||||
|
|
||||||
Pathfindingリクエストが実行中の場合、レスポンスは[`path_find create`](#path_find-create)に対する初期レスポンスと同じフォーマットであるのに加えて、以下のフィールドがあります。
|
Pathfindingリクエストが実行中の場合、レスポンスは[`path_find create`](#path_find-create)に対する初期レスポンスと同じフォーマットであるのに加えて、以下のフィールドがあります。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:---------|:--------|:--------------------------------------------------------|
|
|:-----------|:--------|:-------------------------------------------------|
|
||||||
| `status` | ブール値 | 値が`true`の場合、これは`path_find status`コマンドに対するレスポンスです。 |
|
| `status` | ブール値 | 値が`true`の場合、これは`path_find status`コマンドに対するレスポンスです。 |
|
||||||
|
|
||||||
未処理のPathfindingリクエストがない場合はエラーが返されます。
|
未処理のPathfindingリクエストがない場合はエラーが返されます。
|
||||||
|
|
||||||
|
|||||||
@@ -85,15 +85,16 @@ rippled ripple_path_find '{"source_account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
|||||||
|
|
||||||
リクエストには以下のパラメーターが含まれます。
|
リクエストには以下のパラメーターが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 必須? | 説明 |
|
||||||
|:----------------------|:---------------------------|:------------------------|
|
|:----------------------|:-------------------------|:-------|:-----------------|
|
||||||
| `source_account` | 文字列 | トランザクションで資金を送金するアカウントの一意のアドレス。 |
|
| `source_account` | 文字列 - [アドレス][] | はい | トランザクションで資金を送金するアカウントのアドレス。 |
|
||||||
| `destination_account` | 文字列 | トランザクションで資金を受領するアカウントの一意のアドレス。 |
|
| `destination_account` | 文字列 - [アドレス][] | はい | トランザクションで資金を受領するアカウントのアドレス。 |
|
||||||
| `destination_amount` | 文字列またはオブジェクト | 送金先アカウントがトランザクションで受領する[通貨額][]。**特殊なケース:** {% badge href="https://github.com/XRPLF/rippled/releases/tag/0.30.0" %}新規: rippled 0.30.0{% /badge %}`value`フィールドには`"-1"`(XRPの場合)または-1(XRP以外の通貨の場合)を指定できます。これにより、最大限の額を送金できるパスがリクエストされます。ただし`send_max`が指定されている場合は、指定されている額を上回る額が支払われることはありません。 |
|
| `destination_amount` | [通貨額][] | はい | 送金先アカウントがトランザクションで受領する[通貨額][]。**特殊なケース:** `value`フィールドには`"-1"`(XRPの場合)または-1(XRP以外の通貨の場合)を指定できます。これにより、最大限の額を送金できるパスがリクエストされます。ただし`send_max`が指定されている場合は、指定されている額を上回る額が支払われることはありません。 |
|
||||||
| `send_max` | 文字列またはオブジェクト | _(省略可)_ トランザクションで使用する[通貨額][]。`source_currencies`と同時に使用することはできません。{% badge href="https://github.com/XRPLF/rippled/releases/tag/0.30.0" %}新規: rippled 0.30.0{% /badge %} |
|
| `domain` | 文字列 - [ハッシュ][] | いいえ | 許可型DEXのレジャーエントリID。指定された場合、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用するパスを返します。([PermissionedDEX amendment][] {% not-enabled /%}が必要です) |
|
||||||
| `source_currencies` | 配列 | _(省略可)_ 送信元アカウントが使用する通貨の配列。この配列の各エントリは、必須の`currency`フィールドとオプションの`issuer`フィールドを有するJSONオブジェクトです([通貨額][]の指定方法と同様)。指定できる送金元通貨は**18**種類以下です。デフォルトでは、あらゆる送金元通貨を使用し、最大で**88**の異なる通貨/イシュアーペアに使用できます。 |
|
| `ledger_hash` | 文字列 - [ハッシュ][] | いいえ | 使用するレジャーバージョンの20バイトの16進文字列。([レジャーの指定][]をご覧ください) |
|
||||||
| `ledger_hash` | 文字列 | _(省略可)_ 使用するレジャーバージョンの20バイトの16進文字列。([レジャーの指定][]をご覧ください) |
|
| `ledger_index` | [レジャーインデックス][] | いいえ | 使用するレジャーのシーケンス番号、またはレジャーを自動的に選択するためのショートカット文字列。([レジャーの指定][]をご覧ください) |
|
||||||
| `ledger_index` | 文字列または符号なし整数 | _(省略可)_ 使用するレジャーのシーケンス番号、またはレジャーを自動的に選択するためのショートカット文字列。([レジャーの指定][]をご覧ください) |
|
| `send_max` | [通貨額][] | いいえ | トランザクションで使用する[通貨額][]。`source_currencies`と同時に使用することはできません。 |
|
||||||
|
| `source_currencies` | 配列 | いいえ | 送信元アカウントが使用する通貨の配列。この配列の各エントリは、必須の`currency`フィールドとオプションの`issuer`フィールドを有するJSONオブジェクトです([通貨額][]の指定方法と同様)。指定できる送金元通貨は**18**種類以下です。デフォルトでは、あらゆる送金元通貨を使用し、最大で**88**の異なる通貨/イシュアーペアに使用できます。 |
|
||||||
|
|
||||||
## レスポンスのフォーマット
|
## レスポンスのフォーマット
|
||||||
|
|
||||||
@@ -323,7 +324,7 @@ rippled ripple_path_find '{"source_account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
|||||||
|
|
||||||
このレスポンスは[標準フォーマット][]に従っており、正常に完了した場合は結果に次のフィールドが含まれます。
|
このレスポンスは[標準フォーマット][]に従っており、正常に完了した場合は結果に次のフィールドが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:-------------------------|:-------|:-----------------------------------------|
|
|:-------------------------|:-------|:-----------------------------------------|
|
||||||
| `alternatives` | 配列 | 使用可能なパスを持つオブジェクトの配列。以下に説明します。空の場合、送金元アカウントと送金先アカウントを結ぶパスがありません。 |
|
| `alternatives` | 配列 | 使用可能なパスを持つオブジェクトの配列。以下に説明します。空の場合、送金元アカウントと送金先アカウントを結ぶパスがありません。 |
|
||||||
| `destination_account` | 文字列 | 支払トランザクションを受信するアカウントの一意のアドレス。 |
|
| `destination_account` | 文字列 | 支払トランザクションを受信するアカウントの一意のアドレス。 |
|
||||||
@@ -331,7 +332,7 @@ rippled ripple_path_find '{"source_account":"r9cZA1mLK5R5Am25ArfXFmqgNwjZgnfk59"
|
|||||||
|
|
||||||
`alternatives`配列の各要素は、1つの送金元通貨(開始アカウントが保有)から送金先アカウントへのパスと通貨を表すオブジェクトです。このオブジェクトのフィールドを次に示します。
|
`alternatives`配列の各要素は、1つの送金元通貨(開始アカウントが保有)から送金先アカウントへのパスと通貨を表すオブジェクトです。このオブジェクトのフィールドを次に示します。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:-----------------|:-----------------|:---------------------------------------|
|
|:-----------------|:-----------------|:---------------------------------------|
|
||||||
| `paths_computed` | 配列 | (省略可)[ペイメントパス](../../../../concepts/tokens/fungible-tokens/paths.md)を定義するオブジェクトの配列。 |
|
| `paths_computed` | 配列 | (省略可)[ペイメントパス](../../../../concepts/tokens/fungible-tokens/paths.md)を定義するオブジェクトの配列。 |
|
||||||
| `source_amount` | 文字列またはオブジェクト | 送金先が希望額を受領できるよう、送金元がこのパスで送金する必要のある[通貨額][]。 |
|
| `source_amount` | 文字列またはオブジェクト | 送金先が希望額を受領できるよう、送金元がこのパスで送金する必要のある[通貨額][]。 |
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ labels:
|
|||||||
- スマートコントラクト
|
- スマートコントラクト
|
||||||
---
|
---
|
||||||
# subscribe
|
# subscribe
|
||||||
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/ripple/rpc/handlers/Subscribe.cpp "Source")
|
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/rpc/handlers/Subscribe.cpp "Source")
|
||||||
|
|
||||||
`subscribe`メソッドは、特定のイベントが発生した場合に、定期的に通知するようサーバにリクエストします。
|
`subscribe`メソッドは、特定のイベントが発生した場合に、定期的に通知するようサーバにリクエストします。
|
||||||
|
|
||||||
@@ -66,42 +66,47 @@ labels:
|
|||||||
|
|
||||||
リクエストには以下のパラメーターが含まれます。
|
リクエストには以下のパラメーターが含まれます。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 必須? | 説明 |
|
||||||
| :------------------ | :----- | ---- |
|
|:--------------------|:-------|:-------|:-----|
|
||||||
| `streams` | 配列 | _(省略可)_ 以下に説明する、サブスクライブする汎用ストリームの文字列名の配列。 |
|
| `streams` | 配列 | いいえ | 以下で説明するストリームにサブスクライブします。配列の各要素は、ストリームの文字列名でなければなりません。 |
|
||||||
| `accounts` | 配列 | _(省略可)_ 検証済みトランザクションを監視するアカウントの一意のアドレスを持つ配列。これらのアドレスはXRP Ledgerの[base58][]フォーマットで記述されている必要があります。サーバは、1つ以上のアカウントに影響するすべてのトランザクションについて通知を送信します。 |
|
| `accounts` | 配列 | いいえ | 検証済みトランザクションを監視するアカウントの一意の[アドレス][]を持つ配列。サーバは、少なくともこれらのアカウントのいずれかに影響を与えるトランザクションが発生するたびに、`transaction`タイプのメッセージを送信します。 |
|
||||||
| `accounts_proposed` | 配列 | _(省略可)_ `accounts`と同様ですが、まだファイナライズされていないトランザクションを含みます。 |
|
| `accounts_proposed` | 配列 | いいえ | `accounts`と同様ですが、まだファイナライズされていないトランザクションを含みます。 |
|
||||||
| `books` | 配列 | _(省略可)_ 以下に説明するとおり、更新の監視のために[オーダーブック](http://www.investopedia.com/terms/o/order-book.asp)を定義するオブジェクトの配列。 |
|
| `books` | 配列 | いいえ | 更新を監視するオーダーブック。配列の各要素は、以下で定義される[book object](#book-objects)でなければなりません。サーバは、トランザクションがこのアカウントに影響を与えるたびに、`transaction`タイプのメッセージを送信します。 |
|
||||||
| `url` | 文字列 | (Websocketでは省略可、それ以外では必須)サーバが各イベントのJSON-RPCコールバックを送信するURL。*管理者専用。* |
|
| `url` | 文字列 | いいえ | (Websocketでは省略可、それ以外では必須)サーバが各イベントのJSON-RPCコールバックを送信するURL。*管理者専用。* |
|
||||||
| `url_username` | 文字列 | _(省略可)_ コールバックURLで基本認証を行うためのユーザ名。 |
|
| `url_username` | 文字列 | いいえ | コールバックURLで基本認証を行うためのユーザ名。 |
|
||||||
| `url_password` | 文字列 | _(省略可)_ コールバックURLで基本認証を行うためのパスワード。 |
|
| `url_password` | 文字列 | いいえ | コールバックURLで基本認証を行うためのパスワード。 |
|
||||||
|
|
||||||
以下のパラメーターは廃止予定で、今後予告なしに削除される可能性があります。`user`、`password`、`rt_accounts`。
|
以下のパラメータは廃止予定で、今後予告なしに削除される可能性があります。`user`、`password`、`rt_accounts`。
|
||||||
|
|
||||||
`streams`パラメーターは、以下のデフォルトの情報ストリームへのアクセスを可能にします。
|
`streams`パラメータは、以下のデフォルトの情報ストリームへのアクセスを可能にします。
|
||||||
|
|
||||||
- `book_changes` - コンセンサスプロセスが新しい有効なレジャーを作成するたびに、オーダーブックの変更をメッセージで送信します。
|
| ストリーム名 | メッセージタイプ | 説明 |
|
||||||
- `consensus` - サーバがコンセンサスサイクルのフェーズを変更するたびにメッセージを送信します。
|
|:------------------------|:---------------------|:------------|
|
||||||
- `ledger` - コンセンサスプロセスで新しい検証済みレジャーが宣言されるたびにメッセージを送信します。
|
| `book_changes` | `bookChanges` | コンセンサスプロセスが新しい検証済みレジャーを宣言するたびに、オーダーブックの変更をメッセージで送信します。 |
|
||||||
- `manifests` - バリデータのephemeral署名鍵の更新を受け取るたびにメッセージを送信します。
|
| `consensus` | `consensusPhase` | サーバがコンセンサスサイクルのフェーズを変更するたびにメッセージを送信します。 |
|
||||||
- `peer_status` - **(管理者専用)** 接続している`rippled`のピアサーバに関する情報(特にコンセンサスプロセスに関する情報)。
|
| `ledger` | `ledgerClosed` | コンセンサスプロセスで新しい検証済みレジャーが宣言されるたびにメッセージを送信します。 |
|
||||||
- `transactions` - 閉鎖済みレジャーにトランザクションが追加されるたびにメッセージを送信します。
|
| `manifests` | `manifestReceived` | バリデータのephemeral署名鍵の更新を受け取るたびにメッセージを送信します。 |
|
||||||
- `transactions_proposed` - 閉鎖済みレジャーにトランザクションが追加される場合や、検証済みレジャーにまだ追加されておらず、今後も追加される見込みのない一部のトランザクションが検証済みレジャーに追加される場合に、メッセージを送信します。提案されたすべてのトランザクションが検証前に表示されるわけではありません。
|
| `peer_status` | `peerStatusChange` | **(管理者専用)** 接続している`rippled`のピアサーバに関する情報(特にコンセンサスプロセスに関する情報)。 |
|
||||||
{% admonition type="info" name="注記" %}[成功しなかったトランザクション](../../../protocol/transactions/transaction-results/index.md) 成功しなかったトランザクションも、スパム対策取引手数料を取るため、検証済みレジャーに含まれます。{% /admonition %}
|
| `transactions` | `transaction` | 閉鎖済みレジャーにトランザクションが追加されるたびにメッセージを送信します。 |
|
||||||
- `server` - `rippled`サーバのステータス(ネットワーク接続など)が変更されるたびにメッセージを送信します。
|
| `transactions_proposed` | `transaction` | 閉鎖済みレジャーにトランザクションが追加される場合や、検証済みレジャーにまだ追加されておらず、今後も追加される見込みのない一部のトランザクションが検証済みレジャーに追加される場合に、メッセージを送信します。提案されたすべてのトランザクションが検証前に表示されるわけではありません。 {% admonition type="info" name="注記" %}[成功しなかったトランザクション](../../../protocol/transactions/transaction-results/index.md) 成功しなかったトランザクションも、スパム対策取引手数料を取るため、検証済みレジャーに含まれます。{% /admonition %} |
|
||||||
- `validations` - サーバがバリデータを信頼しているか否かにかかわらず、サーバが検証メッセージを受信するたびに、メッセージを送信します。(個々の`rippled`は、サーバが少なくとも定数の信頼できるバリデータから検証メッセージを受信した時点で、レジャーが検証済みであると宣言します。)
|
| `server` | `serverStatus` | `rippled`サーバのステータス(ネットワーク接続など)が変更されるたびにメッセージを送信します。 |
|
||||||
|
| `validations` | `validationReceived` | サーバがバリデータを信頼しているか否かにかかわらず、サーバが検証メッセージを受信するたびに、メッセージを送信します。(個々の`rippled`は、サーバが少なくとも定数の信頼できるバリデータから検証メッセージを受信した時点で、レジャーが検証済みであると宣言します。) |
|
||||||
|
|
||||||
{% admonition type="info" name="注記" %}以下のストリームは Clioおよび[レポートモード][]の`rippled`サーバからは利用できません: `server`、`peer_status`、`consensus`。これらのストリームを要求すると、どちらも`reportingUnsupported`エラーを返します。 {% badge href="https://github.com/XRPLF/rippled/releases/tag/1.8.1" %}更新: rippled 1.8.1{% /badge %} {% badge href="https://github.com/XRPLF/clio/releases/tag/2.0.0" %}新規: Clio v2.0{% /badge %}{% /admonition %}
|
{% admonition type="info" name="注記" %}以下のストリームは Clioおよび[レポートモード][]の`rippled`サーバからは利用できません: `server`、`peer_status`、`consensus`。これらのストリームを要求すると、どちらも`reportingUnsupported`エラーを返します。 {% badge href="https://github.com/XRPLF/rippled/releases/tag/1.8.1" %}更新: rippled 1.8.1{% /badge %} {% badge href="https://github.com/XRPLF/clio/releases/tag/2.0.0" %}新規: Clio v2.0{% /badge %}{% /admonition %}
|
||||||
|
|
||||||
|
### Bookオブジェクト
|
||||||
|
|
||||||
`books`配列が指定されている場合、この配列の各要素は、以下のフィールドを持つオブジェクトです。
|
`books`配列が指定されている場合、この配列の各要素は、以下のフィールドを持つオブジェクトです。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 必須? | 説明 |
|
||||||
| :----------- | :----------- | ---- |
|
| :----------- | :-------------------- | :----- | ---- |
|
||||||
| `taker_gets` | オブジェクト | オファーを受諾するアカウントが受け取る通貨を[金額なしの通貨オブジェクト](../../../protocol/data-types/currency-formats.md#金額なしでの通貨の指定)として指定します。 |
|
| `taker_gets` | オブジェクト | はい | オファーを受諾するアカウントが受け取る通貨を[金額なしの通貨オブジェクト](../../../protocol/data-types/currency-formats.md#金額なしでの通貨の指定)として指定します。 |
|
||||||
| `taker_pays` | オブジェクト | オファーを受諾するアカウントが支払う通貨を[金額なしの通貨オブジェクト](../../../protocol/data-types/currency-formats.md#金額なしでの通貨の指定)として指定します。 |
|
| `taker_pays` | オブジェクト | はい | オファーを受諾するアカウントが支払う通貨を[金額なしの通貨オブジェクト](../../../protocol/data-types/currency-formats.md#金額なしでの通貨の指定)として指定します。 |
|
||||||
| `taker` | 文字列 | オファーを表示するパースペクティブとして使用する一意のアカウントアドレス(XRP Ledgerの[base58][]フォーマット)。(これはオファーの資金提供ステータスと手数料に影響します。) |
|
| `both` | ブール値 | いいえ | `true`の場合は、オーダーブックの両サイドを返します。デフォルトは`false` |
|
||||||
| `snapshot` | ブール値 | (省略可)`true`の場合は、更新の送信前にサブスクライブした時点でオーダーブックの現在の状態を一度返します。デフォルトは`false` |
|
| `domain` | 文字列 - [ハッシュ][] | いいえ | 許可型DEXのレジャーエントリID。指定された場合、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用するパスを返します。([PermissionedDEX amendment][] {% not-enabled /%}が必要です) |
|
||||||
| `both` | ブール値 | (省略可)`true`の場合は、オーダーブックの両サイドを返します。デフォルトは`false` |
|
| `snapshot` | ブール値 | いいえ | `true`の場合は、更新の送信前にサブスクライブした時点でオーダーブックの現在の状態を一度返します。デフォルトは`false` |
|
||||||
|
| `taker` | 文字列 | いいえ | オファーを表示するパースペクティブとして使用する一意のアカウントアドレス(XRP Ledgerの[base58][]フォーマット)。(これはオファーの資金提供ステータスと手数料に影響します。) |
|
||||||
|
|
||||||
|
|
||||||
## レスポンスのフォーマット
|
## レスポンスのフォーマット
|
||||||
|
|
||||||
@@ -167,7 +172,7 @@ labels:
|
|||||||
|
|
||||||
レジャーストリームメッセージのフィールドは次のとおりです。
|
レジャーストリームメッセージのフィールドは次のとおりです。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
| :------------------ | :------------------------------ | ---- |
|
| :------------------ | :------------------------------ | ---- |
|
||||||
| `type` | 文字列 | `ledgerClosed`は、このメッセージがレジャーストリームからのものであることを示します。 |
|
| `type` | 文字列 | `ledgerClosed`は、このメッセージがレジャーストリームからのものであることを示します。 |
|
||||||
| `fee_base` | 数値 | このレジャーバージョン時点の[Referenceトランザクションコスト](../../../../concepts/transactions/transaction-cost.md#referenceトランザクションコスト)([XRPのdrop数][])。このレジャーバージョンに[SetFee疑似トランザクション](../../../protocol/transactions/pseudo-transaction-types/setfee.md)が含まれている場合は、次のレジャーバージョンから新しいトランザクションコストが適用されます。 |
|
| `fee_base` | 数値 | このレジャーバージョン時点の[Referenceトランザクションコスト](../../../../concepts/transactions/transaction-cost.md#referenceトランザクションコスト)([XRPのdrop数][])。このレジャーバージョンに[SetFee疑似トランザクション](../../../protocol/transactions/pseudo-transaction-types/setfee.md)が含まれている場合は、次のレジャーバージョンから新しいトランザクションコストが適用されます。 |
|
||||||
@@ -212,7 +217,7 @@ labels:
|
|||||||
|
|
||||||
検証ストリームメッセージのフィールドは次のとおりです。
|
検証ストリームメッセージのフィールドは次のとおりです。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
| :---------------------- | :------------ | ---- |
|
| :---------------------- | :------------ | ---- |
|
||||||
| `type` | 文字列 | 値`validationReceived`は、このメッセージが検証ストリームからであることを示します。 |
|
| `type` | 文字列 | 値`validationReceived`は、このメッセージが検証ストリームからであることを示します。 |
|
||||||
| `amendments` | 文字列の配列 | (省略される場合があります)このサーバがプロトコルへの追加を求める[Amendment](../../../../concepts/networks-and-servers/amendments.md)。 |
|
| `amendments` | 文字列の配列 | (省略される場合があります)このサーバがプロトコルへの追加を求める[Amendment](../../../../concepts/networks-and-servers/amendments.md)。 |
|
||||||
@@ -333,7 +338,7 @@ labels:
|
|||||||
|
|
||||||
{% tab label="API v2" %}
|
{% tab label="API v2" %}
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
|:------------------------|:--------------------------|:-----|
|
|:------------------------|:--------------------------|:-----|
|
||||||
| `close_time_iso` | 文字列 | レジャーの終了時刻をISO 8601の時刻形式で表します。 |
|
| `close_time_iso` | 文字列 | レジャーの終了時刻をISO 8601の時刻形式で表します。 |
|
||||||
| `type` | 文字列 | `transaction`は、複数の可能なストリームからのトランザクションの通知であることを示します。 |
|
| `type` | 文字列 | `transaction`は、複数の可能なストリームからのトランザクションの通知であることを示します。 |
|
||||||
@@ -352,7 +357,7 @@ labels:
|
|||||||
|
|
||||||
{% tab label="API v1" %}
|
{% tab label="API v1" %}
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
| :---------------------- | :------------------------------ | ---- |
|
| :---------------------- | :------------------------------ | ---- |
|
||||||
| `type` | 文字列 | `transaction`は、トランザクションの通知であることを示します。この通知はさまざまなストリームから送信される可能性があります。 |
|
| `type` | 文字列 | `transaction`は、トランザクションの通知であることを示します。この通知はさまざまなストリームから送信される可能性があります。 |
|
||||||
| `engine_result` | 文字列 | 文字列の[トランザクション結果コード](../../../protocol/transactions/transaction-results/index.md) |
|
| `engine_result` | 文字列 | 文字列の[トランザクション結果コード](../../../protocol/transactions/transaction-results/index.md) |
|
||||||
@@ -389,7 +394,7 @@ labels:
|
|||||||
|
|
||||||
ピアステータスストリームメッセージは、`rippled`ピアサーバのステータスが変化したイベントを表します。これらのメッセージは、次のフィールドを持つJSONオブジェクトです。
|
ピアステータスストリームメッセージは、`rippled`ピアサーバのステータスが変化したイベントを表します。これらのメッセージは、次のフィールドを持つJSONオブジェクトです。
|
||||||
|
|
||||||
| `Field` | 値 | 説明 |
|
| フィールド | 値 | 説明 |
|
||||||
| :----------------- | :----- | ---- |
|
| :----------------- | :----- | ---- |
|
||||||
| `type` | 文字列 | `peerStatusChange`は、ピアステータスストリームからのメッセージであることを示します。 |
|
| `type` | 文字列 | `peerStatusChange`は、ピアステータスストリームからのメッセージであることを示します。 |
|
||||||
| `action` | 文字列 | このメッセージが送信される原因となったイベントのタイプ。有効な値については、[ピアステータスイベント](#ピアステータスイベント)をご覧ください。 |
|
| `action` | 文字列 | このメッセージが送信される原因となったイベントのタイプ。有効な値については、[ピアステータスイベント](#ピアステータスイベント)をご覧ください。 |
|
||||||
@@ -561,7 +566,7 @@ labels:
|
|||||||
|
|
||||||
オーダーブックストリームメッセージの形式は、[トランザクションストリームメッセージ](#トランザクションストリーム)と同様ですが、`OfferCreate`トランザクションに以下のフィールドも含まれている点が異なります。
|
オーダーブックストリームメッセージの形式は、[トランザクションストリームメッセージ](#トランザクションストリーム)と同様ですが、`OfferCreate`トランザクションに以下のフィールドも含まれている点が異なります。
|
||||||
|
|
||||||
| `Field` | 値 | 説明 |
|
| フィールド | 値 | 説明 |
|
||||||
| :------------------------ | :----- | ---- |
|
| :------------------------ | :----- | ---- |
|
||||||
| `transaction.owner_funds` | 文字列 | このOfferCreateトランザクションを送信する`Account`が、このトランザクション実行後に有する`TakerGets`通貨の金額。この通貨額が[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。<br>[API v2][]では`tx_json.owner_funds`に変更されました。 |
|
| `transaction.owner_funds` | 文字列 | このOfferCreateトランザクションを送信する`Account`が、このトランザクション実行後に有する`TakerGets`通貨の金額。この通貨額が[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているかどうかはチェックされません。<br>[API v2][]では`tx_json.owner_funds`に変更されました。 |
|
||||||
|
|
||||||
@@ -695,7 +700,7 @@ labels:
|
|||||||
|
|
||||||
[Book Changes]ストリームメッセージのフィールドは以下のとおりです:
|
[Book Changes]ストリームメッセージのフィールドは以下のとおりです:
|
||||||
|
|
||||||
| Field | 値 | 説明 |
|
| フィールド | 値 | 説明 |
|
||||||
|:---------------|:-------------------------|:-----|
|
|:---------------|:-------------------------|:-----|
|
||||||
| `type` | 文字列 | 値`bookChanges`は、これがBook Changesストリームからのものであることを示します。 |
|
| `type` | 文字列 | 値`bookChanges`は、これがBook Changesストリームからのものであることを示します。 |
|
||||||
| `ledger_index` | [レジャーインデックス][] | これらの変更を含むレジャーのレジャーインデックス。 |
|
| `ledger_index` | [レジャーインデックス][] | これらの変更を含むレジャーのレジャーインデックス。 |
|
||||||
@@ -717,7 +722,7 @@ labels:
|
|||||||
|
|
||||||
コンセンサスストリームメッセージのフィールドは次のとおりです。
|
コンセンサスストリームメッセージのフィールドは次のとおりです。
|
||||||
|
|
||||||
| `Field` | 型 | 説明 |
|
| フィールド | 型 | 説明 |
|
||||||
| :---------- | :----- | ---- |
|
| :---------- | :----- | ---- |
|
||||||
| `type` | 文字列 | `consensusPhase`は、このメッセージがコンセンサスストリームからのものであることを示します。 |
|
| `type` | 文字列 | `consensusPhase`は、このメッセージがコンセンサスストリームからのものであることを示します。 |
|
||||||
| `consensus` | 文字列 | サーバで実行されている新しいコンセンサスフェーズ。値には、`open`、`establish`、`accepted`などがあります。 |
|
| `consensus` | 文字列 | サーバで実行されている新しいコンセンサスフェーズ。値には、`open`、`establish`、`accepted`などがあります。 |
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ XRPの金額は負になることはありません。
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 金額なしでの通貨の指定
|
### 金額なしでの通貨の指定
|
||||||
|
|
||||||
場合によっては、[分散型取引所](../../../concepts/tokens/decentralized-exchange/index.md)でオーダーブックを指定するときなど、特定の金額なしで資産(XRPやトークン)を定義する必要があります。
|
場合によっては、[分散型取引所](../../../concepts/tokens/decentralized-exchange/index.md)でオーダーブックを指定するときなど、特定の金額なしで資産(XRPやトークン)を定義する必要があります。
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ labels:
|
|||||||
- 分散型取引所
|
- 分散型取引所
|
||||||
---
|
---
|
||||||
# DirectoryNode
|
# DirectoryNode
|
||||||
[[ソース]](https://github.com/XRPLF/rippled/blob/5d2d88209f1732a0f8d592012094e345cbe3e675/src/ripple/protocol/impl/LedgerFormats.cpp#L44 "Source")
|
[[ソース]](https://github.com/XRPLF/rippled/blob/7e24adbdd0b61fb50967c4c6d4b27cc6d81b33f3/include/xrpl/protocol/detail/ledger_entries.macro#L177-L192 "Source")
|
||||||
|
|
||||||
`DirectoryNode`オブジェクトタイプは、レジャーの状態ツリー内の他オブジェクトへのリンクのリストを提供します。概念上の1つの _ディレクトリ_ は、1つ以上の各DirectoryNodeオブジェクトが含まれる二重リンクリストの形式になっています。各DirectoryNodeオブジェクトには、他オブジェクトの[ID](../common-fields.md)が最大32個まで含まれています。1番目のオブジェクトはディレクトリのルートと呼ばれ、ルートオブジェクト以外のオブジェクトはすべて必要に応じて自由に追加または削除できます。
|
`DirectoryNode`オブジェクトタイプは、レジャーの状態ツリー内の他オブジェクトへのリンクのリストを提供します。概念上の1つの _ディレクトリ_ は、1つ以上の各DirectoryNodeオブジェクトが含まれる二重リンクリストの形式になっています。各DirectoryNodeオブジェクトには、他オブジェクトの[ID](../common-fields.md)が最大32個まで含まれています。1番目のオブジェクトはディレクトリのルートと呼ばれ、ルートオブジェクト以外のオブジェクトはすべて必要に応じて自由に追加または削除できます。
|
||||||
|
|
||||||
@@ -95,6 +95,7 @@ labels:
|
|||||||
|
|
||||||
| 名前 | JSONの型 | [内部の型][] | 必須? | 説明 |
|
| 名前 | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|---------------------|-----------|--------------|:-------|-------------|
|
|---------------------|-----------|--------------|:-------|-------------|
|
||||||
|
| `DomainID` | 文字列 | Hash256 | いいえ | (オファーディレクトリのみ) 許可型DEXのレジャーエントリID。指定された場合、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用するパスを返します。([PermissionedDEX amendment][] {% not-enabled /%}が必要です。) |
|
||||||
| `ExchangeRate` | 数値 | UInt64 | いいえ | (オファーディレクトリのみ)**廃止予定**。使用しないでください。 |
|
| `ExchangeRate` | 数値 | UInt64 | いいえ | (オファーディレクトリのみ)**廃止予定**。使用しないでください。 |
|
||||||
| `Flags` | 数値 | UInt32 | はい | このディレクトリに対して有効になっているブール値フラグのビットマップ。現在、プロトコルではDirectoryNodeオブジェクトのフラグは定義されていません。 |
|
| `Flags` | 数値 | UInt32 | はい | このディレクトリに対して有効になっているブール値フラグのビットマップ。現在、プロトコルではDirectoryNodeオブジェクトのフラグは定義されていません。 |
|
||||||
| `Indexes` | 配列 | Vector256 | はい | このディレクトリの内容: 他のオブジェクトのIDの配列。 |
|
| `Indexes` | 配列 | Vector256 | はい | このディレクトリの内容: 他のオブジェクトのIDの配列。 |
|
||||||
@@ -135,6 +136,7 @@ DirectoryNodeのIDを作成するときには、DirectoryNodeが以下のどの
|
|||||||
|
|
||||||
* 所有者ディレクトリまたはNFTオファーディレクトリの1番目のページ(ルートとも呼ばれます)
|
* 所有者ディレクトリまたはNFTオファーディレクトリの1番目のページ(ルートとも呼ばれます)
|
||||||
* オファーディレクトリの1番目のページ
|
* オファーディレクトリの1番目のページ
|
||||||
|
* オファーディレクトリの最初のページ。オープンDEXと認可型DEX用のバージョンが含まれます。 _([PermissionedDEX amendment][]が必要です。 {% not-enabled /%})_
|
||||||
* いずれかのディレクトリの以降のページ
|
* いずれかのディレクトリの以降のページ
|
||||||
|
|
||||||
**所有者ディレクトリまたはNFTオファーディレクトリの1番目のページ**のIDは、以下の値がこの順序で連結されている[SHA-512Half][]です。
|
**所有者ディレクトリまたはNFTオファーディレクトリの1番目のページ**のIDは、以下の値がこの順序で連結されている[SHA-512Half][]です。
|
||||||
@@ -149,6 +151,7 @@ DirectoryNodeのIDを作成するときには、DirectoryNodeが以下のどの
|
|||||||
* `TakerGetsCurrency`の160ビットの通貨コード
|
* `TakerGetsCurrency`の160ビットの通貨コード
|
||||||
* `TakerPaysIssuer`のAccountID
|
* `TakerPaysIssuer`のAccountID
|
||||||
* `TakerGetsIssuer`のAccountID
|
* `TakerGetsIssuer`のAccountID
|
||||||
|
* このオーダーブックが属する許可型DEXの許可型ドメインの`DomainID`。許可型DEXのオーダーブックの場合。オープンDEXのオーダーブックの場合は省略。
|
||||||
|
|
||||||
オファーディレクトリのIDの下位64ビットは、そのディレクトリ内のオファーのTakerPaysの額をTakerGetsの額で割った結果を、XRP Ledgerの内部金額フォーマットの64ビット数値で表したものです。
|
オファーディレクトリのIDの下位64ビットは、そのディレクトリ内のオファーのTakerPaysの額をTakerGetsの額で割った結果を、XRP Ledgerの内部金額フォーマットの64ビット数値で表したものです。
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ labels:
|
|||||||
- 分散型取引所
|
- 分散型取引所
|
||||||
---
|
---
|
||||||
# Offer
|
# Offer
|
||||||
[[ソース]](https://github.com/XRPLF/rippled/blob/5d2d88209f1732a0f8d592012094e345cbe3e675/src/ripple/protocol/impl/LedgerFormats.cpp#L57 "Source")
|
[[ソース]](https://github.com/XRPLF/rippled/blob/7e24adbdd0b61fb50967c4c6d4b27cc6d81b33f3/include/xrpl/protocol/detail/ledger_entries.macro#L242-L255 "ソース")
|
||||||
|
|
||||||
台帳の`Offer`エントリは、XRP Ledgerの[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)で通貨を交換する[オファー](../../../../concepts/tokens/decentralized-exchange/offers.md)を表しています。(金融ではより伝統的に _オーダー_ として知られています)。[OfferCreateトランザクション][]は台帳にある他のOfferを全額約定できない場合、台帳に`Offer`エントリを作成します。
|
`Offer`レジャーエントリは、XRP Ledgerの[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)で通貨を交換する[オファー](../../../../concepts/tokens/decentralized-exchange/offers.md)を表しています。(金融ではより伝統的に _オーダー_ として知られています)。[OfferCreateトランザクション][]は他のOfferを全額約定できない場合、Offerエントリを作成します。
|
||||||
|
|
||||||
オファーがネットワーク上の他の活動によって資金不足になることはありますが、元帳には残ります。トランザクションを処理する際、ネットワークはトランザクションが見つけた資金不足のオファーを自動的に削除します。( _トランザクションのみ_ が台帳の状態を変更できるため、削除が行われないと資金不足のオファーが残ってしまいます。)
|
オファーがネットワーク上の他の活動によって資金不足になることはありますが、元帳には残ります。トランザクションを処理する際、ネットワークはトランザクションが見つけた資金不足のオファーを自動的に削除します。( _トランザクションのみ_ が台帳の状態を変更できるため、削除が行われないと資金不足のオファーが残ってしまいます。)
|
||||||
|
|
||||||
@@ -40,29 +40,32 @@ labels:
|
|||||||
|
|
||||||
[共通フィールド][]に加えて、{% $frontmatter.seo.title %}エントリは以下のフィールドを使用します。
|
[共通フィールド][]に加えて、{% $frontmatter.seo.title %}エントリは以下のフィールドを使用します。
|
||||||
|
|
||||||
| 名前 | JSONの型 | [内部の型][] | 必須? | 説明 |
|
| 名前 | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|-------------------|-----------|-----------|------|-------|
|
|---------------------|-----------------------|--------------|-------|-------|
|
||||||
| `Account` | 文字列 | AccountID | はい | このオファーを所有するアカウントのアドレス。 |
|
| `Account` | 文字列 | AccountID | はい | このオファーを所有するアカウントのアドレス。 |
|
||||||
| `BookDirectory` | 文字列 | UInt256 | はい | このオファーにリンクしている[オファーディレクトリー](directorynode.md)のID。 |
|
| `AdditionalBooks` | 配列 | Array | いいえ| 追加のオファーディレクトリーのリスト。このフィールドは、このオファーが[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)でハイブリッドオファーの場合にのみ存在します。配列には常に1つのエントリが含まれます。([PermissionedDEX amendment][] {% not-enabled /%}が必要です。) |
|
||||||
| `BookNode` | 文字列 | UInt64 | はい | Offerディレクトリが複数ページで構成されている場合に、このオブジェクトにリンクしているページを示すヒント。 |
|
| `BookDirectory` | 文字列 - [ハッシュ][] | UInt256 | はい | このオファーにリンクしている[オファーディレクトリー](directorynode.md)のID。 |
|
||||||
| `Expiration` | 数値 | UInt32 | いいえ | (省略可)このオファーが資金不足とみなされる時刻。詳細は、[時間の指定][]をご覧ください。 |
|
| `BookNode` | 文字列 | UInt64 | はい | Offerディレクトリが複数ページで構成されている場合に、このオブジェクトにリンクしているページを示すヒント。 |
|
||||||
| `Flags` | 数値 | UInt32 | はい | このオファーに対して有効になっているブール値フラグのビットマップ。 |
|
| `DomainID` | 文字列 - [ハッシュ][] | Hash256 | いいえ | 許可型DEXのレジャーエントリID。指定された場合、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用するパスを返します。([PermissionedDEX amendment][] {% not-enabled /%}が必要です。) |
|
||||||
| `LedgerEntryType` | 文字列 | UInt16 | はい | 値が`0x006F`(文字列`Offer`にマッピング)の場合は、このオブジェクトが通貨取引オーダーを記述することを示す。 |
|
| `Expiration` | 数値 | UInt32 | いいえ | (省略可)このオファーが資金不足とみなされる時刻。詳細は、[時間の指定][]をご覧ください。 |
|
||||||
| `OwnerNode` | 文字列 | UInt64 | はい | 所有者ディレクトリーが複数ページで構成されている場合に、このオブジェクトにリンクしているページを示すヒント。**注記:** このオファーには、オファーを含む所有者ディレクトリーへの直接リンクは含まれていません。これは、その値を`Account`から取得できるためです。 |
|
| `Flags` | 数値 | UInt32 | はい | このオファーに対して有効になっているブール値フラグのビットマップ。 |
|
||||||
| `PreviousTxnID` | 文字列 | UInt256 | はい | 最後にこのオブジェクトを変更したトランザクションの識別用ハッシュ。 |
|
| `LedgerEntryType` | 文字列 | UInt16 | はい | 値が`0x006F`(文字列`Offer`にマッピング)の場合は、このオブジェクトが通貨取引オーダーを記述することを示す。 |
|
||||||
| `Sequence` | 数値 | UInt32 | はい | `Offer`オブジェクトを作成した[OfferCreate][]トランザクションの`Sequence`値。`Account`とこのフィールドの組み合わせによってこのオファーが識別されます。 |
|
| `OwnerNode` | 文字列 | UInt64 | はい | 所有者ディレクトリーが複数ページで構成されている場合に、このオブジェクトにリンクしているページを示すヒント。**注記:** このオファーには、オファーを含む所有者ディレクトリーへの直接リンクは含まれていません。これは、その値を`Account`から取得できるためです。 |
|
||||||
|
| `PreviousTxnID` | 文字列 - [ハッシュ][] | UInt256 | はい | 最後にこのオブジェクトを変更したトランザクションの識別用ハッシュ。 |
|
||||||
|
| `Sequence` | 数値 | UInt32 | はい | `Offer`オブジェクトを作成した[OfferCreate][]トランザクションの`Sequence`値。`Account`とこのフィールドの組み合わせによってこのオファーが識別されます。 |
|
||||||
| `PreviousTxnLgrSeq` | 数値 | UInt32 | はい | 最後にこのオブジェクトを変更したトランザクションが記録された[レジャーインデックス][]。 |
|
| `PreviousTxnLgrSeq` | 数値 | UInt32 | はい | 最後にこのオブジェクトを変更したトランザクションが記録された[レジャーインデックス][]。 |
|
||||||
| `TakerPays` | 文字列またはオブジェクト | Amount | はい | オファー作成者がリクエストする残額と通貨の種類。 |
|
| `TakerPays` | [通貨額][] | Amount | はい | オファー作成者がリクエストする残額と通貨の種類。 |
|
||||||
| `TakerGets` | 文字列またはオブジェクト | Amount | はい | オファー作成者が提供する残額と通貨の種類。 |
|
| `TakerGets` | [通貨額][] | Amount | はい | オファー作成者が提供する残額と通貨の種類。 |
|
||||||
|
|
||||||
## Offerのフラグ
|
## Offerのフラグ
|
||||||
|
|
||||||
`Offer`エントリは以下のフラグを`Flags`フィールドに指定することができます。
|
`Offer`エントリは以下のフラグを`Flags`フィールドに指定することができます。
|
||||||
|
|
||||||
| フラグ名 | 16進数値 | 10進数値 | 対応する[OfferCreateフラグ](../../transactions/types/offercreate.md#offercreateフラグ) | 説明 |
|
| フラグ名 | 16進数値 | 10進数値 | 対応する[OfferCreateフラグ](../../transactions/types/offercreate.md#offercreateフラグ) | 説明 |
|
||||||
|-----------|-----------|---------------|-------------|------------------------|
|
|--------------|--------------|----------|-------------|------------------------|
|
||||||
| `lsfPassive` | `0x00010000` | 65536 | `tfPassive` | オブジェクトはパッシブオファーとして発注されています。レジャー内のオブジェクトには影響しません。 |
|
| `lsfPassive` | `0x00010000` | 65536 | `tfPassive` | オブジェクトはパッシブオファーとして発注されています。レジャー内のオブジェクトには影響しません。 |
|
||||||
| `lsfSell` | `0x00020000` | 131072 | `tfSell` | オブジェクトは売却オファーとして発注されています。これは台帳にあるオブジェクトには何の影響もありません (`tfSell`は指定したレートよりも良いレートが存在する場合にのみ意味を持ち、台帳にこのフラグを持ったオブジェクトが入ることはありません。)。 |
|
| `lsfSell` | `0x00020000` | 131072 | `tfSell` | オブジェクトは売却オファーとして発注されています。これは台帳にあるオブジェクトには何の影響もありません (`tfSell`は指定したレートよりも良いレートが存在する場合にのみ意味を持ち、台帳にこのフラグを持ったオブジェクトが入ることはありません。)。 |
|
||||||
|
| `lsfHybrid` | `0x00040000` | 262144 | `tfHybrid` | ハイブリッドオファーとして作成されています。これは、[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)と公開DEXの両方にリストされていることを意味します。([PermissionedDEX amendment][] {% not-enabled /%}が必要です。) |
|
||||||
|
|
||||||
|
|
||||||
## {% $frontmatter.seo.title %}の準備金
|
## {% $frontmatter.seo.title %}の準備金
|
||||||
@@ -78,6 +81,6 @@ labels:
|
|||||||
* オファーを行うアカウントのAccountID
|
* オファーを行うアカウントのAccountID
|
||||||
* オファーを作成した[OfferCreateトランザクション][]のシーケンス番号
|
* オファーを作成した[OfferCreateトランザクション][]のシーケンス番号
|
||||||
|
|
||||||
OfferCreateトランザクションが[Ticket](../../../../concepts/accounts/tickets.md)を使用した場合、代わりに`TicketSequence`値を使用します。
|
OfferCreateトランザクションが[チケット](../../../../concepts/accounts/tickets.md)を使用した場合、代わりに`TicketSequence`値を使用します。
|
||||||
|
|
||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -100,4 +100,4 @@ _([PermissionedDomains amendment][]が必要です {% not-enabled /%})_
|
|||||||
3. 作成した{% code-page-name /%}トランザクションのシーケンス番号
|
3. 作成した{% code-page-name /%}トランザクションのシーケンス番号
|
||||||
|
|
||||||
|
|
||||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ AMMのLPトークンを使って落札すると、落札に利用したLPトー
|
|||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
||||||
|
|
||||||
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|:---------------|:-----------|:- ----------|:----- |:------------|
|
|:---------------|:-----------|:------------|:------|:------------|
|
||||||
| `Asset` | オブジェクト | STIssue | はい | AMMのプールにある資産の一つを定義します。JSONでは、`currency`と`issuer`フィールドを持つオブジェクトになります(XRPの場合は`issuer`を省略します)。 |
|
| `Asset` | オブジェクト | STIssue | はい | AMMのプールにある資産の一つを定義します。JSONでは、`currency`と`issuer`フィールドを持つオブジェクトになります(XRPの場合は`issuer`を省略します)。 |
|
||||||
| `Asset2` | オブジェクト | STIssue | はい | AMMのプールにあるもう一つのアセットの定義です。JSONでは、`currency`と`issuer`フィールドを持つオブジェクトになります(XRPの場合は`issuer`を省略します)。 |
|
| `Asset2` | オブジェクト | STIssue | はい | AMMのプールにあるもう一つのアセットの定義です。JSONでは、`currency`と`issuer`フィールドを持つオブジェクトになります(XRPの場合は`issuer`を省略します)。 |
|
||||||
| `BidMin` | [通貨額][] | Amount | いいえ | スロットに支払う最小の金額。この値を高く設定すると、他の人から競り落とされにくくなります。省略された場合は、落札に必要な最低額を支払います。 |
|
| `BidMin` | [通貨額][] | Amount | いいえ | スロットに支払う最小の金額。この値を高く設定すると、他の人から競り落とされにくくなります。省略された場合は、落札に必要な最低額を支払います。 |
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
seo:
|
||||||
|
description: 自動マーケットメーカープールに発行済みトークンを預け入れた保有者から、トークンを回収する。
|
||||||
|
labels:
|
||||||
|
- AMM
|
||||||
|
- Tokens
|
||||||
|
---
|
||||||
|
# AMMClawback
|
||||||
|
|
||||||
|
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/AMMClawback.cpp "ソース")
|
||||||
|
|
||||||
|
発行したトークンをAMMプールに預け入れた保有者からトークンを回収します。
|
||||||
|
|
||||||
|
Clawbackはデフォルトで無効です。Clawbackを使用するには、[AccountSetトランザクション][]を送信して、**Allow Trust Line Clawback**設定を有効にする必要があります。すでにトークンが発行済みである発行者はClawbackを有効にできません。**Allow Trust Line Clawback**を有効にするには、トラストライン、オファー、エスクロー、ペイメントチャネル、チェック、署名者リストを設定する前に、所有者ディレクトリを完全に空にする必要があります。Clawbackを有効にした後は、元に戻すことはできません。つまり発行者アカウントは、トラストラインの発行済みトークンを回収できる権利を永続的に得ます。
|
||||||
|
|
||||||
|
|
||||||
|
_([AMMClawback amendment][]により追加されました。)_
|
||||||
|
|
||||||
|
|
||||||
|
## {% $frontmatter.seo.title %} JSONの例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"TransactionType": "AMMClawback",
|
||||||
|
"Account": "rPdYxU9dNkbzC5Y2h4jLbVJ3rMRrk7WVRL",
|
||||||
|
"Holder": "rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B",
|
||||||
|
"Asset": {
|
||||||
|
"currency" : "FOO",
|
||||||
|
"issuer" : "rPdYxU9dNkbzC5Y2h4jLbVJ3rMRrk7WVRL"
|
||||||
|
},
|
||||||
|
"Asset2" : {
|
||||||
|
"currency" : "BAR",
|
||||||
|
"issuer" : "rHtptZx1yHf6Yv43s1RWffM3XnEYv3XhRg"
|
||||||
|
},
|
||||||
|
"Amount": {
|
||||||
|
"currency" : "FOO",
|
||||||
|
"issuer" : "rPdYxU9dNkbzC5Y2h4jLbVJ3rMRrk7WVRL",
|
||||||
|
"value" : "1000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
||||||
|
|
||||||
|
|
||||||
|
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|
|:-----------|:----------------------|:-------------|:-------|:------------------|
|
||||||
|
| `Account` | 文字列 - [アドレス][] | AccountID | はい | 回収する資産の発行者。このトランザクションは、発行者のみが送信できます。 |
|
||||||
|
| `Asset` | オブジェクト | Issue | はい | AMMプールから回収したい資産を指定します。資産はXRP、トークン、またはMPT([金額なしの指定][]を参照)です。`issuer`フィールドは`Account`と一致していなければなりません。 |
|
||||||
|
| `Asset2` | オブジェクト | Issue | はい | AMMのプール内のもう一方の資産を指定します。資産はXRP、トークン、またはMPT([金額なしの指定][]を参照)です。 |
|
||||||
|
| `Amount` | [通貨額][] | Amount | いいえ | AMMアカウントから回収する最大額を指定します。`currency`と`issuer`サブフィールドは`Asset`サブフィールドと一致していなければなりません。このフィールドが指定されていない場合、または`value`サブフィールドがAMMの保有者の利用可能なトークンを超えている場合、保有者のすべてのトークンが回収されます。 |
|
||||||
|
| `Holder` | 文字列 - [アドレス][] | AccountID | はい | 回収する資産を保有しているアカウント。 |
|
||||||
|
|
||||||
|
|
||||||
|
## AMMClawbackのフラグ
|
||||||
|
|
||||||
|
| フラグ名 | Hex値 | 10進数値 | 説明 |
|
||||||
|
|-------------------|--------------|----------|-------------|
|
||||||
|
| `tfClawTwoAssets` | `0x00000001` | 1 | `Asset`の指定額を回収し、AMMプールの資産比率に基づいて`Asset2`の対応する額を回収します。両方の資産は`Account`フィールドの発行者によって発行されなければなりません。このフラグが有効でない場合、発行者は`Asset`の指定された額を回収しますが、`Asset2`の対応する比率は`Holder`に返されます。 |
|
||||||
|
|
||||||
|
|
||||||
|
## エラーのケース
|
||||||
|
|
||||||
|
すべてのトランザクションで発生する可能性のあるエラーに加えて、`AMMClawback`トランザクションは以下の[トランザクション結果コード](../transaction-results/index.md)をもたらすことがあります。
|
||||||
|
|
||||||
|
| エラーコード | 説明 |
|
||||||
|
|:-------------------|:------------|
|
||||||
|
| `tecNO_PERMISSION` | `lsfAllowTrustlineClawback` フラグが有効になっていない状態で AMM からトークンを回収しようとした場合、または AMM で両方の資産を発行していない状態で `tfClawTwoAssets` フラグが有効になっている場合に発生します。また、`Asset` の発行者が `Account` と一致しない場合にも発生します。 |
|
||||||
|
| `tecAMM_BALANCE` | `Holder`がAMMプールのLPトークンを保有していない場合に発生します。 |
|
||||||
|
| `temDISABLED` | [AMMClawback amendment][]が有効になっていない場合に発生します。 |
|
||||||
|
| `temBAD_AMOUNT` | `AMMClawback`トランザクションの`Amount`フィールドが0以下の場合、または`currency`と`issuer`サブフィールドが`Amount`と`Asset`の間で一致しない場合に発生します。 |
|
||||||
|
| `temINVALID_FLAG` | `tfClawTwoAssets`以外のフラグを有効にしようとした場合に発生します。 |
|
||||||
|
| `temMALFORMED` | `issuer`サブフィールドが`Asset`と`Account`の間で一致しない場合、`Account`が`Holder`と同じ場合、または`Asset`がXRPの場合に発生します。 |
|
||||||
|
| `terNO_AMM` | `Asset`と`Asset2`で指定されたAMMプールが存在しない場合に発生します。 |
|
||||||
|
|
||||||
|
## 関連項目
|
||||||
|
|
||||||
|
- [AMMエントリ][]
|
||||||
|
|
||||||
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
@@ -39,12 +39,12 @@ AMMを表す[AMMエントリ][]と[特殊なAccountRootエントリ](../../ledge
|
|||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
||||||
|
|
||||||
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|:-------------|:---- -----|:-----------|:------|:------------|
|
|:-------------|:----------|:-----------|:------|:------------|
|
||||||
| `Amount` | [通貨額][] | Amount | はい | このAMMの最初の資金となる2つの資産のうち、1つ目の資産です。これは正数である必要があります。 |
|
| `Amount` | [通貨額][] | Amount | はい | このAMMの最初の資金となる2つの資産のうち、1つ目の資産です。これは正数である必要があります。 |
|
||||||
| `Amount2` | [通貨額][] | Amount | はい | このAMMの最初の資金となる2つの資産のうち、2つ目の資産です。これは正数である必要があります。 |
|
| `Amount2` | [通貨額][] | Amount | はい | このAMMの最初の資金となる2つの資産のうち、2つ目の資産です。これは正数である必要があります。 |
|
||||||
| `TradingFee` | 数値 | UInt16 | はい | このAMMインスタンスに対する取引に課される手数料を1/100,000単位で指定します(値1は0.001%に相当)。最大値は`1000`で、1%の手数料を意味します。最小値は `0`です。 |
|
| `TradingFee` | 数値 | UInt16 | はい | このAMMインスタンスに対する取引に課される手数料を1/100,000単位で指定します(値1は0.001%に相当)。最大値は`1000`で、1%の手数料を意味します。最小値は `0`です。 |
|
||||||
|
|
||||||
`Amount`と`Amount2`の一方または両方は[トークン](../../../../concepts/tokens/index.md)であり、最大でどちらか一方を[XRP](../../../../introduction/what-is-xrp.md)にすることが可能です。通貨コードと発行者が同じものは使用できません。AMMのLPトークンは、別のAMMの資産の1つとして使用することができます。トークンの発行者は[Default Ripple](../../../../concepts/tokens/fungible-tokens/rippling.md#defaultrippleフラグ)を有効にしていなければなりません。[Clawback Amendment][] が有効になっている場合、それらの発行者はAllow Clawbackフラグを有効にしていてはいけません。AMMのLPトークンは、別のAMMの資産の一つとして使用することはできません。
|
`Amount`と`Amount2`の一方または両方は[トークン](../../../../concepts/tokens/index.md)であり、最大でどちらか一方を[XRP](../../../../introduction/what-is-xrp.md)にすることが可能です。通貨コードと発行者が同じものは使用できません。AMMのLPトークンは、別のAMMの資産の1つとして使用することができます。トークンの発行者は[Default Ripple](../../../../concepts/tokens/fungible-tokens/rippling.md#defaultrippleフラグ)を有効にしていなければなりません。AMMのLPトークンは、別のAMMの資産の一つとして使用することはできません。
|
||||||
|
|
||||||
## 特殊なトランザクションコスト
|
## 特殊なトランザクションコスト
|
||||||
|
|
||||||
@@ -54,17 +54,19 @@ AMMを表す[AMMエントリ][]と[特殊なAccountRootエントリ](../../ledge
|
|||||||
|
|
||||||
すべてのトランザクションで発生する可能性のあるエラーに加えて、{% $frontmatter.seo.title %}トランザクションでは、次の[トランザクション結果コード](../transaction-results/index.md)が発生する可能性があります。
|
すべてのトランザクションで発生する可能性のあるエラーに加えて、{% $frontmatter.seo.title %}トランザクションでは、次の[トランザクション結果コード](../transaction-results/index.md)が発生する可能性があります。
|
||||||
|
|
||||||
| エラーコード | 説明 |
|
| エラーコード | 説明 |
|
||||||
|:--------------------|:---------------------------------------------|
|
|:--------------------|:---------------------------------------------|
|
||||||
| `temDISABLED` | このネットワークでは、AMM機能 |
|
| `tecAMM_INVALID_TOKENS` | `Amount`または`Amount2`が、このAMMのLPトークンと同じ通貨コードを使用しています。(これが起こることは稀です。) |
|
||||||
| `temINVALID_FLAG` | トランザクションに無効な`Flags`値が指定されています。現在、このトランザクションタイプに定義されたフラグはないので、[グローバルフラグ](../common-fields.md#グローバルフラグ)のみが許可されます。 |
|
| `tecDUPLICATE` | この通貨ペアを扱っているAMMが既に存在しています。 |
|
||||||
| `temBAD_AMM_TOKENS` | `Amount`と`Amount2`値が正しくありません。例えば、両方とも同じトークンを参照している場合です。 |
|
| `tecFROZEN` | 資産(`Amount`または`Amount2`)の少なくとも1つが現在[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
|
||||||
| `temBAD_FEE` | `TradingFee`の値が不正です。ゼロまたは正の整数でなければならず、1000を超えることはできません。 |
|
| `tecINSUF_RESERVE_LINE` | 送信者は、このトランザクションを処理するための[準備金要件](../../../../concepts/accounts/reserves.md)を満たしていません。おそらく、LPトークンを保持するための新しいトラストラインが必要で、新しいトラストラインの所有者準備金を満たす十分なXRPを持っていないためです。 |
|
||||||
| `terNO_ACCOUNT` | リクエストで参照されたいずれかのアカウントが存在しません。|
|
| `tecNO_AUTH` | 送信者は資産(`Amount`または`Amount2`)のいずれかを保有する権限がありません。 |
|
||||||
| `tecNO_AUTH` | 送信者は資産(`Amount`または`Amount2`)のいずれかを保有する権限がありません。 |
|
| `tecNO_LINE` | 送信者は資産(`Amount`または`Amount2`)のうちいずれか1つに対するトラストラインを保有していません。 |
|
||||||
| `tecNO_LINE` | 送信者は資産(`Amount`または`Amount2`)のうちいずれか1つに対するトラストラインを保有していません。 |
|
| `tecNO_PERMISSION` | 少なくとも1つの入金資産はAMMで使用できません。 |
|
||||||
| `tecFROZEN` | 資産(`Amount`または`Amount2`)の少なくとも1つが現在[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されています。 |
|
|
||||||
| `tecUNFUNDED_AMM` | 送信者は`Amount`と`Amount2`で指定された金額をAMMに入金するための十分な資金を保有していません。 |
|
| `tecUNFUNDED_AMM` | 送信者は`Amount`と`Amount2`で指定された金額をAMMに入金するための十分な資金を保有していません。 |
|
||||||
| `tecAMM_EXISTS` | この通貨ペアを扱っているAMMが既に存在しています。 |
|
| `terNO_RIPPLE` | 少なくとも1つの資産の発行者が[Default Rippleフラグ](../../../../concepts/tokens/fungible-tokens/rippling.md#defaultrippleフラグ)を有効にしていません。 |
|
||||||
|
| `temAMM_BAD_TOKENS` | `Amount`と`Amount2`値が正しくありません。例えば、両方とも同じトークンを参照している場合です。 |
|
||||||
|
| `temBAD_FEE` | `TradingFee`の値が不正です。ゼロまたは正の整数でなければならず、1000を超えることはできません。 |
|
||||||
|
| `temDISABLED` | このネットワークでは、AMM機能が無効になっています。 |
|
||||||
|
|
||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ AMMDepositトランザクションは、以下のような[`Flags`フィール
|
|||||||
| `tecAMM_EMPTY` | 現在、AMM は資産を保有していないため、通常の入金はできません。代わりに、空のAMMの場合の特殊な入金を行う必要があります。 |
|
| `tecAMM_EMPTY` | 現在、AMM は資産を保有していないため、通常の入金はできません。代わりに、空のAMMの場合の特殊な入金を行う必要があります。 |
|
||||||
| `tecAMM_NOT_EMPTY` | トランザクションで`tfTwoAssetIfEmpty`が指定されましたが、AMMは空ではありませんでした。 |
|
| `tecAMM_NOT_EMPTY` | トランザクションで`tfTwoAssetIfEmpty`が指定されましたが、AMMは空ではありませんでした。 |
|
||||||
| `tecAMM_FAILED` | 預け入れの条件が成立しませんでした。例えば、`EPrice`フィールドに指定された実効価格が低すぎる場合など。 |
|
| `tecAMM_FAILED` | 預け入れの条件が成立しませんでした。例えば、`EPrice`フィールドに指定された実効価格が低すぎる場合など。 |
|
||||||
| `tecFROZEN` | トランザクションは[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているトークンを預けようとしました。 |
|
| `tecFROZEN` | トランザクションは[フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されているトークンを預けようとした、またはプール内の資産の少なくとも1つがフリーズされています。 |
|
||||||
| `tecINSUF_RESERVE_LINE` | このトランザクションの送信者は、この処理による[準備金要件](../../../../concepts/accounts/reserves.md)の増加の対象であり、LPトークンを保持するための新しいトラストラインが必要で、そのための追加の所有者準備金分のXRPを保有していないためと思われます。 |
|
| `tecINSUF_RESERVE_LINE` | このトランザクションの送信者は、この処理による[準備金要件](../../../../concepts/accounts/reserves.md)の増加の対象であり、LPトークンを保持するための新しいトラストラインが必要で、そのための追加の所有者準備金分のXRPを保有していないためと思われます。 |
|
||||||
| `tecUNFUNDED_AMM` | 送信者の残高が、指定された預け入れを行うのに十分な量ではありません。 |
|
| `tecUNFUNDED_AMM` | 送信者の残高が、指定された預け入れを行うのに十分な量ではありません。 |
|
||||||
| `temBAD_AMM_TOKENS` | トランザクションでLPトークンを指定しましたが、`issuer`がAMMに紐づくAccountアドレスではない、または`currency`がこのAMMのLPトークンの通貨コードではない、またはトランザクションでこのAMMのLPトークンをAssetフィールドのいずれかに指定しました。 |
|
| `temBAD_AMM_TOKENS` | トランザクションでLPトークンを指定しましたが、`issuer`がAMMに紐づくAccountアドレスではない、または`currency`がこのAMMのLPトークンの通貨コードではない、またはトランザクションでこのAMMのLPトークンをAssetフィールドのいずれかに指定しました。 |
|
||||||
|
|||||||
@@ -170,4 +170,4 @@ status: not_enabled
|
|||||||
| `temINVALID_INNER_BATCH` | 内部トランザクションの形式が不正です。 |
|
| `temINVALID_INNER_BATCH` | 内部トランザクションの形式が不正です。 |
|
||||||
| `temSEQ_AND_TICKET` | トランザクションに`TicketSequence`フィールドと、0以外の`Sequence`フィールドの両方が含まれています。両方を同時に指定することはできませんが、いずれか一方は必須です。 |
|
| `temSEQ_AND_TICKET` | トランザクションに`TicketSequence`フィールドと、0以外の`Sequence`フィールドの両方が含まれています。両方を同時に指定することはできませんが、いずれか一方は必須です。 |
|
||||||
|
|
||||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -34,43 +34,46 @@ OfferCreateトランザクションは[分散型取引所](../../../../concepts/
|
|||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
||||||
|
|
||||||
|
|
||||||
| フィールド | JSONの型 | [内部の型][] | 説明 |
|
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|:-----------------|:----------|:------------|:-----------|
|
|:-----------------|:----------------------|:-------------|:---------|:-----------|
|
||||||
| [Expiration](../../../../concepts/tokens/decentralized-exchange/offers.md#オファーの有効期限) | 数字 | UInt32 | _(省略可)_ オファーがアクティブでなくなるまでの時間([Rippleエポック以降の経過秒数][])。 |
|
| `DomainID` | 文字列 - [ハッシュ][] | Hash256 | いいえ | 許可型DEXのレジャーエントリID。指定された場合、対応する[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用するパスを返します。([PermissionedDEX amendment][] {% not-enabled /%}が必要です。) |
|
||||||
| `OfferSequence` | 数字 | UInt32 | _(省略可)_ 最初に削除されるオファー([OfferCancel][]と同様に指定されます)。 |
|
| [`Expiration`](../../../../concepts/tokens/decentralized-exchange/offers.md#オファーの有効期限) | 整数 | UInt32 | いいえ | オファーがアクティブでなくなるまでの時間([Rippleエポック以降の経過秒数][])。 |
|
||||||
| `TakerGets` | [通貨額][] | Amount | オファーの作成者によって作成される金額および通貨の種類。 |
|
| `OfferSequence` | 整数 | UInt32 | いいえ | 最初に削除されるオファー([OfferCancel][]と同様に指定されます)。 |
|
||||||
| `TakerPays` | [通貨額][] | Amount | オファーの作成者によってリクエストされる金額および通貨の種類。 |
|
| `TakerGets` | [通貨額][] | Amount | はい | オファーの作成者によって作成される金額および通貨の種類。 |
|
||||||
|
| `TakerPays` | [通貨額][] | Amount | はい | オファーの作成者によってリクエストされる金額および通貨の種類。 |
|
||||||
|
|
||||||
## OfferCreateフラグ
|
## OfferCreateフラグ
|
||||||
|
|
||||||
OfferCreate型のトランザクションについては、[`Flags`フィールド](../common-fields.md#flagsフィールド)で以下の値が追加でサポートされます。
|
OfferCreate型のトランザクションについては、[`Flags`フィールド](../common-fields.md#flagsフィールド)で以下の値が追加でサポートされます。
|
||||||
|
|
||||||
| フラグ名 | 16進数 | 10進数 | 説明 |
|
| フラグ名 | 16進数 | 10進数 | 説明 |
|
||||||
|:----------------------|:-------------|:--------------|:-------------------|
|
|:----------------------|:-------------|:--------------|:-------------------|
|
||||||
| `tfPassive` | `0x00010000` | 65536 | 有効な場合、オファーはオファーが完全に約定するオファーを消費せず、代わりにレジャーのOfferオブジェクトになります。それはまだクロスしたオファーを消費します。 |
|
| `tfPassive` | `0x00010000` | 65536 | このオファーと完全に一致するオファーを約定しません。これにより、特定の値で交換レートを固定するオファーを台帳に設定できます。 |
|
||||||
| `tfImmediateOrCancel` | `0x00020000` | 131072 | オファーを[IOC注文](http://en.wikipedia.org/wiki/Immediate_or_cancel)として扱います。有効な場合、オファーはレジャーオブジェクトにはなりません。レジャー内の既存のオファーと約定させようとするだけです。即時にオファーがどのオファーとも約定しない場合、どの通貨とも取引せずに「正常に」実行します。この場合、トランザクションは`tesSUCCESS`の[結果コード](../transaction-results/index.md)を返しますが、レジャー内には、[Offerオブジェクト](../../ledger-data/ledger-entry-types/offer.md)を作成しません。 |
|
| `tfImmediateOrCancel` | `0x00020000` | 131072 | オファーを[即時またはキャンセル注文](http://en.wikipedia.org/wiki/Immediate_or_cancel)として扱い、[Offerエントリ][]をオーダーブックに配置しません。トランザクションは、処理時に既存のオファーを約定し、可能な限り多くの取引を行います。 |
|
||||||
| `tfFillOrKill` | `0x00040000` | 262144 | オファーを[FOK注文](http://en.wikipedia.org/wiki/Fill_or_kill)として扱います。レジャー内の既存のオファーのみを約定しようとします。またこれは、全`TakerPays`の数量が取得できる場合に限られます。[fix1578 amendment][]が有効な場合でオファーを配置した時に実行できない場合、トランザクションは`tecKILLED`の[結果コード](../transaction-results/index.md)を返します。そうでない場合は、トランザクションは、どの通貨とも取り引きせずにキャンセルされた場合でも`tesSUCCESS`の結果コードを返します。 |
|
| `tfFillOrKill` | `0x00040000` | 262144 | オファーを[即時またはキャンセル注文](http://en.wikipedia.org/wiki/Fill_or_kill)として扱い、[Offerエントリ][]をオーダーブックに配置しません。実行時に完全に約定できない場合、オファーをキャンセルします。デフォルトでは、所有者は完全な`TakerPays`の金額を受け取る必要があります。`tfSell`フラグが有効な場合、所有者は代わりに完全な`TakerGets`の金額を約定できる必要があります。 |
|
||||||
| `tfSell` | `0x00080000` | 524288 | 取引所で`TakerPays`Amountよりも多く取得することになっても、`TakerGets` Amountを交換します。 |
|
| `tfSell` | `0x00080000` | 524288 | 取引所で`TakerPays`の金額よりも多く取得することになっても、`TakerGets`の金額を約定します。 |
|
||||||
|
| `tfHybrid` | `0x00100000` | 1048576 | 許可型DEXとオープンDEXの両方を使用できるハイブリッドオファーにします。このフラグを使用する場合、`DomainID`フィールドを指定する必要があります。 |
|
||||||
|
|
||||||
## エラーケース
|
## エラーケース
|
||||||
|
|
||||||
| エラーコード | 説明 |
|
| エラーコード | 説明 |
|
||||||
|:-------------------------|:--------------------------------------------------|
|
|:-------------------------|:--------------------------------------------------|
|
||||||
| `temINVALID_FLAG` | トランザクションが`tfImmediateOrCancel`と`tfFillOrKill`両方を指定した場合に発生します。|
|
|
||||||
| `tecEXPIRED` | トランザクションが指定した`Expiration`の時間が既に経過している場合に発生します。 |
|
|
||||||
| `tecKILLED` | トランザクションが`tfFillOrKill`を指定し、全額を約定できない場合に発生します。_[ImmediateOfferKilled amendment][]_ が有効な場合、この結果コードは、トランザクションが`tfImmediateOrCancel`を指定して資金が移動せずに実行された場合にも発生します(これまでは、これは`tesSUCCESS`を返していました)。 |
|
|
||||||
| `temBAD_EXPIRATION` | トランザクションの`Expiration`フィールドの値が無効なフォーマットの場合に発生します。 |
|
|
||||||
| `temBAD_SEQUENCE` | トランザクションの`OfferSequence`フィールドの値が無効なフォーマットであるか、トランザクション自身の`Sequence`番号より大きい場合に発生します。 |
|
|
||||||
| `temBAD_OFFER` | OfferがXRPとXRPを交換しようとした場合、またはトークンの無効な量やマイナスの量を交換しようとした場合に発生します。 |
|
|
||||||
| `temREDUNDANT` | トランザクションが同じトークン(同じ発行者、通貨コード)を指定した場合に発生します。 |
|
|
||||||
| `temBAD_CURRENCY` | トランザクションで通貨コードが"XRP"のトークンが指定された場合に発生します。 |
|
|
||||||
| `temBAD_ISSUER` | トランザクションが無効な`issuer`値を持つトークンを指定した場合に発生します。 |
|
|
||||||
| `tecNO_ISSUER` | トランザクションで、`issuer`の値が台帳の有効化されたアカウントでないトークンを指定した場合に発生します。|
|
|
||||||
| `tecFROZEN` | [フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されたトラストライン(ローカルおよびグローバルのフリーズを含む)上のトークンを含むトランザクションの場合に発生します。`TakerPays`(購入額)トークンが発行者によってディープフリーズされている場合に発生します。 |
|
|
||||||
| `tecUNFUNDED_OFFER` | トランザクションの送信者が`TakerGets`の通貨を正の値で保有していない場合に発生する。(例外: `TakerGets`にトランザクションの送信者が発行するトークンを指定した場合、トランザクションは成功します)。 |
|
|
||||||
| `tecNO_LINE` | 発行者が[Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使用しているトークンを含むトランザクションで、必要なトラストラインが存在しない場合に発生します。 |
|
|
||||||
| `tecNO_AUTH` | 発行者が[Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使用しているトークンを含むトランザクションで、トークンを受け取るトラストラインが存在するが認証されていない場合に発生します。 |
|
|
||||||
| `tecINSUF_RESERVE_OFFER` | 所有者が台帳に新しいOfferオブジェクトを追加するための準備要件を満たすのに十分なXRPを持っておらず、トランザクションがどの通貨も変換しなかった場合に発生します。(トランザクションが何らかの金額のトレードに成功した場合、トランザクションは結果コード`tesSUCCESS`で成功しますが、残りは台帳にOfferオブジェクトを作成しません)。 |
|
|
||||||
| `tecDIR_FULL` | トランザクションの送信者が台帳で多くのアイテムを所有している場合、またはオーダーブックに同じ取引レートのオファーがすでに多く含まれている場合に発生します。 |
|
| `tecDIR_FULL` | トランザクションの送信者が台帳で多くのアイテムを所有している場合、またはオーダーブックに同じ取引レートのオファーがすでに多く含まれている場合に発生します。 |
|
||||||
|
| `tecEXPIRED` | トランザクションが指定した`Expiration`の時間が既に経過している場合に発生します。 |
|
||||||
|
| `tecFROZEN` | [フリーズ](../../../../concepts/tokens/fungible-tokens/freezes.md)されたトラストライン(ローカルおよびグローバルのフリーズを含む)上のトークンを含むトランザクションの場合に発生します。`TakerPays`(購入額)トークンが発行者によってディープフリーズされている場合に発生します。 |
|
||||||
|
| `tecINSUF_RESERVE_OFFER` | 所有者が台帳に新しいOfferオブジェクトを追加するための準備要件を満たすのに十分なXRPを持っておらず、トランザクションがどの通貨も変換しなかった場合に発生します。(トランザクションが何らかの金額のトレードに成功した場合、トランザクションは結果コード`tesSUCCESS`で成功しますが、残りは台帳にOfferオブジェクトを作成しません)。 |
|
||||||
|
| `tecKILLED` | トランザクションが`tfFillOrKill`を指定し、全額を約定できない場合に発生します。_[ImmediateOfferKilled amendment][]_ が有効な場合、この結果コードは、トランザクションが`tfImmediateOrCancel`を指定して資金が移動せずに実行された場合にも発生します(これまでは、これは`tesSUCCESS`を返していました)。 |
|
||||||
|
| `tecNO_AUTH` | 発行者が[Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使用しているトークンを含むトランザクションで、トークンを受け取るトラストラインが存在するが認証されていない場合に発生します。 |
|
||||||
|
| `tecNO_ISSUER` | トランザクションで、`issuer`の値が台帳の有効化されたアカウントでないトークンを指定した場合に発生します。|
|
||||||
|
| `tecNO_LINE` | 発行者が[Authorized Trust Lines](../../../../concepts/tokens/fungible-tokens/authorized-trust-lines.md)を使用しているトークンを含むトランザクションで、必要なトラストラインが存在しない場合に発生します。 |
|
||||||
|
| `tecNO_PERMISSION` | トランザクションが`DomainID`を使用しているが、送信者がそのドメインのメンバーではない場合に発生します。([PermissionedDEX amendment][] {% not-enabled /%}) |
|
||||||
|
| `tecUNFUNDED_OFFER` | トランザクションの送信者が`TakerGets`の通貨を正の値で保有していない場合に発生する。(例外: `TakerGets`にトランザクションの送信者が発行するトークンを指定した場合、トランザクションは成功します)。 |
|
||||||
|
| `temBAD_CURRENCY` | トランザクションで通貨コードが"XRP"のトークンが指定された場合に発生します。 |
|
||||||
|
| `temBAD_EXPIRATION` | トランザクションの`Expiration`フィールドの値が無効なフォーマットの場合に発生します。 |
|
||||||
|
| `temBAD_ISSUER` | トランザクションが無効な`issuer`値を持つトークンを指定した場合に発生します。 |
|
||||||
|
| `temBAD_OFFER` | OfferがXRPとXRPを交換しようとした場合、またはトークンの無効な量やマイナスの量を交換しようとした場合に発生します。 |
|
||||||
|
| `temBAD_SEQUENCE` | トランザクションの`OfferSequence`フィールドの値が無効なフォーマットであるか、トランザクション自身の`Sequence`番号より大きい場合に発生します。 |
|
||||||
|
| `temINVALID_FLAG` | トランザクションが`tfImmediateOrCancel`と`tfFillOrKill`両方を指定した場合に発生します。|
|
||||||
|
| `temREDUNDANT` | トランザクションが同じトークン(同じ発行者、通貨コード)を指定した場合に発生します。 |
|
||||||
|
|
||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ labels:
|
|||||||
- トークン
|
- トークン
|
||||||
---
|
---
|
||||||
# Payment
|
# Payment
|
||||||
[[ソース]](https://github.com/XRPLF/rippled/blob/5425a90f160711e46b2c1f1c93d68e5941e4bfb6/src/ripple/app/transactors/Payment.cpp "ソース")
|
[[ソース]](https://github.com/XRPLF/rippled/blob/master/src/xrpld/app/tx/detail/Payment.cpp "ソース")
|
||||||
|
|
||||||
Paymentトランザクションは、アカウント間での価値の移動を表現するものです(通過するパスによっては、非可分的に発生する追加的な価値交換を伴うことがあります)。このトランザクションタイプはいくつかの[支払いの種類](#paymentの種類)に使用することがでできます。
|
Paymentトランザクションは、アカウント間での価値の移動を表現するものです(通過するパスによっては、非可分的に発生する追加的な価値交換を伴うことがあります)。このトランザクションタイプはいくつかの[支払いの種類](#paymentの種類)に使用することがでできます。
|
||||||
|
|
||||||
@@ -37,17 +37,18 @@ Paymentは、[アカウントを作成](#アカウントの作成)する唯一
|
|||||||
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/tx-fields-intro.md" /%}
|
||||||
|
|
||||||
|
|
||||||
| フィールド | JSONの型 | [内部の型][] | 説明 |
|
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
| :--------------- | :------------------ | :----------- | ---- |
|
| :--------------- | :-------------------- | :----------- | :---------- | :---- |
|
||||||
| `Amount` | [通貨額][] | Amount | `DeliverMax`のエイリアス |
|
| `Amount` | [通貨額][] | Amount | APIv1: はい | `DeliverMax`のエイリアス |
|
||||||
| `CredentialIDs` | 文字列の配列 | Vector256 | このトランザクションによって作成される入金を承認するための、受取人によって事前承認された資格証明のセット。配列の各メンバは、レジャーのCredentialエントリのレジャーエントリIDでなければなりません。(_[**Credentials** amendment](../../../../../resources/known-amendments.md#credentials)が必要です。_ {% not-enabled /%}) |
|
| `CredentialIDs` | 文字列の配列 | Vector256 | いいえ | このトランザクションによって作成される入金を承認するための、受取人によって事前承認された資格証明のセット。配列の各メンバは、レジャーのCredentialエントリのレジャーエントリIDでなければなりません。(_[**Credentials** amendment](../../../../../resources/known-amendments.md#credentials)が必要です。_ {% not-enabled /%}) |
|
||||||
| `DeliverMax` | [Currency Amount][] | Amount | [API v2][]: 送金する通貨額。XRP以外の金額の場合、入れ子フィールドの名前では、アルファベットの小文字のみ使用してください。[**tfPartialPayment**フラグ](#paymentのフラグ)が設定されている場合は、この金額を _上限_ とする金額を送金します。 {% badge href="https://github.com/XRPLF/rippled/releases/tag/2.0.0" %}新規: rippled 2.0.0{% /badge %} |
|
| `DeliverMax` | [通貨額][] | Amount | はい | [API v2][]: 送金する通貨額。XRP以外の金額の場合、入れ子フィールドの名前では、アルファベットの小文字のみ使用してください。[**tfPartialPayment**フラグ](#paymentのフラグ)が設定されている場合は、この金額を _上限_ とする金額を送金します。 {% badge href="https://github.com/XRPLF/rippled/releases/tag/2.0.0" %}新規: rippled 2.0.0{% /badge %} |
|
||||||
| `DeliverMin` | [通貨額][] | Amount | _(省略可)_ このトランザクションで送金する、宛先通貨での最少金額。[Partial Payments](../../../../concepts/payment-types/partial-payments.md)の場合のみ有効になります。XRP以外の金額の場合、入れ子フィールドの名前では、アルファベットの小文字のみ使用してください。 |
|
| `DeliverMin` | [通貨額][] | Amount | いいえ | _(省略可)_ このトランザクションで送金する、宛先通貨での最少金額。[Partial Payments](#partial-payments)の場合のみ有効になります。XRP以外の金額の場合、入れ子フィールドの名前では、アルファベットの小文字のみ使用してください。 |
|
||||||
| `Destination` | 文字列 | AccountID | 支払いを受取るアカウントの一意アドレス。 |
|
| `Destination` | 文字列 - [アドレス][] | AccountID | はい | 支払いを受取るアカウントの一意アドレス。 |
|
||||||
| `DestinationTag` | 数値 | UInt32 | _(省略可)_ 宛先(支払先となる、ホスティングされている受取人)への支払い理由を明確にするための任意のタグ。 |
|
| `DestinationTag` | 数値 | UInt32 | いいえ | 宛先(支払先となる、ホスティングされている受取人)への支払い理由を明確にするための任意のタグ。 |
|
||||||
| `InvoiceID` | 文字列 | UInt256 | _(省略可)_ この支払いの具体的な理由または識別子を表現する任意の256ビットハッシュ。 |
|
| `DomainID` | String - [Hash][] | Hash256 | いいえ | 許可されたドメインのレジャーエントリID。クロスカレンシー支払いの場合は、通貨を変換するために、対応する[許可されたDEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)のみを使用してください。送信者と受取人の両方が、指定されたドメインへのアクセスを許可する有効な資格証明を持っている必要があります。このフィールドは、クロスカレンシー支払いではない場合は効果がありません。(_[**PermissionedDEX** amendment][]が必要です。_ {% not-enabled /%}) |
|
||||||
| `Paths` | パス配列の配列 | PathSet | (省略可。自動入力可能)このトランザクションに使用される[支払いパス](../../../../concepts/tokens/fungible-tokens/paths.md)の配列。XRP間のトランザクションでは省略する必要があります。 |
|
| `InvoiceID` | 文字列 - 16進文字 | UInt256 | いいえ | この支払いの具体的な理由または識別子を表現する任意の256ビットハッシュ。 |
|
||||||
| `SendMax` | [通貨額][] | Amount | _(省略可)_ [送金手数料](../../../../concepts/tokens/transfer-fees.md)、為替レート、[スリッページ](http://en.wikipedia.org/wiki/Slippage_%28finance%29)を含め、このトランザクションに関して支払い元通貨での負担を許容する上限額。[トランザクションの送信コストとしてバーンされるXRP](../../../../concepts/transactions/transaction-cost.md)は含めないでください。XRP以外の金額の場合、入れ子フィールドの名前では、アルファベットの小文字のみ使用してください。クロスカレンシー支払いまたは複数のトークンを伴う支払いについては、このフィールドを入力する必要があります。XRP間の支払いでは省略する必要があります。 |
|
| `Paths` | パス配列の配列 | PathSet | いいえ | _(自動入力可能)_ このトランザクションに使用される[支払いパス](../../../../concepts/tokens/fungible-tokens/paths.md)の配列。XRP間のトランザクションでは省略する必要があります。 |
|
||||||
|
| `SendMax` | [通貨額][] | Amount | いいえ | [送金手数料](../../../../concepts/tokens/transfer-fees.md)、為替レート、[スリッページ](http://en.wikipedia.org/wiki/Slippage_%28finance%29)を含め、このトランザクションに関して支払い元通貨での負担を許容する上限額。[トランザクションの送信コストとしてバーンされるXRP](../../../../concepts/transactions/transaction-cost.md)は含めないでください。XRP以外の金額の場合、入れ子フィールドの名前では、アルファベットの小文字のみ使用してください。クロスカレンシー支払いまたは複数のトークンを伴う支払いについては、このフィールドを入力する必要があります。XRP間の支払いでは省略する必要があります。 |
|
||||||
|
|
||||||
トランザクションを指定する際は、`Amount`または`DeliverMax`のいずれかを指定する必要がありますが、両方を指定することはできません。JSONでトランザクションを表示する場合、API v1では常に`Amount`を使用し、API v2(以降)では常に`DeliverMax`を使用します。
|
トランザクションを指定する際は、`Amount`または`DeliverMax`のいずれかを指定する必要がありますが、両方を指定することはできません。JSONでトランザクションを表示する場合、API v1では常に`Amount`を使用し、API v2(以降)では常に`DeliverMax`を使用します。
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ Paymentトランザクションタイプは、いくつかの異なるタイプ
|
|||||||
| [クロスカレンシー(通貨間)決済][] | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 通常は必須 | いいえ | 発行された通貨を保有者から別の保有者に送信します。`Amount`と`SendMax`の両方をXRPにすることはできません。これらの支払いは、発行者を介して[リップリング](../../../../concepts/tokens/fungible-tokens/rippling.md)し、トランザクションがパスセットを指定した場合、複数の仲介者を介してより長い[パス](../../../../concepts/tokens/fungible-tokens/paths.md)を取ることができます。トランザクション形式には、発行者が設定した[送金手数料](../../../../concepts/tokens/transfer-fees.md) が適用されます。これらのトランザクションは、異なる通貨間や、場合によっては同じ通貨コードで異なる発行者の通貨間を接続するために、[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)のオファーを利用します。 |
|
| [クロスカレンシー(通貨間)決済][] | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 通常は必須 | いいえ | 発行された通貨を保有者から別の保有者に送信します。`Amount`と`SendMax`の両方をXRPにすることはできません。これらの支払いは、発行者を介して[リップリング](../../../../concepts/tokens/fungible-tokens/rippling.md)し、トランザクションがパスセットを指定した場合、複数の仲介者を介してより長い[パス](../../../../concepts/tokens/fungible-tokens/paths.md)を取ることができます。トランザクション形式には、発行者が設定した[送金手数料](../../../../concepts/tokens/transfer-fees.md) が適用されます。これらのトランザクションは、異なる通貨間や、場合によっては同じ通貨コードで異なる発行者の通貨間を接続するために、[分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)のオファーを利用します。 |
|
||||||
| [Partial payment][] | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 通常は必須 | いいえ | 任意の通貨を特定の金額まで送ります。[`tfPartialPayment` フラグ](#paymentのフラグ)を使用します。トランザクションが成功するための最小値を指定する `DeliverMin` 値を含めることができます。トランザクションが `DeliverMin` を指定しない場合、_任意の正の値_ を指定して成功させることができる。 |
|
| [Partial payment][] | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 通常は必須 | いいえ | 任意の通貨を特定の金額まで送ります。[`tfPartialPayment` フラグ](#paymentのフラグ)を使用します。トランザクションが成功するための最小値を指定する `DeliverMin` 値を含めることができます。トランザクションが `DeliverMin` を指定しない場合、_任意の正の値_ を指定して成功させることができる。 |
|
||||||
| 通貨変換 | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 必須 | はい | [分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)のオファーを消費して、ある通貨を別の通貨に交換し、[裁定取引](https://ja.wikipedia.org/wiki/%E8%A3%81%E5%AE%9A%E5%8F%96%E5%BC%95)の機会を得ることが出来ます。`Amount`と `SendMax` の両方を XRP にすることはできません。[Data API](../../../data-api.md) は、このタイプの取引を "payment" ではなく、"exchange" として追跡しています。 |
|
| 通貨変換 | オブジェクト (非XRP) / 文字列 (XRP) | オブジェクト (非XRP) / 文字列 (XRP) | 必須 | はい | [分散型取引所](../../../../concepts/tokens/decentralized-exchange/index.md)のオファーを消費して、ある通貨を別の通貨に交換し、[裁定取引](https://ja.wikipedia.org/wiki/%E8%A3%81%E5%AE%9A%E5%8F%96%E5%BC%95)の機会を得ることが出来ます。`Amount`と `SendMax` の両方を XRP にすることはできません。[Data API](../../../data-api.md) は、このタイプの取引を "payment" ではなく、"exchange" として追跡しています。 |
|
||||||
| MPTの支払い | オブジェクト | 省略 | 省略 | はい | MPTを保有者に送信します。[MPTの支払い](#mpt-payments)をご覧ください。 |
|
| MPTの支払い | オブジェクト | 省略 | 省略 | いいえ | MPTを保有者に送信します。[MPTの支払い](#mpt-payments)をご覧ください。 |
|
||||||
|
|
||||||
[XRP同士の直接支払い]: ../../../../concepts/payment-types/direct-xrp-payments.md
|
[XRP同士の直接支払い]: ../../../../concepts/payment-types/direct-xrp-payments.md
|
||||||
[発行通貨の作成・償還]: ../../../../concepts/tokens/index.md
|
[発行通貨の作成・償還]: ../../../../concepts/tokens/index.md
|
||||||
@@ -74,11 +75,11 @@ Paymentトランザクションタイプは、いくつかの異なるタイプ
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
ほとんどの場合、XRP以外の[通貨額][]の`issuer`フィールドは、金融機関の[発行アドレス](../../../../concepts/accounts/account-types.md)を示しています。ただし、支払いを記述するにあたって、支払いの`Amount`フィールドと`SendMax`フィールドにある`issuer`フィールドについては、特殊なルールが存在します。
|
ほとんどの場合、XRP以外の[通貨額][]の`issuer`フィールドは、金融機関の[発行アドレス](../../../../concepts/accounts/account-types.md)を示しています。ただし、支払いを記述するにあたって、支払いの`DeliverMax`(または`Amount`)フィールドと`SendMax`フィールドにある`issuer`フィールドについては、特殊なルールが存在します。
|
||||||
|
|
||||||
* 2つのアドレス間で、同一の通貨に関して存在する残高は常に1つです。つまり、金額の`issuer`フィールドが実際に表しているのは、イシュアンスを作成したアドレスではなく、イシュアンスを換金する相手方であることがあります。
|
* 2つのアドレス間で、同一の通貨に関して存在する残高は常に1つです。つまり、金額の`issuer`フィールドが実際に表しているのは、イシュアンスを作成したアドレスではなく、イシュアンスを換金する相手方であることがあります。
|
||||||
* 宛先`Amount`フィールドの`issuer`フィールドが`Destination`アドレスと一致している場合、「宛先が受け入れるあらゆるイシュアー」を意味する特殊なケースとして取り扱われます。これには、他のトラストラインで保持されている宛先によって作成されたイシュアンスに加え、宛先が当該アドレスまでトラストラインを延長しているすべてのアドレスが含まれます。
|
* 宛先`DeliverMax`フィールドの`issuer`フィールドが`Destination`アドレスと一致している場合、「宛先が受け入れるあらゆるイシュアー」を意味する特殊なケースとして取り扱われます。これには、他のトラストラインで保持されている宛先によって作成されたイシュアンスに加え、宛先が当該アドレスまでトラストラインを延長しているすべてのアドレスが含まれます。
|
||||||
* `SendMax`フィールドの`issuer`フィールドが送信元アカウントのアドレスと一致している場合、「送信元が使用できるあらゆるイシュアー」を意味する特殊なケースとして取り扱われます。これには、他のアカウントが送信元アカウントまで延長しているトラストラインで新しいイシュアンスを作成すること、送信元アカウントが保持しているイシュアンスを他のイシュアーから送信することが含まれます。
|
* `SendMax`フィールドの`issuer`フィールドが送信元アカウントのアドレスと一致している場合、「送信元が使用できるあらゆるイシュアー」を意味する特殊なケースとして取り扱われます。送信元アカウントが既に保有しているトークンを送信するか、送信元アカウントと信頼関係にある他のユーザーに対して新しいトークンを発行することができます。
|
||||||
|
|
||||||
## アカウントの作成
|
## アカウントの作成
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ Payment型のトランザクションについては、[`Flags`フィールド](
|
|||||||
| フラグの名前 | 16進値 | 10進値 | 説明 |
|
| フラグの名前 | 16進値 | 10進値 | 説明 |
|
||||||
| :----------------- | :----------- | :----- | ---- |
|
| :----------------- | :----------- | :----- | ---- |
|
||||||
| `tfNoRippleDirect` | `0x00010000` | 65536 | デフォルトパスを使用せず、`Paths`フィールドに含まれているパスのみ使用します。これによりトランザクションは強制的に裁定機会を活用することになります。ほとんどのクライアントでは、これは必要ありません。 |
|
| `tfNoRippleDirect` | `0x00010000` | 65536 | デフォルトパスを使用せず、`Paths`フィールドに含まれているパスのみ使用します。これによりトランザクションは強制的に裁定機会を活用することになります。ほとんどのクライアントでは、これは必要ありません。 |
|
||||||
| `tfPartialPayment` | `0x00020000` | 131072 | `SendMax`を超えていないのに指定された`Amount`を送金できない場合、即座に失敗とするのではなく、受取られる額を減額します。詳細は、[Partial Payments](../../../../concepts/payment-types/partial-payments.md)をご覧ください。 |
|
| `tfPartialPayment` | `0x00020000` | 131072 | `SendMax`を超えていないのに指定された`Amount`を送金できない場合、即座に失敗とするのではなく、受取られる額を減額します。詳細は、[Partial Payments](#partial-payments)をご覧ください。 |
|
||||||
| `tfLimitQuality` | `0x00040000` | 262144 | すべての変換で、入力と出力との比率が`Amount`と`SendMax`との比率と同一であるか、さらに有利となるパスのみを採用します。詳細は、[クオリティの制限](#クオリティの制限)をご覧ください。 |
|
| `tfLimitQuality` | `0x00040000` | 262144 | すべての変換で、入力と出力との比率が`Amount`と`SendMax`との比率と同一であるか、さらに有利となるパスのみを採用します。詳細は、[クオリティの制限](#クオリティの制限)をご覧ください。 |
|
||||||
|
|
||||||
## Partial Payments
|
## Partial Payments
|
||||||
@@ -184,6 +185,10 @@ _([Credentials amendment][]が必要です。 {% not-enabled /%})_
|
|||||||
|
|
||||||
提供された資格証明が、Deposit Authorizationを使用していないアカウントに対して提供されている場合、資格証明は不要ですが、有効性は依然としてチェックされます。
|
提供された資格証明が、Deposit Authorizationを使用していないアカウントに対して提供されている場合、資格証明は不要ですが、有効性は依然としてチェックされます。
|
||||||
|
|
||||||
|
{% admonition type="info" name="注記" %}
|
||||||
|
`CredentialIDs`フィールドは、デポジットの承認処理にのみ使用され、[許可型DEX](../../../../concepts/tokens/decentralized-exchange/permissioned-dexes.md)での取引には使用されません。ただし、許可型DEXでもアクセス権限を付与するために認証情報が使用されます。許可型DEXで取引を行うには、`DomainID`フィールドを使用して、有効な資格情報を保持しているドメインを指定する必要があります。
|
||||||
|
{% /admonition %}
|
||||||
|
|
||||||
|
|
||||||
## 準備金を下回るアカウントに対する特別な送金のケース
|
## 準備金を下回るアカウントに対する特別な送金のケース
|
||||||
|
|
||||||
|
|||||||
@@ -45,4 +45,4 @@ _([PermissionedDomains amendment][]が必要です {% not-enabled /%})_
|
|||||||
| `tecNO_ENTRY` | `DomainID`フィールドで指定された許可型ドメインがレジャーに存在しません。 |
|
| `tecNO_ENTRY` | `DomainID`フィールドで指定された許可型ドメインがレジャーに存在しません。 |
|
||||||
| `temDISABLED` | `PermissionedDomains` amendmentが有効ではありません。 |
|
| `temDISABLED` | `PermissionedDomains` amendmentが有効ではありません。 |
|
||||||
|
|
||||||
{% raw-partial file="/docs/_snippets/common-links.md" /%}
|
{% raw-partial file="/@l10n/ja/docs/_snippets/common-links.md" /%}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ _([XChainBridge Amendment][] {% not-enabled /%} が必要です)_
|
|||||||
## XChainModifyBridgeのフィールド
|
## XChainModifyBridgeのフィールド
|
||||||
|
|
||||||
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
| フィールド | JSONの型 | [内部の型][] | 必須? | 説明 |
|
||||||
|:-------------------------|:-------------|:-------- -----|:------|-----|
|
|:-------------------------|:-------------|:--------------|:------|-----|
|
||||||
| `Flags` | 数値 | UInt32 | はい | このトランザクションのフラグを指定します。 |
|
| `Flags` | 数値 | UInt32 | はい | このトランザクションのフラグを指定します。 |
|
||||||
| `MinAccountCreateAmount` | [通貨額][] | Amount | いいえ | `XChainAccountCreateCommit`トランザクションに必要な最小金額。このフィールドが存在しない場合、`XChainAccountCreateCommit`トランザクションは失敗します。このフィールドはXRP-XRPブリッジにのみ存在できます。 |
|
| `MinAccountCreateAmount` | [通貨額][] | Amount | いいえ | `XChainAccountCreateCommit`トランザクションに必要な最小金額。このフィールドが存在しない場合、`XChainAccountCreateCommit`トランザクションは失敗します。このフィールドはXRP-XRPブリッジにのみ存在できます。 |
|
||||||
| `SignatureReward` | [通貨額][] | Amount | いいえ | Witnessサーバに支払う署名の報酬の合計額。この金額は署名者の間で分配されます。 |
|
| `SignatureReward` | [通貨額][] | Amount | いいえ | Witnessサーバに支払う署名の報酬の合計額。この金額は署名者の間で分配されます。 |
|
||||||
|
|||||||
@@ -829,6 +829,9 @@ resources.dev-tools.websocket-api.curl.modal.desc.part2: を使用してこれ
|
|||||||
API Methods: APIメソッド
|
API Methods: APIメソッド
|
||||||
Methods: メソッド
|
Methods: メソッド
|
||||||
Examples: の例
|
Examples: の例
|
||||||
|
# resources/dev-tools/websocket-api/ClioOnly.tsx
|
||||||
|
resources.dev-tools.websocket-api.clio-only-badge: Clioのみ
|
||||||
|
resources.dev-tools.websocket-api.clio-only-tooltip: このメソッドはClioサーバーからのみ利用可能です。
|
||||||
|
|
||||||
# resources/dev-tools/xrp-ledger-toml-checker.page.tsx
|
# resources/dev-tools/xrp-ledger-toml-checker.page.tsx
|
||||||
resources.dev-tools.toml-checker.p.part1: もしあなたがXRP Ledgerバリデータを運営していたり、XRP Ledgerをビジネスで利用しているのであれば、XRP Ledgerの利用状況に関する情報を、機械読み取り可能な
|
resources.dev-tools.toml-checker.p.part1: もしあなたがXRP Ledgerバリデータを運営していたり、XRP Ledgerをビジネスで利用しているのであれば、XRP Ledgerの利用状況に関する情報を、機械読み取り可能な
|
||||||
|
|||||||
@@ -11,145 +11,155 @@ ul.nav.navbar-nav {
|
|||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
.clio-only-notice {
|
||||||
|
background-color: var(--admonition-info-bg-color);
|
||||||
|
margin-left: var(--spacing-sm);
|
||||||
|
padding: var(--spacing-xs);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root, :root.dark {
|
||||||
|
--navbar-height: 80px;
|
||||||
|
|
||||||
/* XRPL color palette; match to styles/_colors.scss
|
/* XRPL color palette; match to styles/_colors.scss
|
||||||
Some colors don't have a 10 equivalent so 9 is repeated.
|
Some colors don't have a 10 equivalent so 9 is repeated.
|
||||||
|
|
||||||
Note, at present these variables are mostly overridden by
|
These are in reverse order of the ones in styles/_colors.scss
|
||||||
styled-components variables which are in reverse order, so
|
so that they correspond to the same-named variables provided by
|
||||||
we can't actually use these variables as-is.
|
styled-components as part of Redocly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Redocly doesn't have vars for grays by default */
|
/* Redocly doesn't have vars for grays by default */
|
||||||
--color-gray-1: #F5F5F7;
|
--color-gray-1: #111112;
|
||||||
--color-gray-2: #E0E0E1;
|
--color-gray-2: #232325;
|
||||||
--color-gray-3: #C1C1C2;
|
--color-gray-3: #343437;
|
||||||
--color-gray-4: #A2A2A4;
|
--color-gray-4: #454549;
|
||||||
--color-gray-5: #838386;
|
--color-gray-5: #838386;
|
||||||
--color-gray-6: #454549;
|
--color-gray-6: #A2A2A4;
|
||||||
--color-gray-7: #343437;
|
--color-gray-7: #C1C1C2;
|
||||||
--color-gray-8: #232325;
|
--color-gray-8: #E0E0E1;
|
||||||
--color-gray-9: #111112;
|
--color-gray-9: #F5F5F7;
|
||||||
--color-gray-10: var(--color-gray-9);
|
--color-gray-10: var(--color-gray-9);
|
||||||
|
|
||||||
/* color-red = XRPL $magenta */
|
/* color-red = XRPL $magenta */
|
||||||
--color-red-1: #FFE5F2;
|
--color-red-1: #4C0026;
|
||||||
--color-red-2: #FFB2D8;
|
--color-red-2: #4C0026;
|
||||||
--color-red-3: #FF80BF;
|
--color-red-3: #80003F;
|
||||||
--color-red-4: #FF4BA4;
|
--color-red-4: #B20058;
|
||||||
--color-red-5: #FF198B;
|
--color-red-5: #E50071;
|
||||||
--color-red-6: #E50071;
|
--color-red-6: #FF198B;
|
||||||
--color-red-7: #B20058;
|
--color-red-7: #FF4BA4;
|
||||||
--color-red-8: #80003F;
|
--color-red-8: #FF80BF;
|
||||||
--color-red-9: #4C0026;
|
--color-red-9: #FFB2D8;
|
||||||
--color-red-10: #4C0026;
|
--color-red-10: #FFE5F2;
|
||||||
|
|
||||||
/* color-green = XRPL $green */
|
/* color-green = XRPL $green */
|
||||||
--color-green-1: #D6FAE7;
|
--color-green-1: #0A2E1B;
|
||||||
--color-green-2: #ADF5CE;
|
--color-green-2: #145C35;
|
||||||
--color-green-3: #84F0B6;
|
--color-green-3: #1E8A50;
|
||||||
--color-green-4: #5BEB9D;
|
--color-green-4: #28B86A;
|
||||||
--color-green-5: #32E685;
|
--color-green-5: #2DCF78;
|
||||||
--color-green-6: #2DCF78;
|
--color-green-6: #32E685;
|
||||||
--color-green-7: #28B86A;
|
--color-green-7: #5BEB9D;
|
||||||
--color-green-8: #1E8A50;
|
--color-green-8: #84F0B6;
|
||||||
--color-green-9: #145C35;
|
--color-green-9: #ADF5CE;
|
||||||
--color-green-10: #0A2E1B;
|
--color-green-10: #D6FAE7;
|
||||||
|
|
||||||
/* color-gold = XRPL $yellow */
|
/* color-gold = XRPL $yellow */
|
||||||
--color-gold-1: #FEFFE5;
|
--color-gold-1: #4B4C00;
|
||||||
--color-gold-2: #FDFFB2;
|
--color-gold-2: #4B4C00;
|
||||||
--color-gold-3: #FCFF80;
|
--color-gold-3: #7D8000;
|
||||||
--color-gold-4: #FBFF4C;
|
--color-gold-4: #AEB200;
|
||||||
--color-gold-5: #FAFF19;
|
--color-gold-5: #E0E500;
|
||||||
--color-gold-6: #E0E500;
|
--color-gold-6: #FAFF19;
|
||||||
--color-gold-7: #AEB200;
|
--color-gold-7: #FBFF4C;
|
||||||
--color-gold-8: #7D8000;
|
--color-gold-8: #FCFF80;
|
||||||
--color-gold-9: #4B4C00;
|
--color-gold-9: #FDFFB2;
|
||||||
--color-gold-10: #4B4C00;
|
--color-gold-10: #FEFFE5;
|
||||||
|
|
||||||
/* color-blue = XRPL $blue */
|
/* color-blue = XRPL $blue */
|
||||||
--color-blue-1: #E5F5FF;
|
--color-blue-1: #001133;
|
||||||
--color-blue-2: #B2E0FF;
|
--color-blue-2: #002E4C;
|
||||||
--color-blue-3: #80CCFF;
|
--color-blue-3: #004D80;
|
||||||
--color-blue-4: #4BB7FF;
|
--color-blue-4: #006BB2;
|
||||||
--color-blue-5: #19A3FF;
|
--color-blue-5: #008AE5;
|
||||||
--color-blue-6: #008AE5;
|
--color-blue-6: #19A3FF;
|
||||||
--color-blue-7: #006BB2;
|
--color-blue-7: #4BB7FF;
|
||||||
--color-blue-8: #004D80;
|
--color-blue-8: #80CCFF;
|
||||||
--color-blue-9: #002E4C;
|
--color-blue-9: #B2E0FF;
|
||||||
--color-blue-10: #001133;
|
--color-blue-10: #E5F5FF;
|
||||||
|
|
||||||
/* color purple = XRPL $blue-purple */
|
/* color purple = XRPL $blue-purple */
|
||||||
--color-purple-1: #F0E5FF;
|
--color-purple-1: #20004C;
|
||||||
--color-purple-2: #D2B2FF;
|
--color-purple-2: #20004C;
|
||||||
--color-purple-3: #B480FF;
|
--color-purple-3: #350080;
|
||||||
--color-purple-4: #9A52FF;
|
--color-purple-4: #4A00B2;
|
||||||
--color-purple-5: #7919FF;
|
--color-purple-5: #5F00E5;
|
||||||
--color-purple-6: #5F00E5;
|
--color-purple-6: #7919FF;
|
||||||
--color-purple-7: #4A00B2;
|
--color-purple-7: #9A52FF;
|
||||||
--color-purple-8: #350080;
|
--color-purple-8: #B480FF;
|
||||||
--color-purple-9: #20004C;
|
--color-purple-9: #D2B2FF;
|
||||||
--color-purple-10: #20004C;
|
--color-purple-10: #F0E5FF;
|
||||||
|
|
||||||
/* color-magenta = XRPL $red-purple */
|
/* color-magenta = XRPL $red-purple */
|
||||||
--color-magenta-1: #FBE5FF;
|
--color-magenta-1: #40004C;
|
||||||
--color-magenta-2: #F2B2FF;
|
--color-magenta-2: #40004C;
|
||||||
--color-magenta-3: #EA80FF;
|
--color-magenta-3: #6B0080;
|
||||||
--color-magenta-4: #E24CFF;
|
--color-magenta-4: #9500B2;
|
||||||
--color-magenta-5: #D919FF;
|
--color-magenta-5: #C000E5;
|
||||||
--color-magenta-6: #C000E5;
|
--color-magenta-6: #D919FF;
|
||||||
--color-magenta-7: #9500B2;
|
--color-magenta-7: #E24CFF;
|
||||||
--color-magenta-8: #6B0080;
|
--color-magenta-8: #EA80FF;
|
||||||
--color-magenta-9: #40004C;
|
--color-magenta-9: #F2B2FF;
|
||||||
--color-magenta-10: #40004C;
|
--color-magenta-10: #FBE5FF;
|
||||||
|
|
||||||
/* XRPL doesn't have a color-cyan equivalent
|
/* XRPL doesn't have a color-cyan equivalent*
|
||||||
--color-cyan-1: #e6fffb;
|
--color-cyan-1: #002329;*
|
||||||
--color-cyan-2: #b5f5ec;
|
--color-cyan-2: #00474f;*
|
||||||
--color-cyan-3: #87e8de;
|
--color-cyan-3: #006d75;*
|
||||||
--color-cyan-4: #5cdbd3;
|
--color-cyan-4: #08979c;*
|
||||||
--color-cyan-5: #36cfc9;
|
--color-cyan-5: #13c2c2;*
|
||||||
--color-cyan-6: #13c2c2;
|
--color-cyan-6: #36cfc9;*
|
||||||
--color-cyan-7: #08979c;
|
--color-cyan-7: #5cdbd3;*
|
||||||
--color-cyan-8: #006d75;
|
--color-cyan-8: #87e8de;*
|
||||||
--color-cyan-9: #00474f;
|
--color-cyan-9: #b5f5ec;*
|
||||||
--color-cyan-10: #002329; */
|
--color-cyan-10: #e6fffb; */
|
||||||
|
|
||||||
/* color-yellow = XRPL $yellow */
|
/* color-yellow = XRPL $yellow */
|
||||||
--color-yellow-1: #FEFFE5;
|
--color-yellow-1: #4B4C00;
|
||||||
--color-yellow-2: #FDFFB2;
|
--color-yellow-2: #4B4C00;
|
||||||
--color-yellow-3: #FCFF80;
|
--color-yellow-3: #7D8000;
|
||||||
--color-yellow-4: #FBFF4C;
|
--color-yellow-4: #AEB200;
|
||||||
--color-yellow-5: #FAFF19;
|
--color-yellow-5: #E0E500;
|
||||||
--color-yellow-6: #E0E500;
|
--color-yellow-6: #FAFF19;
|
||||||
--color-yellow-7: #AEB200;
|
--color-yellow-7: #FBFF4C;
|
||||||
--color-yellow-8: #7D8000;
|
--color-yellow-8: #FCFF80;
|
||||||
--color-yellow-9: #4B4C00;
|
--color-yellow-9: #FDFFB2;
|
||||||
--color-yellow-10: #4B4C00;
|
--color-yellow-10: #FEFFE5;
|
||||||
|
|
||||||
/* XRPL doesn't have a color-lime equivalent
|
/* XRPL doesn't have a color-lime equivalent*
|
||||||
--color-lime-1: #fcffe6;
|
--color-lime-1: #254000;*
|
||||||
--color-lime-2: #f4ffb8;
|
--color-lime-2: #3f6600;*
|
||||||
--color-lime-3: #eaff8f;
|
--color-lime-3: #5b8c00;*
|
||||||
--color-lime-4: #d3f261;
|
--color-lime-4: #7cb305;*
|
||||||
--color-lime-5: #bae637;
|
--color-lime-5: #a0d911;*
|
||||||
--color-lime-6: #a0d911;
|
--color-lime-6: #bae637;*
|
||||||
--color-lime-7: #7cb305;
|
--color-lime-7: #d3f261;*
|
||||||
--color-lime-8: #5b8c00;
|
--color-lime-8: #eaff8f;*
|
||||||
--color-lime-9: #3f6600;
|
--color-lime-9: #f4ffb8;*
|
||||||
--color-lime-10: #254000; */
|
--color-lime-10: #fcffe6; */
|
||||||
|
|
||||||
/* XRPL doesn't have a color-geekblue equivalent
|
/* XRPL doesn't have a color-geekblue equivalent*
|
||||||
--color-geekblue-1: #f0f5ff;
|
--color-geekblue-1: #030852;*
|
||||||
--color-geekblue-2: #d6e4ff;
|
--color-geekblue-2: #061178;*
|
||||||
--color-geekblue-3: #adc6ff;
|
--color-geekblue-3: #10239e;*
|
||||||
--color-geekblue-4: #85a5ff;
|
--color-geekblue-4: #1d39c4;*
|
||||||
--color-geekblue-5: #597ef7;
|
--color-geekblue-5: #2f54eb;*
|
||||||
--color-geekblue-6: #2f54eb;
|
--color-geekblue-6: #597ef7;*
|
||||||
--color-geekblue-7: #1d39c4;
|
--color-geekblue-7: #85a5ff;*
|
||||||
--color-geekblue-8: #10239e;
|
--color-geekblue-8: #adc6ff;*
|
||||||
--color-geekblue-9: #061178;
|
--color-geekblue-9: #d6e4ff;*
|
||||||
--color-geekblue-10: #030852; */
|
--color-geekblue-10: #f0f5ff; */
|
||||||
|
|
||||||
/* Dark mode colors by default */
|
/* Dark mode colors by default */
|
||||||
--color-primary-bg: var(--color-gray-10);
|
--color-primary-bg: var(--color-gray-10);
|
||||||
@@ -162,30 +172,30 @@ ul.nav.navbar-nav {
|
|||||||
--color-primary-text-hover: #201dad;
|
--color-primary-text-hover: #201dad;
|
||||||
--color-primary-text: #161087;
|
--color-primary-text: #161087;
|
||||||
--color-primary-text-active: #0d086e;*/
|
--color-primary-text-active: #0d086e;*/
|
||||||
|
|
||||||
--link-color-primary: #fff;
|
--link-color-primary: white;
|
||||||
--link-decoration: underline;
|
--link-decoration: underline;
|
||||||
--link-font-weight: var(--font-weight-regular);
|
--link-font-weight: var(--font-weight-regular);
|
||||||
|
|
||||||
--link-color-primary-hover: #9a52ff;
|
--link-color-primary-hover: var(--color-purple-7)
|
||||||
--link-decoration-hover: underline;
|
--link-decoration-hover: underline;
|
||||||
|
|
||||||
--link-color-visited: #fff;
|
--link-color-visited: white;
|
||||||
--link-visited-decoration: underline;
|
--link-visited-decoration: underline;
|
||||||
|
|
||||||
--bg-color: var(--color-gray-10);
|
--bg-color: var(--color-gray-10);
|
||||||
--bg-color-raised: var(--color-gray-8);
|
--bg-color-raised: var(--color-gray-2);
|
||||||
--background-color: var(--bg-color);
|
--background-color: var(--bg-color);
|
||||||
|
|
||||||
--font-family-base: 'Work Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
--font-family-base: 'Work Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||||
--heading-font-family: var(--font-family-base);
|
--heading-font-family: var(--font-family-base);
|
||||||
|
|
||||||
--inline-code-font-family: "Space Mono", monospace;
|
--inline-code-font-family: "Space Mono", monospace;
|
||||||
--inline-code-text-color: #5beb9d; /* $green-400 */
|
--inline-code-text-color: var(--color-green-7);
|
||||||
--inline-code-bg-color: #0a2e1b; /* $green-1000 */
|
--inline-code-bg-color: var(--color-green-1);
|
||||||
--inline-code-border-radius: 0;
|
--inline-code-border-radius: 0;
|
||||||
|
|
||||||
--heading-anchor-color: #9a52ff;
|
--heading-anchor-color: var(--color-purple-7);
|
||||||
--h1-font-size: 3rem;
|
--h1-font-size: 3rem;
|
||||||
--h2-font-size: 2.5rem;
|
--h2-font-size: 2.5rem;
|
||||||
--h3-font-size: 2.125rem;
|
--h3-font-size: 2.125rem;
|
||||||
@@ -195,14 +205,18 @@ ul.nav.navbar-nav {
|
|||||||
--h5-font-size: 1.25rem;
|
--h5-font-size: 1.25rem;
|
||||||
--h5-line-height: 1.5rem;
|
--h5-line-height: 1.5rem;
|
||||||
|
|
||||||
|
--menu-container-padding-top: 0;
|
||||||
|
--md-content-padding: 4px 0;
|
||||||
|
--toc-offset-top: 2px;
|
||||||
|
|
||||||
--sidebar-border-color: transparent;
|
--sidebar-border-color: transparent;
|
||||||
--sidebar-bg-color: transparent;
|
--sidebar-bg-color: transparent;
|
||||||
--sidebar-margin-horizontal: 32px;
|
--sidebar-margin-horizontal: 32px;
|
||||||
|
|
||||||
--border-radius-md: 4px;
|
--border-radius-md: 4px;
|
||||||
|
|
||||||
--code-block-bg-color: #232325;
|
--code-block-bg-color: var(--color-gray-2);
|
||||||
--code-block-controls-bg-color: #232325;
|
--code-block-controls-bg-color: var(--color-gray-2);
|
||||||
--code-block-controls-border: none;
|
--code-block-controls-border: none;
|
||||||
--code-block-padding: 0 2rem 1.5rem 2rem;
|
--code-block-padding: 0 2rem 1.5rem 2rem;
|
||||||
|
|
||||||
@@ -216,62 +230,111 @@ ul.nav.navbar-nav {
|
|||||||
--footer-border-color: transparent;
|
--footer-border-color: transparent;
|
||||||
--footer-title-font-weight: 600;
|
--footer-title-font-weight: 600;
|
||||||
--footer-title-font-size: 1rem;
|
--footer-title-font-size: 1rem;
|
||||||
--footer-title-text-color: #A2A2A4;
|
--footer-title-text-color: var(--color-gray-6);
|
||||||
|
|
||||||
--menu-item-padding-horizontal: 0px;
|
--menu-item-padding-horizontal: 0px;
|
||||||
|
|
||||||
--md-list-left-padding: 40px;
|
--md-list-left-padding: 40px;
|
||||||
--md-table-header-bg-color: #32343E;
|
--md-list-margin: 0 0 20px 0;
|
||||||
--md-table-border-color: #32343E;
|
--md-table-header-bg-color: var(--color-gray-3);
|
||||||
|
--md-table-border-color: var(--color-gray-3);
|
||||||
|
|
||||||
--md-tabs-content-padding: 0;
|
--md-tabs-content-padding: 0;
|
||||||
|
--md-tabs-tab-wrapper-padding: 0;
|
||||||
|
|
||||||
|
--text-color-helper: var(--color-gray-6);
|
||||||
|
--color-text-primary: white;
|
||||||
|
--button-color-hover: white;
|
||||||
|
|
||||||
|
--text-color-secondary: var(--color-gray-9); /* inherited for adominition text color */
|
||||||
|
--admonition-success-bg-color: var(--color-green-2);
|
||||||
|
--admonition-info-bg-color: var(--color-blue-4);
|
||||||
|
/* none of the yellow shades in the XRPL palette work well with "warning"
|
||||||
|
admonitions, so leave it the default */
|
||||||
|
--admonition-danger-bg-color: var(--color-red-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.light {
|
:root.light {
|
||||||
--link-color-primary-hover: #4A00B2;
|
--link-color-primary-hover: var(--color-purple-4);
|
||||||
--link-color-visited: #000;
|
--link-color-visited: black;
|
||||||
--text-color-secondary: #000;
|
--text-color-secondary: black;
|
||||||
--code-block-bg-color: #E0E0E1;
|
--code-block-bg-color: var(--color-gray-8);
|
||||||
--code-block-controls-bg-color: #E0E0E1;
|
--code-block-controls-bg-color: var(--color-gray-8);
|
||||||
--code-block-controls-border: none;
|
--code-block-controls-border: none;
|
||||||
--md-tabs-active-tab-bg-color: #C1C1C2;
|
--md-tabs-active-tab-bg-color: var(--color-gray-7);
|
||||||
|
|
||||||
--code-block-tokens-function-color: #B23C00;
|
|
||||||
--code-block-tokens-operator-color: #000;
|
|
||||||
--code-block-tokens-comment-color: #343437;
|
|
||||||
--code-block-tokens-string-color: #145C35;
|
|
||||||
--inline-code-bg-color: #E0E0E1;
|
|
||||||
|
|
||||||
--search-trigger-bg-color: #E0E0E1;
|
--inline-code-bg-color: var(--color-gray-8);
|
||||||
--search-trigger-color: #838386;
|
|
||||||
|
|
||||||
--language-picker-border-color: #C1C1C2;
|
--search-trigger-bg-color: var(--color-gray-8);
|
||||||
--language-picker-background-color: #E0E0E1;
|
--search-trigger-color: var(--color-gray-5);
|
||||||
--select-list-bg-color: #E0E0E1;
|
--modal-bg-color: var(--color-gray-9);
|
||||||
|
|
||||||
--footer-title-text-color: #000;
|
--language-picker-border-color: var(--color-gray-7);
|
||||||
--bg-color: var(--color-gray-1);
|
--language-picker-background-color: var(--color-gray-8);
|
||||||
--bg-color-raised: var(--color-gray-2);
|
--select-list-bg-color: var(--color-gray-8);
|
||||||
--button-content-color-link: #000;
|
|
||||||
|
|
||||||
--md-table-header-bg-color: var(--color-gray-2);
|
--footer-title-text-color: black;
|
||||||
--md-table-border-color: var(--color-gray-2);
|
--bg-color: var(--color-gray-9);
|
||||||
|
--bg-color-raised: var(--color-gray-8);
|
||||||
|
--button-content-color-link: black;
|
||||||
|
|
||||||
|
--md-table-header-bg-color: var(--color-gray-8);
|
||||||
|
--md-table-border-color: var(--color-gray-8);
|
||||||
|
|
||||||
|
--bg-color: var(--color-gray-8);
|
||||||
|
--code-panel-bg-color: var(--color-blue-7);
|
||||||
|
--layer-color-hover: var(--color-gray-9);
|
||||||
|
|
||||||
|
--code-block-text-color: var(--color-gray-1);
|
||||||
|
--code-block-tokens-comment-color: var(--color-gray-4);
|
||||||
|
--code-block-tokens-constant-color: var(--color-gray-1);
|
||||||
|
--code-block-tokens-function-color: var(--color-red-4);
|
||||||
|
--code-block-tokens-keyword-color: var(--color-magenta-5);
|
||||||
|
--code-block-tokens-operator-color: black;
|
||||||
|
--code-block-tokens-string-color: var(--color-green-3);
|
||||||
|
|
||||||
|
--bg-raised-gradient: "";
|
||||||
|
--text-color-helper: var(--color-gray-4);
|
||||||
|
--button-color-hover: black;
|
||||||
|
|
||||||
|
--admonition-success-bg-color: var(--color-green-9);
|
||||||
|
--admonition-info-bg-color: var(--color-blue-9);
|
||||||
|
--admonition-warning-bg-color: var(--color-yellow-9);
|
||||||
|
--admonition-danger-bg-color: var(--color-red-9);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.dark {
|
:root.dark {
|
||||||
--link-color-primary: #fff;
|
--link-color-primary: white;
|
||||||
--link-color-visited: #fff;
|
--link-color-visited: white;
|
||||||
--link-color-primary-hover: #9a52ff;
|
--link-color-primary-hover: var(--color-purple-7);
|
||||||
|
|
||||||
--search-highlight-text-color: #4BB7FF; /* color-blue-4 */
|
--navbar-bg-color: var(--color-gray-2); /* controls search box bg */
|
||||||
|
--modal-bg-color: var(--color-gray-2); /* controls search modal bg */
|
||||||
--code-block-tokens-comment-color: #C1C1C2; /* color-gray-3 */
|
--search-highlight-text-color: var(--color-blue-7);
|
||||||
|
|
||||||
|
--code-block-text-color: var(--color-gray-9);
|
||||||
|
--code-block-tokens-comment-color: var(--color-gray-7);
|
||||||
|
--code-block-tokens-constant-color: var(--color-gray-9);
|
||||||
|
--code-block-tokens-keyword-color: var(--color-magenta-8);
|
||||||
|
--code-block-tokens-string-color: var(--color-blue-8);
|
||||||
|
|
||||||
|
--code-panel-bg-color: var(--color-blue-3);
|
||||||
|
--layer-color-hover: var(--color-gray-3);
|
||||||
|
--bg-raised-gradient: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
:root .form-control-plaintext {
|
:root .form-control-plaintext {
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fix unnecessary horizontal scrolling of tables in Japanese */
|
||||||
|
[lang="ja"] table.md {
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
[lang="ja"] table.md th {
|
||||||
|
min-width: 7em;
|
||||||
|
}
|
||||||
|
|
||||||
[data-component-name="Search/SearchTrigger"] > div {
|
[data-component-name="Search/SearchTrigger"] > div {
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
4
_code-samples/batch/README.md
Normal file
4
_code-samples/batch/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Batch
|
||||||
|
|
||||||
|
Code samples showing how to create and submit a [Batch transaction](../../docs/concepts/transactions/batch-transactions.md).
|
||||||
|
Both for simple and multi account batch transactions.
|
||||||
24
_code-samples/batch/go/go.mod
Normal file
24
_code-samples/batch/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/batch/go/go.sum
Normal file
58
_code-samples/batch/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
198
_code-samples/batch/go/rpc/main.go
Normal file
198
_code-samples/batch/go/rpc/main.go
Normal file
@@ -0,0 +1,198 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
CreatePaymentTx = func(sender, receiver *wallet.Wallet, amount txnTypes.CurrencyAmount) *transaction.Payment {
|
||||||
|
return &transaction.Payment{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: sender.GetAddress(),
|
||||||
|
TransactionType: transaction.PaymentTx,
|
||||||
|
Flags: txnTypes.TfInnerBatchTxn,
|
||||||
|
},
|
||||||
|
Amount: amount,
|
||||||
|
Destination: receiver.GetAddress(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Configure the client
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.devnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Create and fund wallets
|
||||||
|
userWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user2Wallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
receiverWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
if err := client.FundWallet(&userWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&user2Wallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Wallets funded")
|
||||||
|
|
||||||
|
// Check initial balances
|
||||||
|
userBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
userBalance = "0"
|
||||||
|
}
|
||||||
|
user2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
user2Balance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
receiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
receiverBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("User initial balance: %s XRP\n", userBalance)
|
||||||
|
fmt.Printf("User2 initial balance: %s XRP\n", user2Balance)
|
||||||
|
fmt.Printf("Receiver initial balance: %s XRP\n", receiverBalance)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Printf("Batch transaction test\n")
|
||||||
|
|
||||||
|
// Create test batch transaction
|
||||||
|
batchTx := &transaction.Batch{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: txnTypes.Address(userWallet.ClassicAddress),
|
||||||
|
TransactionType: transaction.BatchTx,
|
||||||
|
},
|
||||||
|
RawTransactions: []txnTypes.RawTransaction{
|
||||||
|
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
batchTx.SetAllOrNothingFlag()
|
||||||
|
|
||||||
|
flattenedBatchTx := batchTx.Flatten()
|
||||||
|
fmt.Println("Autofilling flattened batch transaction...")
|
||||||
|
if err := client.Autofill(&flattenedBatchTx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Signing batch transaction...")
|
||||||
|
response, err := client.SubmitTxAndWait(flattenedBatchTx, &types.SubmitOptions{
|
||||||
|
Autofill: false,
|
||||||
|
Wallet: &userWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Batch transaction submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Printf("Validated: %t\n", response.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check final balances
|
||||||
|
finalUserBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalUserBalance = "0"
|
||||||
|
}
|
||||||
|
finalReceiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalReceiverBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("User final balance: %s XRP\n", finalUserBalance)
|
||||||
|
|
||||||
|
fmt.Printf("Receiver final balance: %s XRP\n", finalReceiverBalance)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("Multisig Batch transaction test\n")
|
||||||
|
|
||||||
|
// Create test batch transaction
|
||||||
|
multiBatchTx := &transaction.Batch{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: txnTypes.Address(userWallet.ClassicAddress),
|
||||||
|
TransactionType: transaction.BatchTx,
|
||||||
|
},
|
||||||
|
RawTransactions: []txnTypes.RawTransaction{
|
||||||
|
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
{RawTransaction: CreatePaymentTx(&user2Wallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
},
|
||||||
|
BatchSigners: []txnTypes.BatchSigner{
|
||||||
|
{
|
||||||
|
BatchSigner: txnTypes.BatchSignerData{
|
||||||
|
Account: txnTypes.Address(user2Wallet.ClassicAddress),
|
||||||
|
SigningPubKey: user2Wallet.PublicKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
multiBatchTx.SetAllOrNothingFlag()
|
||||||
|
|
||||||
|
flattenedMultiBatchTx := multiBatchTx.Flatten()
|
||||||
|
fmt.Println("Autofilling flattened multi batch transaction...")
|
||||||
|
if err := client.AutofillMultisigned(&flattenedMultiBatchTx, 1); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Signing multi batch transaction...")
|
||||||
|
if err := wallet.SignMultiBatch(user2Wallet, &flattenedMultiBatchTx, nil); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxAndWait(flattenedMultiBatchTx, &types.SubmitOptions{
|
||||||
|
Autofill: false,
|
||||||
|
Wallet: &userWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Multisig Batch transaction submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Printf("Validated: %t\n", response.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check final balances
|
||||||
|
finalUser2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalUser2Balance = "0"
|
||||||
|
}
|
||||||
|
finalUserBalance, err = client.GetXrpBalance(userWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalUserBalance = "0"
|
||||||
|
}
|
||||||
|
finalReceiverBalance, err = client.GetXrpBalance(receiverWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalReceiverBalance = "0"
|
||||||
|
}
|
||||||
|
fmt.Printf("User final balance: %s XRP\n", finalUserBalance)
|
||||||
|
fmt.Printf("User2 final balance: %s XRP\n", finalUser2Balance)
|
||||||
|
fmt.Printf("Receiver final balance: %s XRP\n", finalReceiverBalance)
|
||||||
|
}
|
||||||
199
_code-samples/batch/go/ws/main.go
Normal file
199
_code-samples/batch/go/ws/main.go
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
CreatePaymentTx = func(sender, receiver *wallet.Wallet, amount txnTypes.CurrencyAmount) *transaction.Payment {
|
||||||
|
return &transaction.Payment{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: sender.GetAddress(),
|
||||||
|
TransactionType: transaction.PaymentTx,
|
||||||
|
Flags: txnTypes.TfInnerBatchTxn,
|
||||||
|
},
|
||||||
|
Amount: amount,
|
||||||
|
Destination: receiver.GetAddress(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Connect to testnet
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and fund wallets
|
||||||
|
userWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
user2Wallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
receiverWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
if err := client.FundWallet(&userWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&user2Wallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Wallets funded")
|
||||||
|
|
||||||
|
// Check initial balances
|
||||||
|
userBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
userBalance = "0"
|
||||||
|
}
|
||||||
|
user2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
user2Balance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
receiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
receiverBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("User initial balance: %s XRP\n", userBalance)
|
||||||
|
fmt.Printf("User2 initial balance: %s XRP\n", user2Balance)
|
||||||
|
fmt.Printf("Receiver initial balance: %s XRP\n", receiverBalance)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Printf("Batch transaction test\n")
|
||||||
|
|
||||||
|
// Create test batch transaction
|
||||||
|
batchTx := &transaction.Batch{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: txnTypes.Address(userWallet.ClassicAddress),
|
||||||
|
TransactionType: transaction.BatchTx,
|
||||||
|
},
|
||||||
|
RawTransactions: []txnTypes.RawTransaction{
|
||||||
|
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
batchTx.SetAllOrNothingFlag()
|
||||||
|
|
||||||
|
flattenedBatchTx := batchTx.Flatten()
|
||||||
|
fmt.Println("Autofilling flattened batch transaction...")
|
||||||
|
if err := client.Autofill(&flattenedBatchTx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Signing batch transaction...")
|
||||||
|
response, err := client.SubmitTxAndWait(flattenedBatchTx, &types.SubmitOptions{
|
||||||
|
Autofill: false,
|
||||||
|
Wallet: &userWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Batch transaction submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Printf("Validated: %t\n", response.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check final balances
|
||||||
|
finalUserBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalUserBalance = "0"
|
||||||
|
}
|
||||||
|
finalReceiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalReceiverBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("User final balance: %s XRP\n", finalUserBalance)
|
||||||
|
|
||||||
|
fmt.Printf("Receiver final balance: %s XRP\n", finalReceiverBalance)
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Printf("Multisig Batch transaction test\n")
|
||||||
|
|
||||||
|
// Create test batch transaction
|
||||||
|
multiBatchTx := &transaction.Batch{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: txnTypes.Address(userWallet.ClassicAddress),
|
||||||
|
TransactionType: transaction.BatchTx,
|
||||||
|
},
|
||||||
|
RawTransactions: []txnTypes.RawTransaction{
|
||||||
|
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
{RawTransaction: CreatePaymentTx(&user2Wallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
|
||||||
|
},
|
||||||
|
BatchSigners: []txnTypes.BatchSigner{
|
||||||
|
{
|
||||||
|
BatchSigner: txnTypes.BatchSignerData{
|
||||||
|
Account: txnTypes.Address(user2Wallet.ClassicAddress),
|
||||||
|
SigningPubKey: user2Wallet.PublicKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
multiBatchTx.SetAllOrNothingFlag()
|
||||||
|
|
||||||
|
flattenedMultiBatchTx := multiBatchTx.Flatten()
|
||||||
|
fmt.Println("Autofilling flattened multi batch transaction...")
|
||||||
|
if err := client.AutofillMultisigned(&flattenedMultiBatchTx, 1); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Signing multi batch transaction...")
|
||||||
|
if err := wallet.SignMultiBatch(user2Wallet, &flattenedMultiBatchTx, nil); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxAndWait(flattenedMultiBatchTx, &types.SubmitOptions{
|
||||||
|
Autofill: false,
|
||||||
|
Wallet: &userWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Multisig Batch transaction submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Printf("Validated: %t\n", response.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check final balances
|
||||||
|
finalUser2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalUser2Balance = "0"
|
||||||
|
}
|
||||||
|
finalUserBalance, err = client.GetXrpBalance(userWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalUserBalance = "0"
|
||||||
|
}
|
||||||
|
finalReceiverBalance, err = client.GetXrpBalance(receiverWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalReceiverBalance = "0"
|
||||||
|
}
|
||||||
|
fmt.Printf("User final balance: %s XRP\n", finalUserBalance)
|
||||||
|
fmt.Printf("User2 final balance: %s XRP\n", finalUser2Balance)
|
||||||
|
fmt.Printf("Receiver final balance: %s XRP\n", finalReceiverBalance)
|
||||||
|
}
|
||||||
24
_code-samples/checks/go/go.mod
Normal file
24
_code-samples/checks/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/checks/go/go.sum
Normal file
58
_code-samples/checks/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
152
_code-samples/checks/go/rpc/main.go
Normal file
152
_code-samples/checks/go/rpc/main.go
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
w, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
receiverWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Setting up wallets...")
|
||||||
|
if err := client.FundWallet(&w); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Sender wallet funded!")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&receiverWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Receiver wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println("Sender wallet:", w.ClassicAddress)
|
||||||
|
fmt.Println("Receiver wallet:", receiverWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Creating check...")
|
||||||
|
cc := &transaction.CheckCreate{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: w.GetAddress(),
|
||||||
|
},
|
||||||
|
Destination: receiverWallet.GetAddress(),
|
||||||
|
SendMax: types.XRPCurrencyAmount(1000000),
|
||||||
|
InvoiceID: "46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291",
|
||||||
|
}
|
||||||
|
|
||||||
|
flatCc := cc.Flatten()
|
||||||
|
|
||||||
|
if err := client.Autofill(&flatCc); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, _, err := w.Sign(flatCc)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := client.SubmitTxBlobAndWait(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !res.Validated {
|
||||||
|
fmt.Println("Check creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Check created!")
|
||||||
|
fmt.Printf("Hash: %s\n", res.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
meta, ok := res.Meta.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not of type TxObjMeta")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkID string
|
||||||
|
|
||||||
|
affectedNodes := meta["AffectedNodes"].([]interface{})
|
||||||
|
|
||||||
|
for _, node := range affectedNodes {
|
||||||
|
affectedNode, ok := node.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Node is not of type map[string]interface{}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
createdNode, ok := affectedNode["CreatedNode"].(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if createdNode["LedgerEntryType"] == string(ledger.CheckEntry) {
|
||||||
|
|
||||||
|
checkID = createdNode["LedgerIndex"].(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkID == "" {
|
||||||
|
fmt.Println("Check not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cashing out check...")
|
||||||
|
checkCash := &transaction.CheckCash{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: receiverWallet.GetAddress(),
|
||||||
|
},
|
||||||
|
CheckID: types.Hash256(checkID),
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000),
|
||||||
|
}
|
||||||
|
|
||||||
|
flatCheckCash := checkCash.Flatten()
|
||||||
|
|
||||||
|
if err := client.Autofill(&flatCheckCash); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, _, err = receiverWallet.Sign(flatCheckCash)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = client.SubmitTxBlobAndWait(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Check cashed out!")
|
||||||
|
fmt.Printf("Hash: %s\n", res.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
163
_code-samples/checks/go/ws/main.go
Normal file
163
_code-samples/checks/go/ws/main.go
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Connecting to testnet...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.altnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to testnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connected to testnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
w, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
receiverWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Setting up wallets...")
|
||||||
|
if err := client.FundWallet(&w); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Sender wallet funded!")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&receiverWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Receiver wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println("Sender wallet:", w.ClassicAddress)
|
||||||
|
fmt.Println("Receiver wallet:", receiverWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Creating check...")
|
||||||
|
cc := &transaction.CheckCreate{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: w.GetAddress(),
|
||||||
|
},
|
||||||
|
Destination: receiverWallet.GetAddress(),
|
||||||
|
SendMax: types.XRPCurrencyAmount(1000000),
|
||||||
|
InvoiceID: "46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291",
|
||||||
|
}
|
||||||
|
|
||||||
|
flatCc := cc.Flatten()
|
||||||
|
|
||||||
|
if err := client.Autofill(&flatCc); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
blob, _, err := w.Sign(flatCc)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := client.SubmitTxBlobAndWait(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !res.Validated {
|
||||||
|
fmt.Println("Check creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Check created!")
|
||||||
|
fmt.Printf("Hash: %s\n", res.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
meta, ok := res.Meta.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not of type TxObjMeta")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkID string
|
||||||
|
|
||||||
|
affectedNodes := meta["AffectedNodes"].([]interface{})
|
||||||
|
|
||||||
|
for _, node := range affectedNodes {
|
||||||
|
affectedNode, ok := node.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Node is not of type map[string]interface{}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
createdNode, ok := affectedNode["CreatedNode"].(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if createdNode["LedgerEntryType"] == string(ledger.CheckEntry) {
|
||||||
|
|
||||||
|
checkID = createdNode["LedgerIndex"].(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if checkID == "" {
|
||||||
|
fmt.Println("Check not found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cashing out check...")
|
||||||
|
checkCash := &transaction.CheckCash{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: receiverWallet.GetAddress(),
|
||||||
|
},
|
||||||
|
CheckID: types.Hash256(checkID),
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000),
|
||||||
|
}
|
||||||
|
|
||||||
|
flatCheckCash := checkCash.Flatten()
|
||||||
|
|
||||||
|
if err := client.Autofill(&flatCheckCash); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, _, err = receiverWallet.Sign(flatCheckCash)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = client.SubmitTxBlobAndWait(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Check cashed out!")
|
||||||
|
fmt.Printf("Hash: %s\n", res.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
3
_code-samples/clawback/README.md
Normal file
3
_code-samples/clawback/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Clawback
|
||||||
|
|
||||||
|
Create, configure, and execute a Clawback transaction to reclaim issued tokens from a trust line on the XRPL.
|
||||||
24
_code-samples/clawback/go/go.mod
Normal file
24
_code-samples/clawback/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/clawback/go/go.sum
Normal file
58
_code-samples/clawback/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
235
_code-samples/clawback/go/rpc/main.go
Normal file
235
_code-samples/clawback/go/rpc/main.go
Normal file
@@ -0,0 +1,235 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currencyCode = "FOO"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//
|
||||||
|
// Configure client
|
||||||
|
//
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure wallets
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up wallets...")
|
||||||
|
coldWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&coldWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Cold wallet funded!")
|
||||||
|
|
||||||
|
hotWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&hotWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Hot wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println("Cold wallet:", coldWallet.ClassicAddress)
|
||||||
|
fmt.Println("Hot wallet:", hotWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure cold address settings
|
||||||
|
//
|
||||||
|
fmt.Println("Configuring cold address settings...")
|
||||||
|
coldWalletAccountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
TickSize: types.TickSize(5),
|
||||||
|
TransferRate: types.TransferRate(0),
|
||||||
|
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetAsfAllowTrustLineClawback()
|
||||||
|
coldWalletAccountSet.SetDisallowXRP()
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetRequireDestTag()
|
||||||
|
|
||||||
|
flattenedTx := coldWalletAccountSet.Flatten()
|
||||||
|
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold wallet unfreezing failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold address settings configured!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create trust line from hot to cold address
|
||||||
|
//
|
||||||
|
fmt.Println("Creating trust line from hot to cold address...")
|
||||||
|
hotColdTrustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100000000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotColdTrustSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Trust line from hot to cold address creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Trust line from hot to cold address created!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send tokens from cold wallet to hot wallet
|
||||||
|
//
|
||||||
|
fmt.Println("Sending tokens from cold wallet to hot wallet...")
|
||||||
|
coldToHotPayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "3800",
|
||||||
|
},
|
||||||
|
Destination: types.Address(hotWallet.ClassicAddress),
|
||||||
|
DestinationTag: types.DestinationTag(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldToHotPayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Claw back tokens from customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Clawing back tokens from hot wallet...")
|
||||||
|
|
||||||
|
coldWalletClawback := &transactions.Clawback{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(hotWallet.ClassicAddress),
|
||||||
|
Value: "50",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldWalletClawback.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not clawed back from customer one!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens clawed back from customer one!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
241
_code-samples/clawback/go/ws/main.go
Normal file
241
_code-samples/clawback/go/ws/main.go
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currencyCode = "FOO"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//
|
||||||
|
// Configure client
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up client...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.altnet.rippletest.net").
|
||||||
|
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
fmt.Println("Client configured!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Connecting to server...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connection: ", client.IsConnected())
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure wallets
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up wallets...")
|
||||||
|
coldWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&coldWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Cold wallet funded!")
|
||||||
|
|
||||||
|
hotWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&hotWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Hot wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println("Cold wallet:", coldWallet.ClassicAddress)
|
||||||
|
fmt.Println("Hot wallet:", hotWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure cold address settings
|
||||||
|
//
|
||||||
|
fmt.Println("Configuring cold address settings...")
|
||||||
|
coldWalletAccountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
TickSize: types.TickSize(5),
|
||||||
|
TransferRate: types.TransferRate(0),
|
||||||
|
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetAsfAllowTrustLineClawback()
|
||||||
|
coldWalletAccountSet.SetDisallowXRP()
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetRequireDestTag()
|
||||||
|
|
||||||
|
flattenedTx := coldWalletAccountSet.Flatten()
|
||||||
|
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold wallet unfreezing failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold address settings configured!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create trust line from hot to cold address
|
||||||
|
//
|
||||||
|
fmt.Println("Creating trust line from hot to cold address...")
|
||||||
|
hotColdTrustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100000000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotColdTrustSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Trust line from hot to cold address creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Trust line from hot to cold address created!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send tokens from cold wallet to hot wallet
|
||||||
|
//
|
||||||
|
fmt.Println("Sending tokens from cold wallet to hot wallet...")
|
||||||
|
coldToHotPayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "3800",
|
||||||
|
},
|
||||||
|
Destination: types.Address(hotWallet.ClassicAddress),
|
||||||
|
DestinationTag: types.DestinationTag(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldToHotPayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Claw back tokens from customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Clawing back tokens from hot wallet...")
|
||||||
|
|
||||||
|
coldWalletClawback := &transactions.Clawback{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(hotWallet.ClassicAddress),
|
||||||
|
Value: "50",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldWalletClawback.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not clawed back from customer one!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens clawed back from customer one!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
3
_code-samples/credential/README.md
Normal file
3
_code-samples/credential/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Credential
|
||||||
|
|
||||||
|
Create, accept, and delete a credential on the XRPL using dedicated transactions between issuer and subject wallets.
|
||||||
24
_code-samples/credential/go/go.mod
Normal file
24
_code-samples/credential/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/credential/go/go.sum
Normal file
58
_code-samples/credential/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
104
_code-samples/credential/go/rpc/main.go
Normal file
104
_code-samples/credential/go/rpc/main.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/examples/clients"
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
rippleTime "github.com/Peersyst/xrpl-go/xrpl/time"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// As of February 2025, Credential is only available on Devnet.
|
||||||
|
client := clients.GetDevnetRpcClient()
|
||||||
|
|
||||||
|
// Configure wallets
|
||||||
|
|
||||||
|
// Issuer
|
||||||
|
fmt.Println("Setting up credential issuer wallet...")
|
||||||
|
issuer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&issuer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Issuer wallet funded: %s\n", issuer.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Subject (destination)
|
||||||
|
fmt.Println("Setting up Subject wallet...")
|
||||||
|
subjectWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&subjectWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Subject wallet funded: %s\n", subjectWallet.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialCreate transaction
|
||||||
|
fmt.Println("Creating CredentialCreate transaction...")
|
||||||
|
|
||||||
|
expiration, err := rippleTime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
|
||||||
|
credentialType := types.CredentialType("6D795F63726564656E7469616C")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txn := &transaction.CredentialCreate{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Subject: types.Address(subjectWallet.ClassicAddress),
|
||||||
|
Expiration: uint32(expiration),
|
||||||
|
URI: hex.EncodeToString([]byte("https://example.com")),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, txn, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialAccept transaction
|
||||||
|
fmt.Println("Creating CredentialAccept transaction...")
|
||||||
|
|
||||||
|
acceptTxn := &transaction.CredentialAccept{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: types.Address(subjectWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, acceptTxn, subjectWallet)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialDelete transaction
|
||||||
|
fmt.Println("Creating CredentialDelete transaction...")
|
||||||
|
|
||||||
|
deleteTxn := &transaction.CredentialDelete{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Subject: types.Address(subjectWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, deleteTxn, issuer)
|
||||||
|
}
|
||||||
116
_code-samples/credential/go/ws/main.go
Normal file
116
_code-samples/credential/go/ws/main.go
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/examples/clients"
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
rippleTime "github.com/Peersyst/xrpl-go/xrpl/time"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
fmt.Println("Setting up client...")
|
||||||
|
|
||||||
|
client := clients.GetDevnetWebsocketClient()
|
||||||
|
fmt.Println("Connecting to server...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Client configured!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Printf("Connection: %t", client.IsConnected())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Configure wallets
|
||||||
|
|
||||||
|
// Issuer
|
||||||
|
fmt.Println("Setting up credential issuer wallet...")
|
||||||
|
issuer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&issuer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Issuer wallet funded: %s\n", issuer.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Subject (destination)
|
||||||
|
fmt.Println("Setting up Subject wallet...")
|
||||||
|
subjectWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&subjectWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Subject wallet funded: %s\n", subjectWallet.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialCreate transaction
|
||||||
|
fmt.Println("Creating CredentialCreate transaction...")
|
||||||
|
|
||||||
|
expiration, err := rippleTime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
|
||||||
|
credentialType := types.CredentialType("6D795F63726564656E7469616C")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txn := &transaction.CredentialCreate{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Subject: types.Address(subjectWallet.ClassicAddress),
|
||||||
|
Expiration: uint32(expiration),
|
||||||
|
URI: hex.EncodeToString([]byte("https://example.com")),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, txn, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialAccept transaction
|
||||||
|
fmt.Println("Creating CredentialAccept transaction...")
|
||||||
|
|
||||||
|
acceptTxn := &transaction.CredentialAccept{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: types.Address(subjectWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, acceptTxn, subjectWallet)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialDelete transaction
|
||||||
|
fmt.Println("Creating CredentialDelete transaction...")
|
||||||
|
|
||||||
|
deleteTxn := &transaction.CredentialDelete{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Subject: types.Address(subjectWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, deleteTxn, issuer)
|
||||||
|
}
|
||||||
3
_code-samples/delegate-set/README.md
Normal file
3
_code-samples/delegate-set/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Delegate
|
||||||
|
|
||||||
|
Example delegating payment permission to an account and executing on behalf the delegator.
|
||||||
24
_code-samples/delegate-set/go/go.mod
Normal file
24
_code-samples/delegate-set/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/delegate-set/go/go.sum
Normal file
58
_code-samples/delegate-set/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
125
_code-samples/delegate-set/go/rpc/main.go
Normal file
125
_code-samples/delegate-set/go/rpc/main.go
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Configure the client
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.devnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Create and fund wallets
|
||||||
|
delegatorWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
delegateeWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
if err := client.FundWallet(&delegatorWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&delegateeWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Wallets funded")
|
||||||
|
|
||||||
|
// Check initial balances
|
||||||
|
delegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
delegatorBalance = "0"
|
||||||
|
}
|
||||||
|
delegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
delegateeBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Delegator initial balance: %s XRP\n", delegatorBalance)
|
||||||
|
fmt.Printf("Delegatee initial balance: %s XRP\n", delegateeBalance)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Create DelegateSet transaction
|
||||||
|
delegateSetTx := &transactions.DelegateSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: txnTypes.Address(delegatorWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Authorize: txnTypes.Address(delegateeWallet.ClassicAddress),
|
||||||
|
Permissions: []txnTypes.Permission{
|
||||||
|
{
|
||||||
|
Permission: txnTypes.PermissionValue{
|
||||||
|
PermissionValue: "Payment",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit DelegateSet transaction
|
||||||
|
response, err := client.SubmitTxAndWait(delegateSetTx.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &delegatorWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("DelegateSet transaction submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash)
|
||||||
|
fmt.Printf("Validated: %t\n", response.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Create delegated payment transaction
|
||||||
|
delegatedPaymentTx := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: txnTypes.Address(delegatorWallet.ClassicAddress),
|
||||||
|
Delegate: txnTypes.Address(delegateeWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: txnTypes.Address(delegateeWallet.ClassicAddress),
|
||||||
|
Amount: txnTypes.XRPCurrencyAmount(1000000), // 1 XRP
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit delegated payment
|
||||||
|
response2, err := client.SubmitTxAndWait(delegatedPaymentTx.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &delegateeWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Delegated payment submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response2.Hash)
|
||||||
|
fmt.Printf("Validated: %t\n", response2.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check final balances
|
||||||
|
finalDelegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalDelegatorBalance = "0"
|
||||||
|
}
|
||||||
|
finalDelegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalDelegateeBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Delegator final balance: %s XRP\n", finalDelegatorBalance)
|
||||||
|
fmt.Printf("Delegatee final balance: %s XRP\n", finalDelegateeBalance)
|
||||||
|
}
|
||||||
140
_code-samples/delegate-set/go/ws/main.go
Normal file
140
_code-samples/delegate-set/go/ws/main.go
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Connect to testnet
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and fund wallets
|
||||||
|
delegatorWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
delegateeWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
if err := client.FundWallet(&delegatorWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&delegateeWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Wallets funded")
|
||||||
|
|
||||||
|
// Check initial balances
|
||||||
|
delegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
delegatorBalance = "0"
|
||||||
|
}
|
||||||
|
delegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
delegateeBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Delegator initial balance: %s XRP\n", delegatorBalance)
|
||||||
|
fmt.Printf("Delegatee initial balance: %s XRP\n", delegateeBalance)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Create DelegateSet transaction
|
||||||
|
delegateSetTx := &transactions.DelegateSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(delegatorWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Authorize: types.Address(delegateeWallet.ClassicAddress),
|
||||||
|
Permissions: []types.Permission{
|
||||||
|
{
|
||||||
|
Permission: types.PermissionValue{
|
||||||
|
PermissionValue: "Payment",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit DelegateSet transaction
|
||||||
|
flattenedTx := delegateSetTx.Flatten()
|
||||||
|
if err := client.Autofill(&flattenedTx); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := delegatorWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("DelegateSet transaction submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash)
|
||||||
|
fmt.Printf("Validated: %t\n", response.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Create delegated payment transaction
|
||||||
|
delegatedPaymentTx := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(delegatorWallet.ClassicAddress),
|
||||||
|
Delegate: types.Address(delegateeWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(delegateeWallet.ClassicAddress),
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000), // 1 XRP
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit delegated payment
|
||||||
|
flatDelegatedPayment := delegatedPaymentTx.Flatten()
|
||||||
|
if err := client.Autofill(&flatDelegatedPayment); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob2, _, err := delegateeWallet.Sign(flatDelegatedPayment)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response2, err := client.SubmitTxBlobAndWait(txBlob2, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Delegated payment submitted")
|
||||||
|
fmt.Printf("Hash: %s\n", response2.Hash)
|
||||||
|
fmt.Printf("Validated: %t\n", response2.Validated)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Check final balances
|
||||||
|
finalDelegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalDelegatorBalance = "0"
|
||||||
|
}
|
||||||
|
finalDelegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
|
||||||
|
if err != nil {
|
||||||
|
finalDelegateeBalance = "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Delegator final balance: %s XRP\n", finalDelegatorBalance)
|
||||||
|
fmt.Printf("Delegatee final balance: %s XRP\n", finalDelegateeBalance)
|
||||||
|
}
|
||||||
3
_code-samples/deposit-preauth/README.md
Normal file
3
_code-samples/deposit-preauth/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# DepositPreauth
|
||||||
|
|
||||||
|
Example of DepositPreauth transaction demonstrating how deposit permissions can be managed.
|
||||||
24
_code-samples/deposit-preauth/go/go.mod
Normal file
24
_code-samples/deposit-preauth/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/deposit-preauth/go/go.sum
Normal file
58
_code-samples/deposit-preauth/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
214
_code-samples/deposit-preauth/go/rpc/main.go
Normal file
214
_code-samples/deposit-preauth/go/rpc/main.go
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/examples/clients"
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
|
||||||
|
rippletime "github.com/Peersyst/xrpl-go/xrpl/time"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client := clients.GetDevnetRpcClient()
|
||||||
|
|
||||||
|
// Configure wallets
|
||||||
|
|
||||||
|
// Issuer
|
||||||
|
fmt.Println("Setting up credential issuer wallet...")
|
||||||
|
issuer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&issuer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Credential issuer wallet funded: %s\n", issuer.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Holder 1
|
||||||
|
fmt.Println("Setting up holder 1 wallet...")
|
||||||
|
holderWallet1, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&holderWallet1)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Holder 1 wallet funded: %s\n", holderWallet1.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Enabling DepositAuth on the issuer account with an AccountSet transaction
|
||||||
|
fmt.Println("Enabling DepositAuth on the issuer account...")
|
||||||
|
accountSetTx := &transaction.AccountSet{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.AccountSetTx,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
accountSetTx.SetAsfDepositAuth()
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, accountSetTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialCreate transaction
|
||||||
|
fmt.Println("Creating the CredentialCreate transaction...")
|
||||||
|
|
||||||
|
expiration, err := rippletime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
credentialType := types.CredentialType("6D795F63726564656E7469616C") // my_credential
|
||||||
|
|
||||||
|
credentialCreateTx := &transaction.CredentialCreate{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.CredentialCreateTx,
|
||||||
|
},
|
||||||
|
Expiration: uint32(expiration),
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Subject: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
URI: hex.EncodeToString([]byte("https://example.com")),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, credentialCreateTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialAccept transaction
|
||||||
|
fmt.Println("Creating the CredentialAccept transaction...")
|
||||||
|
|
||||||
|
credentialAcceptTx := &transaction.CredentialAccept{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
TransactionType: transaction.CredentialAcceptTx,
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, credentialAcceptTx, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the DepositPreauth transaction
|
||||||
|
fmt.Println("Creating the DepositPreauth transaction using AuthorizeCredentials...")
|
||||||
|
|
||||||
|
depositPreauthTx := &transaction.DepositPreauth{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.DepositPreauthTx,
|
||||||
|
},
|
||||||
|
AuthorizeCredentials: []types.AuthorizeCredentialsWrapper{
|
||||||
|
{
|
||||||
|
Credential: types.AuthorizeCredentials{
|
||||||
|
Issuer: issuer.ClassicAddress,
|
||||||
|
CredentialType: credentialType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, depositPreauthTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Get the credential ID
|
||||||
|
fmt.Println("Getting the credential ID from the holder 1 account...")
|
||||||
|
|
||||||
|
objectsRequest := &account.ObjectsRequest{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
Type: account.CredentialObject,
|
||||||
|
LedgerIndex: common.Validated,
|
||||||
|
}
|
||||||
|
|
||||||
|
objectsResponse, err := client.GetAccountObjects(objectsRequest)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have any credential objects
|
||||||
|
if len(objectsResponse.AccountObjects) == 0 {
|
||||||
|
fmt.Println("No credential objects found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the credential ID
|
||||||
|
credentialID, ok := objectsResponse.AccountObjects[0]["index"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Could not extract credential ID from response")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Credential ID: %s\n", credentialID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending XRP to the holder 1 account
|
||||||
|
fmt.Println("Sending XRP to the issuer account, should succeed...")
|
||||||
|
|
||||||
|
sendTx := &transaction.Payment{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
TransactionType: transaction.PaymentTx,
|
||||||
|
},
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000),
|
||||||
|
Destination: issuer.ClassicAddress,
|
||||||
|
CredentialIDs: types.CredentialIDs{credentialID},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, sendTx, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Unauthorizing the holder 1 account
|
||||||
|
fmt.Println("Unauthorizing the holder 1 account with the DepositPreauth transaction and the UnauthorizeCredentials field...")
|
||||||
|
|
||||||
|
unauthorizeTx := &transaction.DepositPreauth{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.DepositPreauthTx,
|
||||||
|
},
|
||||||
|
UnauthorizeCredentials: []types.AuthorizeCredentialsWrapper{
|
||||||
|
{
|
||||||
|
Credential: types.AuthorizeCredentials{
|
||||||
|
Issuer: issuer.ClassicAddress,
|
||||||
|
CredentialType: credentialType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, unauthorizeTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending XRP to the holder 1 account again (which should fail)
|
||||||
|
fmt.Println("Sending XRP to the issuer account again (which should fail)...")
|
||||||
|
|
||||||
|
sendTx2 := &transaction.Payment{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
TransactionType: transaction.PaymentTx,
|
||||||
|
},
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000),
|
||||||
|
Destination: issuer.ClassicAddress,
|
||||||
|
CredentialIDs: types.CredentialIDs{credentialID},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, sendTx2, holderWallet1)
|
||||||
|
}
|
||||||
227
_code-samples/deposit-preauth/go/ws/main.go
Normal file
227
_code-samples/deposit-preauth/go/ws/main.go
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/examples/clients"
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
|
||||||
|
rippletime "github.com/Peersyst/xrpl-go/xrpl/time"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
fmt.Println("Setting up client...")
|
||||||
|
|
||||||
|
client := clients.GetDevnetWebsocketClient()
|
||||||
|
fmt.Println("Connecting to server...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Client configured!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Printf("Connection: %t", client.IsConnected())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Configure wallets
|
||||||
|
|
||||||
|
// Issuer
|
||||||
|
fmt.Println("Setting up credential issuer wallet...")
|
||||||
|
issuer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&issuer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Credential issuer wallet funded: %s\n", issuer.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Holder 1
|
||||||
|
fmt.Println("Setting up holder 1 wallet...")
|
||||||
|
holderWallet1, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&holderWallet1)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Holder 1 wallet funded: %s\n", holderWallet1.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Enabling DepositAuth on the issuer account with an AccountSet transaction
|
||||||
|
fmt.Println("Enabling DepositAuth on the issuer account...")
|
||||||
|
accountSetTx := &transaction.AccountSet{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.AccountSetTx,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
accountSetTx.SetAsfDepositAuth()
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, accountSetTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialCreate transaction
|
||||||
|
fmt.Println("Creating the CredentialCreate transaction...")
|
||||||
|
|
||||||
|
expiration, err := rippletime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
credentialType := types.CredentialType("6D795F63726564656E7469616C") // my_credential
|
||||||
|
|
||||||
|
credentialCreateTx := &transaction.CredentialCreate{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.CredentialCreateTx,
|
||||||
|
},
|
||||||
|
Expiration: uint32(expiration),
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Subject: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
URI: hex.EncodeToString([]byte("https://example.com")),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, credentialCreateTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the CredentialAccept transaction
|
||||||
|
fmt.Println("Creating the CredentialAccept transaction...")
|
||||||
|
|
||||||
|
credentialAcceptTx := &transaction.CredentialAccept{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
TransactionType: transaction.CredentialAcceptTx,
|
||||||
|
},
|
||||||
|
CredentialType: credentialType,
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, credentialAcceptTx, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Creating the DepositPreauth transaction
|
||||||
|
fmt.Println("Creating the DepositPreauth transaction using AuthorizeCredentials...")
|
||||||
|
|
||||||
|
depositPreauthTx := &transaction.DepositPreauth{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.DepositPreauthTx,
|
||||||
|
},
|
||||||
|
AuthorizeCredentials: []types.AuthorizeCredentialsWrapper{
|
||||||
|
{
|
||||||
|
Credential: types.AuthorizeCredentials{
|
||||||
|
Issuer: issuer.ClassicAddress,
|
||||||
|
CredentialType: credentialType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, depositPreauthTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Get the credential ID
|
||||||
|
fmt.Println("Getting the credential ID from the holder 1 account...")
|
||||||
|
|
||||||
|
objectsRequest := &account.ObjectsRequest{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
Type: account.CredentialObject,
|
||||||
|
LedgerIndex: common.Validated,
|
||||||
|
}
|
||||||
|
|
||||||
|
objectsResponse, err := client.GetAccountObjects(objectsRequest)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have any credential objects
|
||||||
|
if len(objectsResponse.AccountObjects) == 0 {
|
||||||
|
fmt.Println("No credential objects found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the credential ID
|
||||||
|
credentialID, ok := objectsResponse.AccountObjects[0]["index"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Could not extract credential ID from response")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Credential ID: %s\n", credentialID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending XRP to the holder 1 account
|
||||||
|
fmt.Println("Sending XRP to the issuer account, should succeed...")
|
||||||
|
|
||||||
|
sendTx := &transaction.Payment{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
TransactionType: transaction.PaymentTx,
|
||||||
|
},
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000),
|
||||||
|
Destination: issuer.ClassicAddress,
|
||||||
|
CredentialIDs: types.CredentialIDs{credentialID},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, sendTx, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Unauthorize the holder 1 account
|
||||||
|
fmt.Println("Unauthorize the holder 1 account with the DepositPreauth transaction and the UnauthorizeCredentials field...")
|
||||||
|
|
||||||
|
unauthorizeTx := &transaction.DepositPreauth{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: issuer.ClassicAddress,
|
||||||
|
TransactionType: transaction.DepositPreauthTx,
|
||||||
|
},
|
||||||
|
UnauthorizeCredentials: []types.AuthorizeCredentialsWrapper{
|
||||||
|
{
|
||||||
|
Credential: types.AuthorizeCredentials{
|
||||||
|
Issuer: issuer.ClassicAddress,
|
||||||
|
CredentialType: credentialType,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, unauthorizeTx, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending XRP to the holder 1 account again (which should fail)
|
||||||
|
fmt.Println("Sending XRP to the issuer account again (which should fail)...")
|
||||||
|
|
||||||
|
sendTx2 := &transaction.Payment{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: holderWallet1.ClassicAddress,
|
||||||
|
TransactionType: transaction.PaymentTx,
|
||||||
|
},
|
||||||
|
Amount: types.XRPCurrencyAmount(1000000),
|
||||||
|
Destination: issuer.ClassicAddress,
|
||||||
|
CredentialIDs: types.CredentialIDs{credentialID},
|
||||||
|
}
|
||||||
|
|
||||||
|
clients.SubmitTxBlobAndWait(client, sendTx2, holderWallet1)
|
||||||
|
}
|
||||||
24
_code-samples/freeze/go/go.mod
Normal file
24
_code-samples/freeze/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/freeze/go/go.sum
Normal file
58
_code-samples/freeze/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
335
_code-samples/freeze/go/rpc/main.go
Normal file
335
_code-samples/freeze/go/rpc/main.go
Normal file
@@ -0,0 +1,335 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/currency"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currencyCode = "USDA"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SubmittableTransaction interface {
|
||||||
|
TxType() transactions.TxType
|
||||||
|
Flatten() transactions.FlatTransaction // Ensures all transactions can be flattened
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
client := getRpcClient()
|
||||||
|
|
||||||
|
// Configure wallets
|
||||||
|
|
||||||
|
// Issuer
|
||||||
|
fmt.Println("Setting up issuer wallet...")
|
||||||
|
issuer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&issuer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Issuer wallet funded: %s\n", issuer.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Holder 1
|
||||||
|
fmt.Println("Setting up holder 1 wallet...")
|
||||||
|
holderWallet1, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&holderWallet1)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Holder wallet 1 funded: %s\n", holderWallet1.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Holder 2
|
||||||
|
fmt.Println("Setting up holder 2 wallet...")
|
||||||
|
holderWallet2, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&holderWallet2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Holder wallet 2 funded: %s\n", holderWallet2.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Configuring Issuing account
|
||||||
|
fmt.Println("Configuring issuer address settings...")
|
||||||
|
accountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
Domain: types.Domain("697373756572"), // issuer
|
||||||
|
}
|
||||||
|
|
||||||
|
accountSet.SetAsfDefaultRipple()
|
||||||
|
submitAndWait(client, accountSet, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Trustline from the holder 1 to the issuer
|
||||||
|
fmt.Println("Setting up trustline from holder 1 to the issuer...")
|
||||||
|
trustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "1000000000",
|
||||||
|
}}
|
||||||
|
trustSet.SetSetNoRippleFlag()
|
||||||
|
submitAndWait(client, trustSet, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Trustline from the holder 2 to the issuer
|
||||||
|
fmt.Println("Setting up trustline from holder 2 to the issuer...")
|
||||||
|
trustSet = &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "1000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
trustSet.SetSetNoRippleFlag()
|
||||||
|
submitAndWait(client, trustSet, holderWallet2)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Minting to Holder 1
|
||||||
|
fmt.Println("Minting to Holder 1...")
|
||||||
|
payment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "50000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Minting to Holder 2
|
||||||
|
fmt.Println("Minting to Holder 2...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "40000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 1 to Holder 2
|
||||||
|
fmt.Println("Sending payment from Holder 1 to Holder 2...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "20",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Freezing and Deep Freezing holder1
|
||||||
|
fmt.Println("Freezing and Deep Freezing holder 1 trustline...")
|
||||||
|
trustSet = &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Value: "0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
trustSet.SetSetFreezeFlag()
|
||||||
|
trustSet.SetSetDeepFreezeFlag()
|
||||||
|
|
||||||
|
submitAndWait(client, trustSet, issuer)
|
||||||
|
|
||||||
|
// ------------------- SHOULD FAIL ------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 1 to Holder 2 (which should fail), Holder 1 can't decrease its balance
|
||||||
|
fmt.Println("Sending payment from Holder 1 to Holder 2 (which should fail). Holder 1 can't decrease its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet1)
|
||||||
|
|
||||||
|
// ------------------- SHOULD FAIL ------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 2 to Holder 1 (which should fail), Holder 1 can't increase its balance
|
||||||
|
fmt.Println("Sending payment from Holder 2 to Holder 1 (which should fail). Holder 1 can't increase its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet2)
|
||||||
|
|
||||||
|
// ------------------- SHOULD FAIL ------------------
|
||||||
|
|
||||||
|
// Creating OfferCreate transaction (which should fail), Holder 1 can't create an offer
|
||||||
|
fmt.Println("Creating OfferCreate transaction (which should fail). Holder 1 can't create an offer...")
|
||||||
|
offerCreate := &transactions.OfferCreate{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
TakerPays: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
TakerGets: types.XRPCurrencyAmount(10),
|
||||||
|
}
|
||||||
|
submitAndWait(client, offerCreate, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Unfreezing and Deep Unfreezing holder 1
|
||||||
|
fmt.Println("Unfreezing and Deep Unfreezing holder 1 trustline...")
|
||||||
|
trustSet = &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Value: "0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
trustSet.SetClearFreezeFlag()
|
||||||
|
trustSet.SetClearDeepFreezeFlag()
|
||||||
|
submitAndWait(client, trustSet, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 1 to Holder 2 (which should succeed), Holder 1 can decrease its balance
|
||||||
|
fmt.Println("Sending payment from Holder 1 to Holder 2 (which should succeed). Holder 1 can decrease its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 2 to Holder 1 (which should succeed), Holder 1 can increase its balance
|
||||||
|
fmt.Println("Sending payment from Holder 2 to Holder 1 (which should succeed). Holder 1 can increase its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRpcClient returns a new rpc client
|
||||||
|
func getRpcClient() *rpc.Client {
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
// DeepFreeze only available on Devnet as of February 2025, change to testnet/mainnet once the amendment passes.
|
||||||
|
"https://s.devnet.rippletest.net:51234",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rpc.NewClient(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// submitAndWait submits a transaction and waits for it to be included in a validated ledger
|
||||||
|
func submitAndWait(client *rpc.Client, txn SubmittableTransaction, wallet wallet.Wallet) {
|
||||||
|
fmt.Printf("Submitting %s transaction...\n", txn.TxType())
|
||||||
|
|
||||||
|
flattenedTx := txn.Flatten()
|
||||||
|
|
||||||
|
err := client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := wallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s transaction submitted\n", txn.TxType())
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
344
_code-samples/freeze/go/ws/main.go
Normal file
344
_code-samples/freeze/go/ws/main.go
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/currency"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currencyCode = "USDA"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SubmittableTransaction interface {
|
||||||
|
TxType() transactions.TxType
|
||||||
|
Flatten() transactions.FlatTransaction // Ensures all transactions can be flattened
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Setting up client...")
|
||||||
|
|
||||||
|
client := getClient()
|
||||||
|
fmt.Println("Connecting to server...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Client configured!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Printf("Connection: %t", client.IsConnected())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Configure wallets
|
||||||
|
|
||||||
|
// Issuer
|
||||||
|
fmt.Println("Setting up issuer wallet...")
|
||||||
|
issuer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&issuer)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Issuer wallet funded: %s\n", issuer.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Holder 1
|
||||||
|
fmt.Println("Setting up holder 1 wallet...")
|
||||||
|
holderWallet1, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&holderWallet1)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Holder wallet 1 funded: %s\n", holderWallet1.ClassicAddress)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Holder 2
|
||||||
|
fmt.Println("Setting up holder 2 wallet...")
|
||||||
|
holderWallet2, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = client.FundWallet(&holderWallet2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Printf("Holder wallet 2 funded: %s\n", holderWallet2.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Configuring Issuing account
|
||||||
|
fmt.Println("Configuring issuer address settings...")
|
||||||
|
accountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
Domain: types.Domain("697373756572"), // issuer
|
||||||
|
}
|
||||||
|
|
||||||
|
accountSet.SetAsfDefaultRipple()
|
||||||
|
submitAndWait(client, accountSet, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Trustline from the holder 1 to the issuer
|
||||||
|
fmt.Println("Setting up trustline from holder 1 to the issuer...")
|
||||||
|
trustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "1000000000",
|
||||||
|
}}
|
||||||
|
trustSet.SetSetNoRippleFlag()
|
||||||
|
submitAndWait(client, trustSet, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Trustline from the holder 2 to the issuer
|
||||||
|
fmt.Println("Setting up trustline from holder 2 to the issuer...")
|
||||||
|
trustSet = &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "1000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
trustSet.SetSetNoRippleFlag()
|
||||||
|
submitAndWait(client, trustSet, holderWallet2)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Minting to Holder 1
|
||||||
|
fmt.Println("Minting to Holder 1...")
|
||||||
|
payment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "50000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Minting to Holder 2
|
||||||
|
fmt.Println("Minting to Holder 2...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "40000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 1 to Holder 2
|
||||||
|
fmt.Println("Sending payment from Holder 1 to Holder 2...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "20",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Freezing and Deep Freezing holder1
|
||||||
|
fmt.Println("Freezing and Deep Freezing holder 1 trustline...")
|
||||||
|
trustSet = &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Value: "0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
trustSet.SetSetFreezeFlag()
|
||||||
|
trustSet.SetSetDeepFreezeFlag()
|
||||||
|
|
||||||
|
submitAndWait(client, trustSet, issuer)
|
||||||
|
|
||||||
|
// ------------------- SHOULD FAIL ------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 1 to Holder 2 (which should fail), Holder 1 can't decrease its balance
|
||||||
|
fmt.Println("Sending payment from Holder 1 to Holder 2 (which should fail). Holder 1 can't decrease its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet1)
|
||||||
|
|
||||||
|
// ------------------- SHOULD FAIL ------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 2 to Holder 1 (which should fail), Holder 1 can't increase its balance
|
||||||
|
fmt.Println("Sending payment from Holder 2 to Holder 1 (which should fail). Holder 1 can't increase its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet2)
|
||||||
|
|
||||||
|
// ------------------- SHOULD FAIL ------------------
|
||||||
|
|
||||||
|
// Creating OfferCreate transaction (which should fail), Holder 1 can't create an offer
|
||||||
|
fmt.Println("Creating OfferCreate transaction (which should fail). Holder 1 can't create an offer...")
|
||||||
|
offerCreate := &transactions.OfferCreate{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
TakerPays: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
TakerGets: types.XRPCurrencyAmount(10),
|
||||||
|
}
|
||||||
|
submitAndWait(client, offerCreate, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Unfreezing and Deep Unfreezing holder 1
|
||||||
|
fmt.Println("Unfreezing and Deep Unfreezing holder 1 trustline...")
|
||||||
|
trustSet = &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(issuer.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Value: "0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
trustSet.SetClearFreezeFlag()
|
||||||
|
trustSet.SetClearDeepFreezeFlag()
|
||||||
|
submitAndWait(client, trustSet, issuer)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 1 to Holder 2 (which should succeed), Holder 1 can decrease its balance
|
||||||
|
fmt.Println("Sending payment from Holder 1 to Holder 2 (which should succeed). Holder 1 can decrease its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet1)
|
||||||
|
|
||||||
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
// Sending payment from Holder 2 to Holder 1 (which should succeed), Holder 1 can increase its balance
|
||||||
|
fmt.Println("Sending payment from Holder 2 to Holder 1 (which should succeed). Holder 1 can increase its balance...")
|
||||||
|
payment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(holderWallet2.ClassicAddress),
|
||||||
|
},
|
||||||
|
Destination: types.Address(holderWallet1.ClassicAddress),
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currency.ConvertStringToHex(currencyCode),
|
||||||
|
Issuer: types.Address(issuer.ClassicAddress),
|
||||||
|
Value: "10",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
submitAndWait(client, payment, holderWallet2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRpcClient returns a new rpc client
|
||||||
|
func getClient() *websocket.Client {
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
// submitAndWait submits a transaction and waits for it to be included in a validated ledger
|
||||||
|
func submitAndWait(client *websocket.Client, txn SubmittableTransaction, wallet wallet.Wallet) {
|
||||||
|
fmt.Printf("Submitting %s transaction...\n", txn.TxType())
|
||||||
|
|
||||||
|
flattenedTx := txn.Flatten()
|
||||||
|
|
||||||
|
err := client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := wallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s transaction submitted\n", txn.TxType())
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
@@ -8,3 +8,4 @@ For more context, see the Get Started tutorial for your preferred language:
|
|||||||
- [Java](https://xrpl.org/get-started-using-java.html)
|
- [Java](https://xrpl.org/get-started-using-java.html)
|
||||||
- [JavaScript](https://xrpl.org/get-started-using-javascript.html)
|
- [JavaScript](https://xrpl.org/get-started-using-javascript.html)
|
||||||
- [PHP](https://xrpl.org/get-started-using-php.html)
|
- [PHP](https://xrpl.org/get-started-using-php.html)
|
||||||
|
- [Go](https://xrpl.org/get-started-using-go.html)
|
||||||
|
|||||||
30
_code-samples/get-started/go/base/rpc/main.go
Normal file
30
_code-samples/get-started/go/base/rpc/main.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/utility"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Define the network client configuration
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initiate the network client
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Ping the network (used to avoid Go unused variable error, but useful to check connectivity)
|
||||||
|
_, err = client.Ping(&utility.PingRequest{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... custom code goes here
|
||||||
|
|
||||||
|
}
|
||||||
25
_code-samples/get-started/go/base/ws/main.go
Normal file
25
_code-samples/get-started/go/base/ws/main.go
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Define the network client
|
||||||
|
client := websocket.NewClient(websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.altnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Disconnect the client when done. (Defer executes at the end of the function)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
// Connect to the network
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... custom code goes here
|
||||||
|
}
|
||||||
55
_code-samples/get-started/go/get-acc-info/rpc/main.go
Normal file
55
_code-samples/get-started/go/get-acc-info/rpc/main.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/ledger"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Define the network client with a faucet provider
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Create a new wallet
|
||||||
|
w, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("New wallet created:")
|
||||||
|
fmt.Println("Address:", w.ClassicAddress)
|
||||||
|
|
||||||
|
// Fund the wallet with testnet XRP
|
||||||
|
if err := client.FundWallet(&w); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get info from the ledger about the address we just funded
|
||||||
|
acc_info, err := client.GetAccountInfo(&account.InfoRequest{
|
||||||
|
Account: w.GetAddress(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Account Balance:", acc_info.AccountData.Balance)
|
||||||
|
fmt.Println("Account Sequence:", acc_info.AccountData.Sequence)
|
||||||
|
|
||||||
|
// Get info about the ledger
|
||||||
|
ledger, err := client.GetLedger(&ledger.Request{LedgerIndex: common.Current})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Ledger Index:", ledger.Ledger.LedgerIndex)
|
||||||
|
}
|
||||||
69
_code-samples/get-started/go/get-acc-info/ws/main.go
Normal file
69
_code-samples/get-started/go/get-acc-info/ws/main.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/ledger"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Define the network client with a faucet provider
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.altnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Disconnect the client when done. (Defer executes at the end of the function)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
// Connect to the network
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to testnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connected to testnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Create a new wallet
|
||||||
|
w, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("New wallet created:")
|
||||||
|
fmt.Println("Address:", w.ClassicAddress)
|
||||||
|
|
||||||
|
// Fund the wallet with testnet XRP
|
||||||
|
if err := client.FundWallet(&w); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get info from the ledger about the address we just funded
|
||||||
|
acc_info, err := client.GetAccountInfo(&account.InfoRequest{
|
||||||
|
Account: w.GetAddress(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Account Balance:", acc_info.AccountData.Balance)
|
||||||
|
fmt.Println("Account Sequence:", acc_info.AccountData.Sequence)
|
||||||
|
|
||||||
|
// Get info about the ledger
|
||||||
|
ledger, err := client.GetLedger(&ledger.Request{LedgerIndex: common.Current})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Ledger Index:", ledger.Ledger.LedgerIndex)
|
||||||
|
}
|
||||||
24
_code-samples/get-started/go/go.mod
Normal file
24
_code-samples/get-started/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/get-started/go/go.sum
Normal file
58
_code-samples/get-started/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
135
_code-samples/get-started/js/README.md
Normal file
135
_code-samples/get-started/js/README.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# Get Started Using JavaScript Library
|
||||||
|
|
||||||
|
Connects to the XRP Ledger, gets account information, and subscribes to ledger events using JavaScript.
|
||||||
|
|
||||||
|
To download the source code, see [Get Started Using JavaScript Library](http://xrpl.org/docs/tutorials/javascript/build-apps/get-started).
|
||||||
|
|
||||||
|
## Run the Code
|
||||||
|
|
||||||
|
**Node.js**
|
||||||
|
|
||||||
|
Quick setup and usage:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install
|
||||||
|
node ./get-acct-info.js
|
||||||
|
```
|
||||||
|
|
||||||
|
You should see output similar to the following:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Connected to Testnet
|
||||||
|
|
||||||
|
Creating a new wallet and funding it with Testnet XRP...
|
||||||
|
Wallet: rMnXR9p2sZT9iZ6ew3iEqvBMyPts1ADc4i
|
||||||
|
Balance: 10
|
||||||
|
|
||||||
|
Account Testnet Explorer URL:
|
||||||
|
https://testnet.xrpl.org/accounts/rMnXR9p2sZT9iZ6ew3iEqvBMyPts1ADc4i
|
||||||
|
|
||||||
|
Getting account info...
|
||||||
|
{
|
||||||
|
"api_version": 2,
|
||||||
|
"id": 4,
|
||||||
|
"result": {
|
||||||
|
"account_data": {
|
||||||
|
"Account": "rMnXR9p2sZT9iZ6ew3iEqvBMyPts1ADc4i",
|
||||||
|
"Balance": "10000000",
|
||||||
|
"Flags": 0,
|
||||||
|
"LedgerEntryType": "AccountRoot",
|
||||||
|
"OwnerCount": 0,
|
||||||
|
"PreviousTxnID": "0FF9DB2FE141DD0DF82566A171B6AF70BB2C6EB6A53D496E65D42FC062C91A78",
|
||||||
|
"PreviousTxnLgrSeq": 9949268,
|
||||||
|
"Sequence": 9949268,
|
||||||
|
"index": "4A9C9220AE778DC38C004B2B17A08E218416D90E01456AFCF844C18838B36D01"
|
||||||
|
},
|
||||||
|
"account_flags": {
|
||||||
|
"allowTrustLineClawback": false,
|
||||||
|
"defaultRipple": false,
|
||||||
|
"depositAuth": false,
|
||||||
|
"disableMasterKey": false,
|
||||||
|
"disallowIncomingCheck": false,
|
||||||
|
"disallowIncomingNFTokenOffer": false,
|
||||||
|
"disallowIncomingPayChan": false,
|
||||||
|
"disallowIncomingTrustline": false,
|
||||||
|
"disallowIncomingXRP": false,
|
||||||
|
"globalFreeze": false,
|
||||||
|
"noFreeze": false,
|
||||||
|
"passwordSpent": false,
|
||||||
|
"requireAuthorization": false,
|
||||||
|
"requireDestinationTag": false
|
||||||
|
},
|
||||||
|
"ledger_hash": "304C7CC2A33B712BE43EB398B399E290C191A71FCB71784F584544DFB7C441B0",
|
||||||
|
"ledger_index": 9949268,
|
||||||
|
"validated": true
|
||||||
|
},
|
||||||
|
"type": "response"
|
||||||
|
}
|
||||||
|
|
||||||
|
Listening for ledger close events...
|
||||||
|
Ledger #9949269 validated with 0 transactions!
|
||||||
|
Ledger #9949270 validated with 0 transactions!
|
||||||
|
Ledger #9949271 validated with 0 transactions!
|
||||||
|
|
||||||
|
Disconnected
|
||||||
|
```
|
||||||
|
|
||||||
|
**Web**
|
||||||
|
|
||||||
|
To run the web example, open `index.html` in a web browser and wait for the results to appear on the page.
|
||||||
|
|
||||||
|
You should see output similar to the following:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Connected to Testnet
|
||||||
|
Creating a new wallet and funding it with Testnet XRP...
|
||||||
|
Wallet: rf7CWJdNssSzQk2GtypYLVhyvGe8oHS3S
|
||||||
|
Balance: 10
|
||||||
|
View account on XRPL Testnet Explorer: rf7CWJdNssSzQk2GtypYLVhyvGe8oHS3S
|
||||||
|
|
||||||
|
Getting account info...
|
||||||
|
{
|
||||||
|
"api_version": 2,
|
||||||
|
"id": 5,
|
||||||
|
"result": {
|
||||||
|
"account_data": {
|
||||||
|
"Account": "rf7CWJdNssSzQk2GtypYLVhyvGe8oHS3S",
|
||||||
|
"Balance": "10000000",
|
||||||
|
"Flags": 0,
|
||||||
|
"LedgerEntryType": "AccountRoot",
|
||||||
|
"OwnerCount": 0,
|
||||||
|
"PreviousTxnID": "96E4B44F93EC0399B7ADD75489630C6A8DCFC922F20F6810D25490CC0D3AA12E",
|
||||||
|
"PreviousTxnLgrSeq": 9949610,
|
||||||
|
"Sequence": 9949610,
|
||||||
|
"index": "B5D2865DD4BF8EEDFEE2FD95DE37FC28D624548E9BBC42F9FBF61B618E98FAC8"
|
||||||
|
},
|
||||||
|
"account_flags": {
|
||||||
|
"allowTrustLineClawback": false,
|
||||||
|
"defaultRipple": false,
|
||||||
|
"depositAuth": false,
|
||||||
|
"disableMasterKey": false,
|
||||||
|
"disallowIncomingCheck": false,
|
||||||
|
"disallowIncomingNFTokenOffer": false,
|
||||||
|
"disallowIncomingPayChan": false,
|
||||||
|
"disallowIncomingTrustline": false,
|
||||||
|
"disallowIncomingXRP": false,
|
||||||
|
"globalFreeze": false,
|
||||||
|
"noFreeze": false,
|
||||||
|
"passwordSpent": false,
|
||||||
|
"requireAuthorization": false,
|
||||||
|
"requireDestinationTag": false
|
||||||
|
},
|
||||||
|
"ledger_hash": "7692673B8091899C3EEE6807F66B65851D3563F483A49A5F03A83608658473D6",
|
||||||
|
"ledger_index": 9949610,
|
||||||
|
"validated": true
|
||||||
|
},
|
||||||
|
"type": "response"
|
||||||
|
}
|
||||||
|
|
||||||
|
Listening for ledger close events...
|
||||||
|
Ledger #9949611 validated with 0 transactions
|
||||||
|
Ledger #9949612 validated with 1 transactions
|
||||||
|
Ledger #9949613 validated with 0 transactions
|
||||||
|
|
||||||
|
Disconnected
|
||||||
|
```
|
||||||
@@ -1,17 +1,11 @@
|
|||||||
// In browsers, use a <script> tag. In Node.js, uncomment the following line:
|
// You can also use a <script> tag in browsers or require('xrpl') in Node.js
|
||||||
// const xrpl = require('xrpl')
|
import xrpl from 'xrpl'
|
||||||
|
|
||||||
// Wrap code in an async function so we can use await
|
// Define the network client
|
||||||
async function main() {
|
const client = new xrpl.Client("wss://s.altnet.rippletest.net:51233")
|
||||||
|
await client.connect()
|
||||||
|
|
||||||
// Define the network client
|
// ... custom code goes here
|
||||||
const client = new xrpl.Client("wss://s.altnet.rippletest.net:51233")
|
|
||||||
await client.connect()
|
|
||||||
|
|
||||||
// ... custom code goes here
|
// Disconnect when done (If you omit this, Node.js won't end the process)
|
||||||
|
client.disconnect()
|
||||||
// Disconnect when done (If you omit this, Node.js won't end the process)
|
|
||||||
await client.disconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|||||||
@@ -1,39 +1,65 @@
|
|||||||
// Import the library
|
// Import the library
|
||||||
const xrpl = require("xrpl")
|
// @chunk {"steps": ["connect-tag"]}
|
||||||
|
import xrpl from "xrpl"
|
||||||
|
|
||||||
// Wrap code in an async function so we can use await
|
// Define the network client
|
||||||
async function main() {
|
const SERVER_URL = "wss://s.altnet.rippletest.net:51233/"
|
||||||
|
const client = new xrpl.Client(SERVER_URL)
|
||||||
|
await client.connect()
|
||||||
|
console.log("Connected to Testnet")
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
// Define the network client
|
// @chunk {"steps": ["get-account-create-wallet-tag"]}
|
||||||
const SERVER_URL = "wss://s.altnet.rippletest.net:51233/"
|
// Create a wallet and fund it with the Testnet faucet:
|
||||||
const client = new xrpl.Client(SERVER_URL)
|
console.log("\nCreating a new wallet and funding it with Testnet XRP...")
|
||||||
await client.connect()
|
const fund_result = await client.fundWallet()
|
||||||
|
const test_wallet = fund_result.wallet
|
||||||
|
console.log(`Wallet: ${test_wallet.address}`)
|
||||||
|
console.log(`Balance: ${fund_result.balance}`)
|
||||||
|
console.log('Account Testnet Explorer URL:')
|
||||||
|
console.log(` https://testnet.xrpl.org/accounts/${test_wallet.address}`)
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
// Create a wallet and fund it with the Testnet faucet:
|
// To generate a wallet without funding it, uncomment the code below
|
||||||
const fund_result = await client.fundWallet()
|
// @chunk {"steps": ["get-account-create-wallet-b-tag"]}
|
||||||
const test_wallet = fund_result.wallet
|
// const test_wallet = xrpl.Wallet.generate()
|
||||||
console.log(fund_result)
|
// @chunk-end
|
||||||
|
|
||||||
// Get info from the ledger about the address we just funded
|
// To provide your own seed, replace the test_wallet value with the below
|
||||||
const response = await client.request({
|
// @chunk {"steps": ["get-account-create-wallet-c-tag"]}
|
||||||
"command": "account_info",
|
// const test_wallet = xrpl.Wallet.fromSeed("your-seed-key")
|
||||||
"account": test_wallet.address,
|
// @chunk-end
|
||||||
"ledger_index": "validated"
|
|
||||||
})
|
|
||||||
console.log(response)
|
|
||||||
|
|
||||||
// Listen to ledger close events
|
// @chunk {"steps": ["query-xrpl-tag"]}
|
||||||
client.request({
|
// Get info from the ledger about the address we just funded
|
||||||
"command": "subscribe",
|
console.log("\nGetting account info...")
|
||||||
"streams": ["ledger"]
|
const response = await client.request({
|
||||||
})
|
"command": "account_info",
|
||||||
client.on("ledgerClosed", async (ledger) => {
|
"account": test_wallet.address,
|
||||||
console.log(`Ledger #${ledger.ledger_index} validated with ${ledger.txn_count} transactions!`)
|
"ledger_index": "validated"
|
||||||
})
|
})
|
||||||
|
console.log(JSON.stringify(response, null, 2))
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
// Disconnect when done so Node.js can end the process
|
// @chunk {"steps": ["listen-for-events-tag"]}
|
||||||
await client.disconnect()
|
// Listen to ledger close events
|
||||||
}
|
console.log("\nListening for ledger close events...")
|
||||||
|
client.request({
|
||||||
|
"command": "subscribe",
|
||||||
|
"streams": ["ledger"]
|
||||||
|
})
|
||||||
|
client.on("ledgerClosed", async (ledger) => {
|
||||||
|
console.log(`Ledger #${ledger.ledger_index} validated ` +
|
||||||
|
`with ${ledger.txn_count} transactions!`)
|
||||||
|
})
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
// call the async function
|
// @chunk {"steps": ["disconnect-node-tag"]}
|
||||||
main()
|
// Disconnect when done so Node.js can end the process.
|
||||||
|
// Delay this by 10 seconds to give the ledger event listener time to receive
|
||||||
|
// and display some ledger events.
|
||||||
|
setTimeout(async () => {
|
||||||
|
await client.disconnect();
|
||||||
|
console.log('\nDisconnected');
|
||||||
|
}, 10000);
|
||||||
|
// @chunk-end
|
||||||
|
|||||||
79
_code-samples/get-started/js/index.html
Normal file
79
_code-samples/get-started/js/index.html
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>XRPL.js Base Example</title>
|
||||||
|
<!-- @chunk {"steps": ["import-web-tag"]} -->
|
||||||
|
<script src="https://unpkg.com/xrpl/build/xrpl-latest-min.js"></script>
|
||||||
|
<!-- @chunk-end -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>XRPL.js Get Started</h1>
|
||||||
|
<div id="output"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(async () => {
|
||||||
|
const output = document.getElementById('output');
|
||||||
|
|
||||||
|
// @chunk {"steps": ["connect-tag"]}
|
||||||
|
// Define the network client
|
||||||
|
const SERVER_URL = "wss://s.altnet.rippletest.net:51233/"
|
||||||
|
const client = new xrpl.Client(SERVER_URL)
|
||||||
|
await client.connect()
|
||||||
|
output.innerHTML = '<p>Connected to Testnet</p>';
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
|
// @chunk {"steps": ["get-account-create-wallet-tag"]}
|
||||||
|
// Create a wallet and fund it with the Testnet faucet:
|
||||||
|
output.innerHTML += '<p>Creating a new wallet and funding it with Testnet XRP...</p>';
|
||||||
|
const fund_result = await client.fundWallet()
|
||||||
|
const test_wallet = fund_result.wallet
|
||||||
|
output.innerHTML += `<p>Wallet: ${test_wallet.address}</p>`;
|
||||||
|
output.innerHTML += `<p>Balance: ${fund_result.balance}</p>`;
|
||||||
|
output.innerHTML += `<p>View account on XRPL Testnet Explorer: <a href="https://testnet.xrpl.org/accounts/${test_wallet.address}" target="_blank">${test_wallet.address}</a></p>`;
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
|
// To generate a wallet without funding it, uncomment the code below
|
||||||
|
// @chunk {"steps": ["get-account-create-wallet-b-tag"]}
|
||||||
|
// const test_wallet = xrpl.Wallet.generate()
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
|
// To provide your own seed, replace the test_wallet value with the below
|
||||||
|
// @chunk {"steps": ["get-account-create-wallet-c-tag"]}
|
||||||
|
// const test_wallet = xrpl.Wallet.fromSeed("your-seed-key")
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
|
// @chunk {"steps": ["query-xrpl-tag"]}
|
||||||
|
// Get info from the ledger about the address we just funded
|
||||||
|
output.innerHTML += `<p>Getting account info...</p>`;
|
||||||
|
const response = await client.request({
|
||||||
|
"command": "account_info",
|
||||||
|
"account": test_wallet.address,
|
||||||
|
"ledger_index": "validated"
|
||||||
|
})
|
||||||
|
output.innerHTML += `<pre>${JSON.stringify(response, null, 2)}</pre>`;
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
|
// @chunk {"steps": ["listen-for-events-tag"]}
|
||||||
|
// Listen to ledger close events
|
||||||
|
output.innerHTML += '<p>Listening for ledger close events...</p>';
|
||||||
|
client.request({
|
||||||
|
"command": "subscribe",
|
||||||
|
"streams": ["ledger"]
|
||||||
|
})
|
||||||
|
client.on("ledgerClosed", async (ledger) => {
|
||||||
|
output.innerHTML += `<p>Ledger #${ledger.ledger_index} validated with ${ledger.txn_count} transactions</p>`;
|
||||||
|
})
|
||||||
|
// @chunk-end
|
||||||
|
|
||||||
|
// @chunk {"steps": ["disconnect-web-tag"]}
|
||||||
|
// Disconnect when done. Delay this by 10 seconds to give the ledger event listener time to
|
||||||
|
// receive and display some ledger events.
|
||||||
|
setTimeout(async () => {
|
||||||
|
await client.disconnect();
|
||||||
|
output.innerHTML += '<p>Disconnected</p>';
|
||||||
|
}, 10000);
|
||||||
|
// @chunk-end
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"xrpl": "^4.0.0"
|
"xrpl": "^4.4.0"
|
||||||
}
|
},
|
||||||
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
23
_code-samples/get-tx/go/go.mod
Normal file
23
_code-samples/get-tx/go/go.mod
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
56
_code-samples/get-tx/go/go.sum
Normal file
56
_code-samples/get-tx/go/go.sum
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
46
_code-samples/get-tx/go/main.go
Normal file
46
_code-samples/get-tx/go/main.go
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/ledger"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/queries/transactions"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Get the latest validated ledger
|
||||||
|
led, err := client.GetLedger(&ledger.Request{
|
||||||
|
Transactions: true,
|
||||||
|
LedgerIndex: common.Validated,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Latest validated ledger:", led)
|
||||||
|
|
||||||
|
// Get the first transaction hash from the ledger
|
||||||
|
if len(led.Ledger.Transactions) > 0 {
|
||||||
|
txHash := led.Ledger.Transactions[0].(string) // type assertion may be needed
|
||||||
|
|
||||||
|
// Query the transaction details
|
||||||
|
txResp, err := client.Request(&transactions.TxRequest{
|
||||||
|
Transaction: txHash,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("First transaction in the ledger:")
|
||||||
|
fmt.Println(txResp)
|
||||||
|
}
|
||||||
|
}
|
||||||
24
_code-samples/issue-a-token/go/go.mod
Normal file
24
_code-samples/issue-a-token/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/issue-a-token/go/go.sum
Normal file
58
_code-samples/issue-a-token/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
488
_code-samples/issue-a-token/go/rpc/main.go
Normal file
488
_code-samples/issue-a-token/go/rpc/main.go
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currencyCode = "FOO"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//
|
||||||
|
// Configure client
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up client...")
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
fmt.Println("Client configured!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure wallets
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up wallets...")
|
||||||
|
coldWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&coldWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Cold wallet funded!")
|
||||||
|
|
||||||
|
hotWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&hotWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Hot wallet funded!")
|
||||||
|
|
||||||
|
customerOneWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&customerOneWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Customer one wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println("Cold wallet:", coldWallet.ClassicAddress)
|
||||||
|
fmt.Println("Hot wallet:", hotWallet.ClassicAddress)
|
||||||
|
fmt.Println("Customer one wallet:", customerOneWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure cold address settings
|
||||||
|
//
|
||||||
|
fmt.Println("Configuring cold address settings...")
|
||||||
|
coldWalletAccountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
TickSize: types.TickSize(5),
|
||||||
|
TransferRate: types.TransferRate(0),
|
||||||
|
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetAsfDefaultRipple()
|
||||||
|
coldWalletAccountSet.SetDisallowXRP()
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetRequireDestTag()
|
||||||
|
|
||||||
|
flattenedTx := coldWalletAccountSet.Flatten()
|
||||||
|
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold address settings configuration failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold address settings configured!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure hot address settings
|
||||||
|
//
|
||||||
|
fmt.Println("Configuring hot address settings...")
|
||||||
|
hotWalletAccountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
hotWalletAccountSet.SetAsfRequireAuth()
|
||||||
|
hotWalletAccountSet.SetDisallowXRP()
|
||||||
|
hotWalletAccountSet.SetRequireDestTag()
|
||||||
|
|
||||||
|
flattenedTx = hotWalletAccountSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Hot address settings configuration failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Hot address settings configured!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create trust line from hot to cold address
|
||||||
|
//
|
||||||
|
fmt.Println("Creating trust line from hot to cold address...")
|
||||||
|
hotColdTrustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100000000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotColdTrustSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Trust line from hot to cold address creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Trust line from hot to cold address created!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create trust line from costumer one to cold address
|
||||||
|
//
|
||||||
|
fmt.Println("Creating trust line from customer one to cold address...")
|
||||||
|
customerOneColdTrustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100000000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = customerOneColdTrustSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = customerOneWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Trust line from customer one to cold address creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Trust line from customer one to cold address created!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send tokens from cold wallet to hot wallet
|
||||||
|
//
|
||||||
|
fmt.Println("Sending tokens from cold wallet to hot wallet...")
|
||||||
|
coldToHotPayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "3800",
|
||||||
|
},
|
||||||
|
Destination: types.Address(hotWallet.ClassicAddress),
|
||||||
|
DestinationTag: types.DestinationTag(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldToHotPayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send tokens from hot wallet to customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Sending tokens from cold wallet to customer one...")
|
||||||
|
coldToCustomerOnePayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100",
|
||||||
|
},
|
||||||
|
Destination: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldToCustomerOnePayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from cold wallet to customer one!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from cold wallet to customer one!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Freeze cold wallet
|
||||||
|
//
|
||||||
|
fmt.Println("Freezing cold wallet...")
|
||||||
|
freezeColdWallet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
freezeColdWallet.SetAsfGlobalFreeze()
|
||||||
|
|
||||||
|
flattenedTx = freezeColdWallet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold wallet freezing failed!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold wallet frozen!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to send tokens from hot wallet to customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Trying to send tokens from hot wallet to customer one...")
|
||||||
|
hotToCustomerOnePayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100",
|
||||||
|
},
|
||||||
|
Destination: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotToCustomerOnePayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens not sent from hot wallet to customer one!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Unfreeze cold wallet
|
||||||
|
// //
|
||||||
|
fmt.Println("Unfreezing cold wallet...")
|
||||||
|
unfreezeColdWallet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
unfreezeColdWallet.ClearAsfGlobalFreeze()
|
||||||
|
|
||||||
|
flattenedTx = unfreezeColdWallet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold wallet unfreezing failed!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold wallet unfrozen!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to send tokens from hot wallet to customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Trying to send tokens from hot wallet to customer one...")
|
||||||
|
hotToCustomerOnePayment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100",
|
||||||
|
},
|
||||||
|
Destination: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotToCustomerOnePayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from hot wallet to customer one!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from hot wallet to customer one!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
493
_code-samples/issue-a-token/go/ws/main.go
Normal file
493
_code-samples/issue-a-token/go/ws/main.go
Normal file
@@ -0,0 +1,493 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currencyCode = "FOO"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
//
|
||||||
|
// Configure client
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up client...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.altnet.rippletest.net").
|
||||||
|
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
fmt.Println("Client configured!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Connecting to server...")
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connection: ", client.IsConnected())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure wallets
|
||||||
|
//
|
||||||
|
fmt.Println("Setting up wallets...")
|
||||||
|
coldWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&coldWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Cold wallet funded!")
|
||||||
|
|
||||||
|
hotWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&hotWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Hot wallet funded!")
|
||||||
|
|
||||||
|
customerOneWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
err = client.FundWallet(&customerOneWallet)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Customer one wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Wallets setup complete!")
|
||||||
|
fmt.Println("Cold wallet:", coldWallet.ClassicAddress)
|
||||||
|
fmt.Println("Hot wallet:", hotWallet.ClassicAddress)
|
||||||
|
fmt.Println("Customer one wallet:", customerOneWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure cold address settings
|
||||||
|
//
|
||||||
|
fmt.Println("Configuring cold address settings...")
|
||||||
|
coldWalletAccountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
TickSize: types.TickSize(5),
|
||||||
|
TransferRate: types.TransferRate(0),
|
||||||
|
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetAsfDefaultRipple()
|
||||||
|
coldWalletAccountSet.SetDisallowXRP()
|
||||||
|
|
||||||
|
coldWalletAccountSet.SetRequireDestTag()
|
||||||
|
|
||||||
|
flattenedTx := coldWalletAccountSet.Flatten()
|
||||||
|
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err := coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold address settings configuration failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold address settings configured!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Configure hot address settings
|
||||||
|
//
|
||||||
|
fmt.Println("Configuring hot address settings...")
|
||||||
|
hotWalletAccountSet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
|
||||||
|
}
|
||||||
|
|
||||||
|
hotWalletAccountSet.SetAsfRequireAuth()
|
||||||
|
hotWalletAccountSet.SetDisallowXRP()
|
||||||
|
hotWalletAccountSet.SetRequireDestTag()
|
||||||
|
|
||||||
|
flattenedTx = hotWalletAccountSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Hot address settings configuration failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Hot address settings configured!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create trust line from hot to cold address
|
||||||
|
//
|
||||||
|
fmt.Println("Creating trust line from hot to cold address...")
|
||||||
|
hotColdTrustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100000000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotColdTrustSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Trust line from hot to cold address creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Trust line from hot to cold address created!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create trust line from costumer one to cold address
|
||||||
|
//
|
||||||
|
fmt.Println("Creating trust line from customer one to cold address...")
|
||||||
|
customerOneColdTrustSet := &transactions.TrustSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
LimitAmount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100000000000000",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = customerOneColdTrustSet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = customerOneWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Trust line from customer one to cold address creation failed!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Trust line from customer one to cold address created!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send tokens from cold wallet to hot wallet
|
||||||
|
//
|
||||||
|
fmt.Println("Sending tokens from cold wallet to hot wallet...")
|
||||||
|
coldToHotPayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "3800",
|
||||||
|
},
|
||||||
|
Destination: types.Address(hotWallet.ClassicAddress),
|
||||||
|
DestinationTag: types.DestinationTag(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldToHotPayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from cold wallet to hot wallet!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Send tokens from hot wallet to customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Sending tokens from cold wallet to customer one...")
|
||||||
|
coldToCustomerOnePayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100",
|
||||||
|
},
|
||||||
|
Destination: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = coldToCustomerOnePayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from cold wallet to customer one!")
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from cold wallet to customer one!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Freeze cold wallet
|
||||||
|
//
|
||||||
|
fmt.Println("Freezing cold wallet...")
|
||||||
|
freezeColdWallet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
freezeColdWallet.SetAsfGlobalFreeze()
|
||||||
|
|
||||||
|
flattenedTx = freezeColdWallet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold wallet freezing failed!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold wallet frozen!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to send tokens from hot wallet to customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Trying to send tokens from hot wallet to customer one...")
|
||||||
|
hotToCustomerOnePayment := &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100",
|
||||||
|
},
|
||||||
|
Destination: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotToCustomerOnePayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens not sent from hot wallet to customer one!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Unfreeze cold wallet
|
||||||
|
// //
|
||||||
|
fmt.Println("Unfreezing cold wallet...")
|
||||||
|
unfreezeColdWallet := &transactions.AccountSet{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(coldWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
unfreezeColdWallet.ClearAsfGlobalFreeze()
|
||||||
|
|
||||||
|
flattenedTx = unfreezeColdWallet.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = coldWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Cold wallet unfreezing failed!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Cold wallet unfrozen!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
//
|
||||||
|
// Try to send tokens from hot wallet to customer one
|
||||||
|
//
|
||||||
|
fmt.Println("Trying to send tokens from hot wallet to customer one...")
|
||||||
|
hotToCustomerOnePayment = &transactions.Payment{
|
||||||
|
BaseTx: transactions.BaseTx{
|
||||||
|
Account: types.Address(hotWallet.ClassicAddress),
|
||||||
|
},
|
||||||
|
Amount: types.IssuedCurrencyAmount{
|
||||||
|
Currency: currencyCode,
|
||||||
|
Issuer: types.Address(coldWallet.ClassicAddress),
|
||||||
|
Value: "100",
|
||||||
|
},
|
||||||
|
Destination: types.Address(customerOneWallet.ClassicAddress),
|
||||||
|
}
|
||||||
|
|
||||||
|
flattenedTx = hotToCustomerOnePayment.Flatten()
|
||||||
|
err = client.Autofill(&flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
txBlob, _, err = hotWallet.Sign(flattenedTx)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err = client.SubmitTxBlobAndWait(txBlob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("Tokens not sent from hot wallet to customer one!")
|
||||||
|
fmt.Println("Try again!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Tokens sent from hot wallet to customer one!")
|
||||||
|
fmt.Printf("Hash: %s\n", response.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
3
_code-samples/issue-mpt-with-metadata/README.md
Normal file
3
_code-samples/issue-mpt-with-metadata/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Issue an MPT with Metadata
|
||||||
|
|
||||||
|
Shows how to issue a Multi-Purpose Token (MPT) with metadata encoded according to the XLS-89 schema.
|
||||||
16
_code-samples/issue-mpt-with-metadata/js/README.md
Normal file
16
_code-samples/issue-mpt-with-metadata/js/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Issue MPT with Metadata (JavaScript)
|
||||||
|
|
||||||
|
Creates a sample MPT issuance with metadata encoded as JSON according to the [XLS-89 standard](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0089-multi-purpose-token-metadata-schema).
|
||||||
|
|
||||||
|
Quick setup and usage:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm i
|
||||||
|
node issue-mpt-with-metadata.js
|
||||||
|
```
|
||||||
|
|
||||||
|
The script should output a validated transaction and end with a line such as the following:
|
||||||
|
|
||||||
|
```text
|
||||||
|
MPToken created successfully with issuance ID 005073C721E14A7613BAAF5E0B1A253459832FF8D0D81278.
|
||||||
|
```
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
import { stringToHex, hexToString } from '@xrplf/isomorphic/dist/utils/index.js'
|
||||||
|
import { MPTokenIssuanceCreateFlags, Client } from 'xrpl'
|
||||||
|
|
||||||
|
// Connect to network and get a wallet
|
||||||
|
const client = new Client('wss://s.devnet.rippletest.net:51233')
|
||||||
|
await client.connect()
|
||||||
|
|
||||||
|
console.log('Funding new wallet from faucet...')
|
||||||
|
const { wallet } = await client.fundWallet()
|
||||||
|
|
||||||
|
// Define metadata as JSON
|
||||||
|
const mpt_metadata = {
|
||||||
|
ticker: 'TBILL',
|
||||||
|
name: 'T-Bill Yield Token',
|
||||||
|
desc: 'A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.',
|
||||||
|
icon: 'https://example.org/tbill-icon.png',
|
||||||
|
asset_class: 'rwa',
|
||||||
|
asset_subclass: 'treasury',
|
||||||
|
issuer_name: 'Example Yield Co.',
|
||||||
|
urls: [
|
||||||
|
{
|
||||||
|
url: 'https://exampleyield.co/tbill',
|
||||||
|
type: 'website',
|
||||||
|
title: 'Product Page'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: 'https://exampleyield.co/docs',
|
||||||
|
type: 'docs',
|
||||||
|
title: 'Yield Token Docs'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
additional_info: {
|
||||||
|
interest_rate: '5.00%',
|
||||||
|
interest_type: 'variable',
|
||||||
|
yield_source: 'U.S. Treasury Bills',
|
||||||
|
maturity_date: '2045-06-30',
|
||||||
|
cusip: '912796RX0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert JSON to a string (without excess whitespace), then string to hex
|
||||||
|
const mpt_metadata_hex = stringToHex(JSON.stringify(mpt_metadata))
|
||||||
|
|
||||||
|
// Define the transaction, including other MPT parameters
|
||||||
|
const mpt_issuance_create = {
|
||||||
|
TransactionType: 'MPTokenIssuanceCreate',
|
||||||
|
Account: wallet.address,
|
||||||
|
AssetScale: 4,
|
||||||
|
MaximumAmount: '50000000',
|
||||||
|
TransferFee: 0,
|
||||||
|
Flags: MPTokenIssuanceCreateFlags.tfMPTCanTransfer |
|
||||||
|
MPTokenIssuanceCreateFlags.tfMPTCanTrade,
|
||||||
|
MPTokenMetadata: mpt_metadata_hex
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare, sign, and submit the transaction
|
||||||
|
console.log('Sending MPTokenIssuanceCreate transaction...')
|
||||||
|
const submit_response = await client.submitAndWait(mpt_issuance_create, { wallet, autofill: true })
|
||||||
|
|
||||||
|
// Check transaction results and disconnect
|
||||||
|
console.log(JSON.stringify(submit_response, null, 2))
|
||||||
|
if (submit_response.result.meta.TransactionResult !== 'tesSUCCESS') {
|
||||||
|
const result_code = response.result.meta.TransactionResult
|
||||||
|
console.warn(`Transaction failed with result code ${result_code}.`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const issuance_id = submit_response.result.meta.mpt_issuance_id
|
||||||
|
console.log(`MPToken created successfully with issuance ID ${issuance_id}.`)
|
||||||
|
|
||||||
|
// Look up MPT Issuance entry in the validated ledger
|
||||||
|
console.log('Confirming MPT Issuance metadata in the validated ledger.')
|
||||||
|
const ledger_entry_response = await client.request({
|
||||||
|
"command": "ledger_entry",
|
||||||
|
"mpt_issuance": issuance_id,
|
||||||
|
"ledger_index": "validated"
|
||||||
|
})
|
||||||
|
|
||||||
|
// Decode the metadata
|
||||||
|
const metadata_blob = ledger_entry_response.result.node.MPTokenMetadata
|
||||||
|
const decoded_metadata = JSON.parse(hexToString(metadata_blob))
|
||||||
|
console.log('Decoded metadata:', decoded_metadata)
|
||||||
|
|
||||||
|
|
||||||
|
client.disconnect()
|
||||||
6
_code-samples/issue-mpt-with-metadata/js/package.json
Normal file
6
_code-samples/issue-mpt-with-metadata/js/package.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"xrpl": "^4.4.0"
|
||||||
|
},
|
||||||
|
"type": "module"
|
||||||
|
}
|
||||||
18
_code-samples/issue-mpt-with-metadata/py/README.md
Normal file
18
_code-samples/issue-mpt-with-metadata/py/README.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Issue MPT with Metadata (Python)
|
||||||
|
|
||||||
|
Creates a sample MPT issuance with metadata encoded as JSON according to the [XLS-89 standard](https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-0089-multi-purpose-token-metadata-schema).
|
||||||
|
|
||||||
|
Quick setup and usage:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python -m venv .venv
|
||||||
|
source .venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
python issue-mpt-with-metadata.py
|
||||||
|
```
|
||||||
|
|
||||||
|
The script should output a validated transaction and end with a line such as the following:
|
||||||
|
|
||||||
|
```text
|
||||||
|
MPToken created successfully with issuance ID 0050773D6B8DF8C6BEA497016C8679728A217DE1C4D50AC5.
|
||||||
|
```
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import json
|
||||||
|
from xrpl.utils import str_to_hex, hex_to_str
|
||||||
|
from xrpl.clients import JsonRpcClient
|
||||||
|
from xrpl.wallet import generate_faucet_wallet
|
||||||
|
from xrpl.transaction import submit_and_wait
|
||||||
|
from xrpl.models import LedgerEntry, MPTokenIssuanceCreate, MPTokenIssuanceCreateFlag
|
||||||
|
|
||||||
|
# Set up client and get a wallet
|
||||||
|
client = JsonRpcClient("https://s.devnet.rippletest.net:51234")
|
||||||
|
print("Funding new wallet from faucet...")
|
||||||
|
wallet = generate_faucet_wallet(client, debug=True)
|
||||||
|
|
||||||
|
# Define metadata as JSON
|
||||||
|
mpt_metadata = {
|
||||||
|
"ticker": "TBILL",
|
||||||
|
"name": "T-Bill Yield Token",
|
||||||
|
"desc": "A yield-bearing stablecoin backed by short-term U.S. Treasuries and money market instruments.",
|
||||||
|
"icon": "https://example.org/tbill-icon.png",
|
||||||
|
"asset_class": "rwa",
|
||||||
|
"asset_subclass": "treasury",
|
||||||
|
"issuer_name": "Example Yield Co.",
|
||||||
|
"urls": [
|
||||||
|
{
|
||||||
|
"url": "https://exampleyield.co/tbill",
|
||||||
|
"type": "website",
|
||||||
|
"title": "Product Page"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://exampleyield.co/docs",
|
||||||
|
"type": "docs",
|
||||||
|
"title": "Yield Token Docs"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"additional_info": {
|
||||||
|
"interest_rate": "5.00%",
|
||||||
|
"interest_type": "variable",
|
||||||
|
"yield_source": "U.S. Treasury Bills",
|
||||||
|
"maturity_date": "2045-06-30",
|
||||||
|
"cusip": "912796RX0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Convert JSON to a string (without excess whitespace), then string to hex
|
||||||
|
mpt_metadata_string = json.dumps(mpt_metadata, separators=(',', ':'))
|
||||||
|
mpt_metadata_hex = str_to_hex(mpt_metadata_string)
|
||||||
|
|
||||||
|
# Define the transaction, including other MPT parameters
|
||||||
|
mpt_issuance_create = MPTokenIssuanceCreate(
|
||||||
|
account=wallet.address,
|
||||||
|
asset_scale=4,
|
||||||
|
maximum_amount="50000000",
|
||||||
|
transfer_fee=0,
|
||||||
|
flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER |
|
||||||
|
MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRADE,
|
||||||
|
mptoken_metadata=mpt_metadata_hex
|
||||||
|
)
|
||||||
|
|
||||||
|
# Prepare, sign, and submit the transaction
|
||||||
|
print("Sending MPTokenIssuanceCreate transaction...")
|
||||||
|
response = submit_and_wait(mpt_issuance_create, client, wallet, autofill=True)
|
||||||
|
print(json.dumps(response.result, indent=2))
|
||||||
|
|
||||||
|
# Check transaction results
|
||||||
|
result_code = response.result["meta"]["TransactionResult"]
|
||||||
|
if result_code != "tesSUCCESS":
|
||||||
|
print(f"Transaction failed with result code {result_code}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
issuance_id = response.result["meta"]["mpt_issuance_id"]
|
||||||
|
print(f"MPToken successfully created with issuance ID {issuance_id}")
|
||||||
|
|
||||||
|
# Look up MPT Issuance entry in the validated ledger
|
||||||
|
print("Confirming MPT Issuance metadata in the validated ledger.")
|
||||||
|
ledger_entry_response = client.request(LedgerEntry(
|
||||||
|
mpt_issuance=issuance_id,
|
||||||
|
ledger_index="validated"
|
||||||
|
))
|
||||||
|
|
||||||
|
# Decode the metadata
|
||||||
|
metadata_blob = ledger_entry_response.result["node"]["MPTokenMetadata"]
|
||||||
|
decoded_metadata = json.loads(hex_to_str(metadata_blob))
|
||||||
|
print("Decoded metadata:", decoded_metadata)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
xrpl-py==4.3.0
|
||||||
@@ -7,15 +7,15 @@ package main
|
|||||||
// install: go get github.com/gorilla/websocket
|
// install: go get github.com/gorilla/websocket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
)
|
)
|
||||||
|
|
||||||
// websocket address
|
// websocket address
|
||||||
@@ -23,75 +23,72 @@ var addr = flag.String("addr", "s.altnet.rippletest.net:51233", "http service ad
|
|||||||
|
|
||||||
// Payload object
|
// Payload object
|
||||||
type message struct {
|
type message struct {
|
||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
Accounts []string `json:"accounts"`
|
Accounts []string `json:"accounts"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
|
|
||||||
var m message
|
var m message
|
||||||
|
|
||||||
// check for interrupts and cleanly close the connection
|
// check for interrupts and cleanly close the connection
|
||||||
interrupt := make(chan os.Signal, 1)
|
interrupt := make(chan os.Signal, 1)
|
||||||
signal.Notify(interrupt, os.Interrupt)
|
signal.Notify(interrupt, os.Interrupt)
|
||||||
|
|
||||||
u := url.URL{Scheme: "ws", Host: *addr, Path: "/"}
|
u := url.URL{Scheme: "ws", Host: *addr, Path: "/"}
|
||||||
log.Printf("connecting to %s", u.String())
|
log.Printf("connecting to %s", u.String())
|
||||||
|
|
||||||
// make the connection
|
// make the connection
|
||||||
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("dial:", err)
|
panic(err)
|
||||||
}
|
}
|
||||||
// on exit close
|
// on exit close
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
done := make(chan struct{})
|
done := make(chan struct{})
|
||||||
|
|
||||||
// send a subscribe command and a target XRPL account
|
// send a subscribe command and a target XRPL account
|
||||||
m.Command = "subscribe"
|
m.Command = "subscribe"
|
||||||
m.Accounts = append(m.Accounts, "rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM")
|
m.Accounts = append(m.Accounts, "rUCzEr6jrEyMpjhs4wSdQdz4g8Y382NxfM")
|
||||||
|
|
||||||
// struct to JSON marshalling
|
// struct to JSON marshalling
|
||||||
msg, _ := json.Marshal(m)
|
msg, _ := json.Marshal(m)
|
||||||
// write to the websocket
|
// write to the websocket
|
||||||
err = c.WriteMessage(websocket.TextMessage, []byte(string(msg)))
|
err = c.WriteMessage(websocket.TextMessage, []byte(string(msg)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("write:", err)
|
panic(err)
|
||||||
return
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// read from the websocket
|
// read from the websocket
|
||||||
_, message, err := c.ReadMessage()
|
_, message, err := c.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("read:", err)
|
panic(err)
|
||||||
return
|
}
|
||||||
}
|
// print the response from the XRP Ledger
|
||||||
// print the response from the XRP Ledger
|
log.Printf("recv: %s", message)
|
||||||
log.Printf("recv: %s", message)
|
|
||||||
|
|
||||||
// handle interrupt
|
// handle interrupt
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-done:
|
case <-done:
|
||||||
return
|
return
|
||||||
case <-interrupt:
|
case <-interrupt:
|
||||||
log.Println("interrupt")
|
log.Println("interrupt")
|
||||||
|
|
||||||
// Cleanly close the connection by sending a close message and then
|
// Cleanly close the connection by sending a close message and then
|
||||||
// waiting (with timeout) for the server to close the connection.
|
// waiting (with timeout) for the server to close the connection.
|
||||||
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("write close:", err)
|
panic(err)
|
||||||
return
|
}
|
||||||
}
|
select {
|
||||||
select {
|
case <-done:
|
||||||
case <-done:
|
case <-time.After(time.Second):
|
||||||
case <-time.After(time.Second):
|
}
|
||||||
}
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
24
_code-samples/multisigning/go/go.mod
Normal file
24
_code-samples/multisigning/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/multisigning/go/go.sum
Normal file
58
_code-samples/multisigning/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
152
_code-samples/multisigning/go/rpc/main.go
Normal file
152
_code-samples/multisigning/go/rpc/main.go
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.altnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
w1, err := wallet.FromSeed("sEdTtvLmJmrb7GaivhWoXRkvU4NDjVf", "")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w2, err := wallet.FromSeed("sEdSFiKMQp7RvYLgH7t7FEpwNRWv2Gr", "")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
master, err := wallet.FromSeed("sEdTMm2yv8c8Rg8YHFHQA9TxVMFy1ze", "")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&w1); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Wallet 1 funded")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&w2); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Wallet 2 funded")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&master); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Master wallet funded")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Setting up signer list...")
|
||||||
|
|
||||||
|
ss := &transaction.SignerListSet{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: master.GetAddress(),
|
||||||
|
},
|
||||||
|
SignerQuorum: uint32(2),
|
||||||
|
SignerEntries: []ledger.SignerEntryWrapper{
|
||||||
|
{
|
||||||
|
SignerEntry: ledger.SignerEntry{
|
||||||
|
Account: w1.GetAddress(),
|
||||||
|
SignerWeight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SignerEntry: ledger.SignerEntry{
|
||||||
|
Account: w2.GetAddress(),
|
||||||
|
SignerWeight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SignerEntry: ledger.SignerEntry{
|
||||||
|
Account: "XVYRdEocC28DRx94ZFGP3qNJ1D5Ln7ecXFMd3vREB5Pesju",
|
||||||
|
SignerWeight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
flatSs := ss.Flatten()
|
||||||
|
|
||||||
|
if err := client.Autofill(&flatSs); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, _, err := master.Sign(flatSs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := client.SubmitTxBlobAndWait(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("SignerListSet transaction submitted!")
|
||||||
|
fmt.Printf("Hash: %s\n", res.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Setting up AccountSet multisign transaction...")
|
||||||
|
|
||||||
|
as := &transaction.AccountSet{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: master.GetAddress(),
|
||||||
|
},
|
||||||
|
Domain: types.Domain(strings.ToUpper(hex.EncodeToString([]byte("example.com")))),
|
||||||
|
}
|
||||||
|
|
||||||
|
flatAs := as.Flatten()
|
||||||
|
|
||||||
|
if err := client.AutofillMultisigned(&flatAs, 2); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w1As := maps.Clone(flatAs)
|
||||||
|
|
||||||
|
blob1, _, err := w1.Multisign(w1As)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w2As := maps.Clone(flatAs)
|
||||||
|
|
||||||
|
blob2, _, err := w2.Multisign(w2As)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, err = xrpl.Multisign(blob1, blob2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mRes, err := client.SubmitMultisigned(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Multisigned transaction submitted!")
|
||||||
|
fmt.Printf("Result: %s\n", mRes.EngineResult)
|
||||||
|
}
|
||||||
166
_code-samples/multisigning/go/ws/main.go
Normal file
166
_code-samples/multisigning/go/ws/main.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Connecting to testnet...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.altnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to testnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connected to testnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
w1, err := wallet.FromSeed("sEdTtvLmJmrb7GaivhWoXRkvU4NDjVf", "")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w2, err := wallet.FromSeed("sEdSFiKMQp7RvYLgH7t7FEpwNRWv2Gr", "")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
master, err := wallet.FromSeed("sEdTMm2yv8c8Rg8YHFHQA9TxVMFy1ze", "")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&w1); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Wallet 1 funded")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&w2); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Wallet 2 funded")
|
||||||
|
|
||||||
|
if err := client.FundWallet(&master); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("Master wallet funded")
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("Setting up signer list...")
|
||||||
|
|
||||||
|
ss := &transaction.SignerListSet{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: master.GetAddress(),
|
||||||
|
},
|
||||||
|
SignerQuorum: uint32(2),
|
||||||
|
SignerEntries: []ledger.SignerEntryWrapper{
|
||||||
|
{
|
||||||
|
SignerEntry: ledger.SignerEntry{
|
||||||
|
Account: w1.GetAddress(),
|
||||||
|
SignerWeight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SignerEntry: ledger.SignerEntry{
|
||||||
|
Account: w2.GetAddress(),
|
||||||
|
SignerWeight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
SignerEntry: ledger.SignerEntry{
|
||||||
|
Account: "XVYRdEocC28DRx94ZFGP3qNJ1D5Ln7ecXFMd3vREB5Pesju",
|
||||||
|
SignerWeight: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Flattening transaction...")
|
||||||
|
flatSs := ss.Flatten()
|
||||||
|
|
||||||
|
fmt.Println("Autofilling transaction...")
|
||||||
|
if err := client.Autofill(&flatSs); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Signing transaction...")
|
||||||
|
blob, _, err := master.Sign(flatSs)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Submitting transaction...")
|
||||||
|
res, err := client.SubmitTxBlobAndWait(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("SignerListSet transaction submitted!")
|
||||||
|
fmt.Printf("Hash: %s\n", res.Hash.String())
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Setting up AccountSet multisign transaction...")
|
||||||
|
|
||||||
|
as := &transaction.AccountSet{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: master.GetAddress(),
|
||||||
|
},
|
||||||
|
Domain: types.Domain(strings.ToUpper(hex.EncodeToString([]byte("example.com")))),
|
||||||
|
}
|
||||||
|
|
||||||
|
flatAs := as.Flatten()
|
||||||
|
|
||||||
|
if err := client.AutofillMultisigned(&flatAs, 2); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w1As := maps.Clone(flatAs)
|
||||||
|
|
||||||
|
blob1, _, err := w1.Multisign(w1As)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
w2As := maps.Clone(flatAs)
|
||||||
|
|
||||||
|
blob2, _, err := w2.Multisign(w2As)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
blob, err = xrpl.Multisign(blob1, blob2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mRes, err := client.SubmitMultisigned(blob, false)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Multisigned transaction submitted!")
|
||||||
|
fmt.Printf("Result: %s\n", mRes.EngineResult)
|
||||||
|
}
|
||||||
24
_code-samples/non-fungible-token/go/go.mod
Normal file
24
_code-samples/non-fungible-token/go/go.mod
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
module github.com/XRPLF
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.10
|
||||||
|
|
||||||
|
require github.com/Peersyst/xrpl-go v0.1.11
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||||
|
golang.org/x/crypto v0.35.0 // indirect
|
||||||
|
)
|
||||||
58
_code-samples/non-fungible-token/go/go.sum
Normal file
58
_code-samples/non-fungible-token/go/go.sum
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
|
||||||
|
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
|
||||||
|
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
|
||||||
|
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||||
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
|
||||||
|
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
|
||||||
|
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||||
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||||
|
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||||
|
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||||
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||||
|
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||||
|
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
|
||||||
|
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
|
||||||
|
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
|
||||||
|
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||||
|
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||||
|
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
|
||||||
|
golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
|
||||||
|
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
|
||||||
122
_code-samples/non-fungible-token/go/nft-accept/rpc/main.go
Normal file
122
_code-samples/non-fungible-token/go/nft-accept/rpc/main.go
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialize the RPC client configuration
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.devnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the RPC client
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Step 1: Fund wallets
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
|
||||||
|
// Create and fund the NFT minter wallet
|
||||||
|
nftMinter, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftMinter); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minter wallet funded!")
|
||||||
|
|
||||||
|
// Create and fund the NFT buyer wallet
|
||||||
|
nftBuyer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftBuyer); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT buyer wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 2: Mint an NFT
|
||||||
|
fmt.Println("Minting NFT...")
|
||||||
|
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
Destination: nftBuyer.ClassicAddress,
|
||||||
|
Amount: txnTypes.XRPCurrencyAmount(1000000), // 1 XRP
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("NFTokenMint txn is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the NFT token offer ID
|
||||||
|
fmt.Println("Retrieving NFT offer ID...")
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
offerID, ok := metaMap["offer_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("offer_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("offer_id:", offerID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 4: Accept the NFT offer
|
||||||
|
fmt.Println("Accepting NFT offer...")
|
||||||
|
|
||||||
|
nftAccept := transaction.NFTokenAcceptOffer{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftBuyer.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenAcceptOfferTx,
|
||||||
|
},
|
||||||
|
NFTokenSellOffer: txnTypes.Hash256(offerID),
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxAndWait(nftAccept.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftBuyer,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("NFTokenAcceptOffer txn is not in a validated ledger", response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT offer accepted successfully! - Hash: ", response.Hash)
|
||||||
|
}
|
||||||
126
_code-samples/non-fungible-token/go/nft-accept/ws/main.go
Normal file
126
_code-samples/non-fungible-token/go/nft-accept/ws/main.go
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Connect to the XRPL devnet
|
||||||
|
fmt.Println("Connecting to devnet...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to devnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Connected to devnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Fund wallets
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
|
||||||
|
// Create and fund the NFT minter wallet
|
||||||
|
nftMinter, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftMinter); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minter wallet funded!")
|
||||||
|
|
||||||
|
// Create and fund the NFT buyer wallet
|
||||||
|
nftBuyer, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftBuyer); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT buyer wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Mint an NFT
|
||||||
|
fmt.Println("Minting NFT...")
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
Destination: nftBuyer.ClassicAddress,
|
||||||
|
Amount: txnTypes.XRPCurrencyAmount(1000000), // 1 XRP
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("NFTokenMint transaction is not in a validated ledger:", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minted successfully! - Hash:", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Extract the NFT token offer ID from the transaction metadata
|
||||||
|
fmt.Println("Extracting offer ID...")
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
offerID, ok := metaMap["offer_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("offer_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("offer_id:", offerID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Accept the NFT offer
|
||||||
|
fmt.Println("Accepting NFT offer...")
|
||||||
|
nftAccept := transaction.NFTokenAcceptOffer{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftBuyer.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenAcceptOfferTx,
|
||||||
|
},
|
||||||
|
NFTokenSellOffer: txnTypes.Hash256(offerID),
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxAndWait(nftAccept.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftBuyer,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("NFTokenAcceptOffer transaction is not in a validated ledger:", response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT offer accepted successfully! - Hash:", response.Hash)
|
||||||
|
}
|
||||||
110
_code-samples/non-fungible-token/go/nft-burn/rpc/main.go
Normal file
110
_code-samples/non-fungible-token/go/nft-burn/rpc/main.go
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialize the RPC client configuration
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.devnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the RPC client
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Step 1: Fund wallets
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
|
||||||
|
// Create and fund the NFT minter wallet
|
||||||
|
nftMinter, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftMinter); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minter wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 2: Mint an NFT
|
||||||
|
fmt.Println("Minting NFT...")
|
||||||
|
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("NFTokenMint txn is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the token ID
|
||||||
|
fmt.Println("Retrieving NFT ID...")
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID, ok := metaMap["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 4: Burn the NFT
|
||||||
|
fmt.Println("Burn the NFT...")
|
||||||
|
|
||||||
|
nftBurn := transaction.NFTokenBurn{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenAcceptOfferTx,
|
||||||
|
},
|
||||||
|
NFTokenID: txnTypes.NFTokenID(nftokenID),
|
||||||
|
}
|
||||||
|
|
||||||
|
responseBurn, err := client.SubmitTxAndWait(nftBurn.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseBurn.Validated {
|
||||||
|
fmt.Println("NFTokenBurn transactiob is not in a validated ledger", responseBurn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT burned successfully! - Hash: ", responseBurn.Hash)
|
||||||
|
}
|
||||||
118
_code-samples/non-fungible-token/go/nft-burn/ws/main.go
Normal file
118
_code-samples/non-fungible-token/go/nft-burn/ws/main.go
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Connect to the XRPL devnet
|
||||||
|
fmt.Println("Connecting to devnet...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to devnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Connected to devnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 1: Fund wallets
|
||||||
|
fmt.Println("Funding wallets...")
|
||||||
|
|
||||||
|
// Create and fund the NFT minter wallet
|
||||||
|
nftMinter, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftMinter); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minter wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 2: Mint an NFT
|
||||||
|
fmt.Println("Minting NFT...")
|
||||||
|
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("NFTokenMint txn is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the token ID
|
||||||
|
fmt.Println("Retrieving NFT ID...")
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID, ok := metaMap["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 4: Burn the NFT
|
||||||
|
fmt.Println("Burn the NFT...")
|
||||||
|
|
||||||
|
nftBurn := transaction.NFTokenBurn{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenAcceptOfferTx,
|
||||||
|
},
|
||||||
|
NFTokenID: txnTypes.NFTokenID(nftokenID),
|
||||||
|
}
|
||||||
|
|
||||||
|
responseBurn, err := client.SubmitTxAndWait(nftBurn.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseBurn.Validated {
|
||||||
|
fmt.Println("NFTokenBurn transactiob is not in a validated ledger", responseBurn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT burned successfully! - Hash: ", responseBurn.Hash)
|
||||||
|
}
|
||||||
158
_code-samples/non-fungible-token/go/nft-cancel/rpc/main.go
Normal file
158
_code-samples/non-fungible-token/go/nft-cancel/rpc/main.go
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Initialize the RPC client configuration
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.devnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the RPC client
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
|
||||||
|
// Step 1: Fund wallet
|
||||||
|
fmt.Println("Funding wallet...")
|
||||||
|
|
||||||
|
// Create and fund the NFT minter wallet
|
||||||
|
nftMinter, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftMinter); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minter wallet funded!")
|
||||||
|
|
||||||
|
// Step 2: Mint two NFTs
|
||||||
|
fmt.Println("Minting first NFT...")
|
||||||
|
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("First NFTokenMint transaction is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("First NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the NFT token ID
|
||||||
|
fmt.Println("Retrieving NFT ID...")
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID1, ok := metaMap["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID1)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// ------
|
||||||
|
|
||||||
|
fmt.Println("Minting second NFT...")
|
||||||
|
|
||||||
|
nftMint2 := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint2.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint2, err := client.SubmitTxAndWait(nftMint2.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("Second NFTokenMint transaction is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Second NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the second NFT token ID
|
||||||
|
fmt.Println("Retrieving second NFT ID...")
|
||||||
|
|
||||||
|
metaMap2, ok := responseMint2.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID2, ok := metaMap2["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID2)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 4: Cancel the NFT offers
|
||||||
|
fmt.Println("Canceling NFT offers...")
|
||||||
|
|
||||||
|
nftCancel := transaction.NFTokenCancelOffer{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenAcceptOfferTx,
|
||||||
|
},
|
||||||
|
NFTokenOffers: []txnTypes.NFTokenID{
|
||||||
|
txnTypes.NFTokenID(nftokenID1),
|
||||||
|
txnTypes.NFTokenID(nftokenID2),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxAndWait(nftCancel.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("NFTokenCancelOffer transaction is not in a validated ledger", response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT offers canceled successfully! - Hash: ", response.Hash)
|
||||||
|
}
|
||||||
166
_code-samples/non-fungible-token/go/nft-cancel/ws/main.go
Normal file
166
_code-samples/non-fungible-token/go/nft-cancel/ws/main.go
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Connect to the XRPL devnet
|
||||||
|
fmt.Println("Connecting to devnet...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to devnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Connected to devnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 1: Fund wallet
|
||||||
|
fmt.Println("Funding wallet...")
|
||||||
|
|
||||||
|
// Create and fund the NFT minter wallet
|
||||||
|
nftMinter, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftMinter); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minter wallet funded!")
|
||||||
|
|
||||||
|
// Step 2: Mint two NFTs
|
||||||
|
fmt.Println("Minting first NFT...")
|
||||||
|
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("First NFTokenMint transaction is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("First NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the NFT token ID
|
||||||
|
fmt.Println("Retrieving NFT ID...")
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID1, ok := metaMap["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID1)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// ------
|
||||||
|
|
||||||
|
fmt.Println("Minting second NFT...")
|
||||||
|
|
||||||
|
nftMint2 := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint2.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint2, err := client.SubmitTxAndWait(nftMint2.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("Second NFTokenMint transaction is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("Second NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 3: Retrieve the second NFT token ID
|
||||||
|
fmt.Println("Retrieving second NFT ID...")
|
||||||
|
|
||||||
|
metaMap2, ok := responseMint2.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID2, ok := metaMap2["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID2)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Step 4: Cancel the NFT offers
|
||||||
|
fmt.Println("Canceling NFT offers...")
|
||||||
|
|
||||||
|
nftCancel := transaction.NFTokenCancelOffer{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftMinter.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenAcceptOfferTx,
|
||||||
|
},
|
||||||
|
NFTokenOffers: []txnTypes.NFTokenID{
|
||||||
|
txnTypes.NFTokenID(nftokenID1),
|
||||||
|
txnTypes.NFTokenID(nftokenID2),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.SubmitTxAndWait(nftCancel.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftMinter,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !response.Validated {
|
||||||
|
fmt.Println("NFTokenCancelOffer transaction is not in a validated ledger", response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT offers canceled successfully! - Hash: ", response.Hash)
|
||||||
|
}
|
||||||
103
_code-samples/non-fungible-token/go/nft-modify/rpc/main.go
Normal file
103
_code-samples/non-fungible-token/go/nft-modify/rpc/main.go
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg, err := rpc.NewClientConfig(
|
||||||
|
"https://s.devnet.rippletest.net:51234/",
|
||||||
|
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := rpc.NewClient(cfg)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
fmt.Println("Funding wallet...")
|
||||||
|
|
||||||
|
// Create and fund the nft wallet
|
||||||
|
nftWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT wallet funded: ", nftWallet.ClassicAddress)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Mint NFT
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftWallet.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetMutableFlag()
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("NFTokenMint txn is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID, ok := metaMap["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Update NFT
|
||||||
|
nftModify := transaction.NFTokenModify{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftWallet.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenModifyTx,
|
||||||
|
},
|
||||||
|
URI: "68747470733A2F2F7961686F6F2E636F6D", // https://yahoo.com
|
||||||
|
NFTokenID: txnTypes.NFTokenID(nftokenID),
|
||||||
|
}
|
||||||
|
// nftoken_id
|
||||||
|
responseModify, err := client.SubmitTxAndWait(nftModify.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseModify.Validated {
|
||||||
|
fmt.Println("NFTokenModify txn is not in a validated ledger", responseModify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT URI modified successfully! - Hash: ", responseModify.Hash)
|
||||||
|
}
|
||||||
112
_code-samples/non-fungible-token/go/nft-modify/ws/main.go
Normal file
112
_code-samples/non-fungible-token/go/nft-modify/ws/main.go
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/Peersyst/xrpl-go/pkg/crypto"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/faucet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/transaction"
|
||||||
|
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/wallet"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket"
|
||||||
|
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Connecting to devnet...")
|
||||||
|
client := websocket.NewClient(
|
||||||
|
websocket.NewClientConfig().
|
||||||
|
WithHost("wss://s.devnet.rippletest.net:51233").
|
||||||
|
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
|
||||||
|
)
|
||||||
|
|
||||||
|
defer client.Disconnect()
|
||||||
|
|
||||||
|
if err := client.Connect(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !client.IsConnected() {
|
||||||
|
fmt.Println("Failed to connect to devnet")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Connected to devnet")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Create and fund the nft wallet
|
||||||
|
fmt.Println("Funding wallet...")
|
||||||
|
nftWallet, err := wallet.New(crypto.ED25519())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := client.FundWallet(&nftWallet); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
fmt.Println("NFT wallet funded!")
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Mint NFT
|
||||||
|
nftMint := transaction.NFTokenMint{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftWallet.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenMintTx,
|
||||||
|
},
|
||||||
|
NFTokenTaxon: 0,
|
||||||
|
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
|
||||||
|
}
|
||||||
|
nftMint.SetMutableFlag()
|
||||||
|
nftMint.SetTransferableFlag()
|
||||||
|
|
||||||
|
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseMint.Validated {
|
||||||
|
fmt.Println("NFTokenMint txn is not in a validated ledger", responseMint)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT minted successfully! - Hash: ", responseMint.Hash)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
metaMap, ok := responseMint.Meta.(map[string]any)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("Meta is not a map[string]any")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
nftokenID, ok := metaMap["nftoken_id"].(string)
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("nftoken_id not found or not a string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("nftoken_id:", nftokenID)
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
|
// Update NFT
|
||||||
|
nftModify := transaction.NFTokenModify{
|
||||||
|
BaseTx: transaction.BaseTx{
|
||||||
|
Account: nftWallet.ClassicAddress,
|
||||||
|
TransactionType: transaction.NFTokenModifyTx,
|
||||||
|
},
|
||||||
|
URI: "68747470733A2F2F7961686F6F2E636F6D", // https://yahoo.com
|
||||||
|
NFTokenID: txnTypes.NFTokenID(nftokenID),
|
||||||
|
}
|
||||||
|
|
||||||
|
responseModify, err := client.SubmitTxAndWait(nftModify.Flatten(), &types.SubmitOptions{
|
||||||
|
Autofill: true,
|
||||||
|
Wallet: &nftWallet,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if !responseModify.Validated {
|
||||||
|
fmt.Println("NFTokenModify txn is not in a validated ledger", responseModify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println("NFT URI modified successfully! - Hash: ", responseModify.Hash)
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user